为什么使用继承的外键不起作用?

时间:2013-11-26 21:09:56

标签: postgresql inheritance

create table abstract_addresses (
  address_id int primary key
);

create table phone_numbers (
  phone_number text not null unique
) inherits (abstract_addresses) ;

create table contacts (
  name text primary key,
  address_id int not null references abstract_addresses(address_id)
);

insert into phone_numbers values (1, '18005551212'); --works

select * from abstract_addresses;

address_id
1

select * from phone_numbers;

address_id  phone_number
1           18005551212


insert into contacts values ('Neil', 1); --error

我收到此错误消息:

ERROR: insert or update on table "contacts" violates foreign key constraint "contacts_address_id_fkey"
SQL state: 23503
Detail: Key (address_id)=(1) is not present in table "abstract_addresses".

postgresql表继承只是一个糟糕的用例?

1 个答案:

答案 0 :(得分:3)

根据文档中的警告:

  

继承功能的一个严重限制是索引(包括唯一约束)和外键约束仅适用于单个表,而不适用于其继承子项。在外键约束的引用和引用方都是如此。

http://www.postgresql.org/docs/current/static/ddl-inherit.html

做你想做的事:

  1. 创建一个只有id的表 - 就像你做的那样。

  2. 不要使用继承。真的没有。分区日志表很有用;不是因为你在做什么。

  3. 将电话号码ids设为默认为nextval('abstract_addresses_address_id_seq'),或无论序列名称是什么。

  4. 在引用phone_numbers的{​​{1}}中添加外键。使其可延期,最初推迟。

  5. abstract_addresses (address_id)上添加后插入触发器,在需要时在phone_numbers中插入新行。

  6. 如果合适,请在级联删除abstract_addresses的{​​{1}}上添加删除后触发器 - 确保在 删除后 ,当您从phone_numbers删除时,受影响的行会报告错误的值。

  7. 这样,你就会有一个abstract_addresses用于偶尔需要这样的东西的表,同时仍然可以对phone_numbers进行硬引用,后者就是你真正想要的

    需要注意的一点是:它与ORM不相符。