【问题标题】:Constraint for nullable column involving column of another table涉及另一个表的列的可空列的约束
【发布时间】:2018-06-17 16:08:05
【问题描述】:

我有两张桌子:

table1:
id bigserial not null,
value1 integer not null

table2:
id bigserial not null,
table1_id bigint not null,(FK)
value2 character varying not null,
value3 character varying,

我需要添加一些约束以确保当value3 不为空时,value3value2table1.value1 的组合对于table2 应该是唯一的。我该怎么做?

【问题讨论】:

  • 您的 Postgres 版本?而table1.value1 没有被定义为 UNIQUE? (table1.id 显然需要 PK 或 UNIQUE 约束来允许 FK。)编写模式? table1 是只读的吗?
  • table1.value1 不是唯一的。 Table1.id 是一个 PK。 Postgres 9.4 版
  • edit问题提供完整信息。评论不是地方。

标签: postgresql database-design foreign-keys constraints unique-constraint


【解决方案1】:

对于初学者,你可以有一个部分 UNIQUE 索引

CREATE UNIQUE INDEX table2_foo_idx ON table2 (value3, value2, table1_id)`
WHERE value3 IS NOT NULL;

相关:

但是这不考虑table1value1 的重复值。这不能通过没有恶意技巧的约束来强制执行,因为所有相关的约束只涉及同一个表的列。

有多种解决方法,具体取决于完整的情况。触发器,使用假不可变函数的部分功能唯一多列索引,(NOT VALIDCHECK 约束...

一种干净的方法是在table2中冗余存储value1,用ON UPDATE CASCADE添加多列FK约束并创建上面提到的唯一索引:

CREATE TABLE table1 (
   table1_id bigserial PRIMARY KEY
 , value1    text NOT NULL
 , UNIQUE   (value1, table1_id)  -- logically redundant, neede for FK
);

CREATE TABLE table2 (
   table2_id bigserial PRIMARY KEY
 , table1_id bigint NOT NULL
 , value1    text NOT NULL
 , value2    text NOT NULL
 , value3    text
 , FOREIGN KEY (table1_id, value1) REFERENCES table1(table1_id, value1) ON UPDATE CASCADE
);

CREATE UNIQUE INDEX table2_foo_idx ON table2 (value3, value2, value1)`
WHERE value3 IS NOT NULL;

相关:

在唯一索引和约束中选择适当的列顺序,以便在不添加更多索引的情况下最好地支持典型查询。比较:

【讨论】:

  • table1中的Value1可以重复
猜你喜欢
  • 1970-01-01
  • 2014-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
  • 1970-01-01
  • 2021-05-08
  • 1970-01-01
相关资源
最近更新 更多