Postgresql 引用继承表的外键
我有以下表格:Postgresql 引用继承表的外键,postgresql,postgresql-9.2,Postgresql,Postgresql 9.2,我有以下表格: CREATE TABLE mail ( id serial, parent_mail_id integer, ... PRIMARY KEY (id), FOREIGN KEY (parent_mail_id) REFERENCES mail(id), ... ); CREATE TABLE incoming ( from_contact_id integer NOT NULL REFERENCES contact(id
CREATE TABLE mail (
id serial,
parent_mail_id integer,
...
PRIMARY KEY (id),
FOREIGN KEY (parent_mail_id) REFERENCES mail(id),
...
);
CREATE TABLE incoming (
from_contact_id integer NOT NULL REFERENCES contact(id),
...
PRIMARY KEY (id),
---> FOREIGN KEY (parent_mail_id) REFERENCES mail(id), <---
...
) INHERITS(mail);
CREATE TABLE outgoing (
from_user_id integer NOT NULL REFERENCES "user"(id),
...
PRIMARY KEY (id),
--> FOREIGN KEY (parent_mail_id) REFERENCES mail(id), <--
...
) INHERITS(mail);
创建表邮件(
id序列号,
父项\u邮件\u id整数,
...
主键(id),
外键(父邮件id)引用邮件(id),
...
);
创建传入表(
from_contact_id整数非空引用contact(id),
...
主键(id),
--->外键(父邮件id)引用邮件(id),外键(父邮件id)引用邮件(id),:
继承特性的一个严重限制是索引
(包括唯一约束)和外键约束仅适用
对于单个表,而不是它们的继承子表。对于
外键约束的参照侧和参照侧。
因此,在上述示例中:
如果我们将cities.name声明为唯一的或主键,这不会阻止capitals表中包含带有名称的行
复制城市中的行。默认情况下,这些重复行
显示在城市查询中。事实上,默认情况下,大写字母
完全没有唯一约束,因此可能包含多行
使用相同的名称。您可以为大写字母添加唯一的约束,但是
与城市相比,这并不能防止重复
类似地,如果指定cities.name引用其他表,则此约束不会自动传播到
大写。在这种情况下,您可以通过手动添加
对大写字母的引用相同
指定另一个表的列引用城市(名称)将允许另一个表包含城市名称,但不包含大写字母
名字。这个案子没有好的解决办法
这些缺陷可能会在将来的版本中修复,但是
与此同时,在决定是否
继承对您的应用程序很有用。
这并不是一个真正的解决方法,因此可能会将邮件设为非继承表,然后将传入和传出的列分别作为各自的额外列,并将邮件id作为主键和外键。例如,您可以创建一个视图“作为邮件传出”内部联接“传出”列。您可以使用约束触发器
CREATE OR REPLACE FUNCTION mail_ref_trigger()
RETURNS trigger AS
$BODY$
DECLARE
BEGIN
IF NOT EXISTS (
SELECT 1 FROM mail WHERE id = NEW.parent_mail_id
) THEN
RAISE foreign_key_violation USING MESSAGE = FORMAT('Referenced mail id not found, mail_id:%s', NEW.parent_mail_id);
END IF;
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
CREATE CONSTRAINT TRIGGER mail_fkey_trigger
AFTER UPDATE OR INSERT ON incoming
DEFERRABLE
FOR EACH ROW EXECUTE PROCEDURE mail_ref_trigger();