postgresql - Postgres : Performance and correctness of inheritance-foreign-key workaround

标签 postgresql inheritance

我正在尝试构建我的第一个涉及继承的 Postgres 数据库模式。我知道 PostgreSQL foreign key not existing, issue of inheritance? 中讨论的外键问题.但是,这个问题的答案并没有真正给出解决方案的示例,所以我想出了自己的解决方案(受 http://people.planetpostgresql.org/dfetter/index.php?/archives/51-Partitioning-Is-Such-Sweet-Sorrow.html 启发):

CREATE TABLE a (
    id  SERIAL PRIMARY KEY INITIALLY DEFERRED,
    foo TEXT
);

CREATE TABLE b (
    PRIMARY KEY(id),
    a_number REAL
) inherits(a);

CREATE TABLE c (
    PRIMARY KEY(id),
    a_number INTEGER
) inherits(a);

-- SELECT * FROM ONLY a; will always return an empty record.

CREATE TABLE  x (
    a_id INTEGER NOT NULL,
    bar  TEXT
);

CREATE TABLE  xb (
    FOREIGN KEY( a_id ) REFERENCES b INITIALLY DEFERRED
) inherits(x);

CREATE TABLE  xc (
    FOREIGN KEY( a_id ) REFERENCES c INITIALLY DEFERRED
) inherits(x);

为了执行有效的INSERT INTO x,我定义了以下触发器:

CREATE FUNCTION marshal_x()
    RETURNS TRIGGER
    LANGUAGE plpgsql
    AS $$
        DECLARE
            ref_table varchar;
        BEGIN
            SELECT INTO ref_table p.relname FROM a, pg_class p WHERE a.id = NEW.a_id AND a.tableoid = p.oid;

            IF ref_table = 'b'
                THEN INSERT INTO xb ( a_id, bar ) VALUES ( NEW.a_id, NEW.bar );
            ELSIF ref_table = 'c'
                THEN INSERT INTO xc ( a_id, bar ) VALUES ( NEW.a_id, NEW.bar );
            END IF;
            RETURN NULL;
        END;
    $$;

CREATE TRIGGER insert_x_trg
    BEFORE INSERT ON x
    FOR EACH ROW
        EXECUTE PROCEDURE marshal_x();

编辑:有没有人发现这个定义有问题,这对我未经训练的人来说并不明显? 假设表 c 为空。会不会表现

SELECT * FROM a JOIN x ON a.id= x.a_id;

一样
SELECT * FROM b JOIN x ON b.id= x.a_id;

?非常感谢。

伊萨姆

最佳答案

无论如何,使用继承的目的是什么?如果您只想根据行类型使用不同的列,例如在 OOP 中,您最好使用单个表并将 NULL 放在不适用的列中。或者将额外的列拆分到另一个表中,然后将其加入原始表。

继承在 PostgreSQL 中的主要用途是表分区,继承有许多注意事项。 PostgreSQL 9.1 引入了“Merge Append”优化,这在一定程度上有所帮助,但仍然不是最佳选择。

SELECT * FROM a JOIN x ON a.id= x.a_id;

将两个大的继承表连接在一起听起来不会很好地扩展,尤其是当您增加子表的数量时。 PostgreSQL 不够聪明,无法在此处遵循 xb 和 xc 外键约束,它会尝试将整个表 a 连接到整个 x

但话又说回来,这可能不是问题,这完全取决于您的查询和性能预期。

关于postgresql - Postgres : Performance and correctness of inheritance-foreign-key workaround,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7150418/

相关文章:

postgresql - 按列自动完成

c++ - const 和虚拟继承

postgresql - 致命 : database does not exist

sql - 将多行的列列为行(postgresQL)

c# - 为什么 SWIG C# 重载失败?

ruby-on-rails - 将继承的对象保存到 Mongoid 中的单独集合中

css - 了解初始值如何处理继承和非继承属性

c++ - 虚函数C++中的默认参数

postgresql - 在 Postgresql 中锁定事务(一系列选择和更新)

postgresql - "postgres"Unix 用户的用途