【问题标题】:Why does this foreign key using inheritance not work? [duplicate]为什么这个使用继承的外键不起作用? [复制]
【发布时间】:2013-11-26 21:09:56
【问题描述】:
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 表继承只是一个糟糕的用例?

【问题讨论】:

  • 电话号码插入有效,因为您没有在 phone_numbers 上为 abstract_addresses 创建外键。
  • @GriffeyDog,插入 phone_numbers 后, abstract_addresses 在其 address_id 中的值为 1。

标签: postgresql inheritance


【解决方案1】:

根据文档中的警告:

继承特性的一个严重限制是索引(包括唯一约束)和外键约束仅适用于单个表,而不适用于它们的继承子表。在外键约束的引用侧和被引用侧都是如此。

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

做你想做的事:

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

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

  3. 将电话号码 ID 默认设置为 nextval('abstract_addresses_address_id_seq'),或任何序列名称。

  4. phone_numbers 中添加一个外键引用abstract_addresses (address_id)。使其可延期,最初延期。

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

  6. 如果合适,在 phone_numbers 上添加一个删除后触发器,该触发器级联删除 abstract_addresses — 确保它发生在删除 之后,否则受影响的行当您从phone_numbers 中删除时,将报告不正确的值。

这样,您将有一个 abstract_address 用于偶尔需要这种东西的表,同时仍然可以硬引用 phone_numbers,后者是您真正想要的。

需要注意的一个警告:它不适用于 ORM。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 2015-06-10
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 2021-11-29
    • 2015-11-14
    • 2013-02-24
    相关资源
    最近更新 更多