PostgreSQL外键约束违反继承

时间:2017-03-11 04:37:51

标签: sql postgresql foreign-keys

我有一个PostgreSQL数据库,3个表和我的架构如下

--- Parent Table

CREATE TABLE IF NOT EXISTS abc.parent(
    record_id         SERIAL PRIMARY KEY,
    description       text NOT NULL
);

--- Child Table


CREATE TABLE IF NOT EXISTS abc.child ( 
    total_count INT NOT NULL)  INHERITS (abc.parent);

-- Detail

CREATE TABLE abc.detail(
    detail_id      int NOT NULL,
    detail_description       text NOT NULL
    record_id         int NOT NULL,
    FOREIGN KEY (record_id) REFERENCES abc.parent(record_id)
);

然后我将记录插入父表和子表中。

|record_id|description|
|1        |abcd       |
|2        |efgh       |

|record_id|description|total_count|
|3        |xygh       |5          |
|4        |mnop       |7          |

当我尝试将记录插入详细信息表后,两个entires成功

Detail
|detail_id|detail_description|record_id|
|100      |detail_desc1      |  1      |
|200      |detail_desc2      |  2      |

但是我无法使用record_id 3插入条目,它给了我一个外键违规错误

有人可以解释这个错误吗?

我们可以在Postgresql中使用继承创建这样的外键关系吗

2 个答案:

答案 0 :(得分:1)

不,那不行。

the documentation说:

  

继承功能的一个严重限制是索引   (包括唯一约束)和外键约束仅适用   单个表,而不是他们的继承子。这是真的   在外键约束的引用和引用方面。

“全局索引”是表继承的重要缺失功能之一。

答案 1 :(得分:1)

很抱歉,您的回答很晚。与其他答案一样,约束不会被继承,因此在您的情况下,父表在record_id上具有主键,但是子表没有相同的约束。没有主键,外键无法指向它。

尽管也可以通过向子表添加主键约束来轻松解决此问题。下面的结构可以正常工作:

CREATE TABLE IF NOT EXISTS abc.parent
(
    record_id         SERIAL,
    description       text NOT NULL,
    CONSTRAINT parent_pkey PRIMARY KEY (record_id)
);

--- Child Table

CREATE TABLE IF NOT EXISTS abc.child 
( 
    total_count INT NOT NULL,
    CONSTRAINT child_pkey PRIMARY KEY (record_id)
)  INHERITS (abc.parent);

-- Detail

CREATE TABLE abc.detail
(
  detail_id integer NOT NULL,
  detail_description text NOT NULL,
  record_id integer NOT NULL,
  CONSTRAINT detail_pkey PRIMARY KEY (detail_id),
  CONSTRAINT detail_record_id_fkey FOREIGN KEY (record_id)
      REFERENCES abc.parent (record_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
);

这将完美地工作,并允许在详细信息表中引用子记录。请注意,作为一种很好的做法,我还向详细信息表添加了一个主要名称(尽管它并没有帮助回答您的问题)。

有趣的是,您正在对CREATE TABLE语句中未提及的列创建约束。这是继承列的本质,但起初可能并不明显。

从PostgresSQL版本10开始,不支持约束继承,因此必须在子表上重新创建约束(唯一,主键,外键等)。希望他们尽快解决此问题。