简化构建MATCH SIMPLEfk 约束的行为
如果多列外部约束中至少有一列具有默认值MATCH SIMPLE
行为是NULL
,不强制执行约束。您可以在此基础上进一步简化您的设计。
CREATE SCHEMA test;
CREATE TABLE test.status(
status_id integer PRIMARY KEY
,sub bool NOT NULL DEFAULT FALSE -- TRUE .. *can* be sub-status
,UNIQUE (sub, status_id)
);
CREATE TABLE test.entity(
entity_id integer PRIMARY KEY
,status_id integer REFERENCES test.status -- can reference all statuses
,sub bool -- see examples below
,additional_col1 text -- should be NULL for main entities
,additional_col2 text -- should be NULL for main entities
,FOREIGN KEY (sub, status_id) REFERENCES test.status(sub, status_id)
MATCH SIMPLE ON UPDATE CASCADE -- optionally enforce sub-status
);
It is 非常便宜存储一些额外的 NULL 列(对于主要实体):
- 使用 postgresql DB 存储 NULL 值需要多少磁盘空间?
BTW, 根据文档:
If the refcolumn
列表被省略,主键reftable
用来。
演示数据:
INSERT INTO test.status VALUES
(1, TRUE)
, (2, TRUE)
, (3, FALSE); -- not valid for sub-entities
INSERT INTO test.entity(entity_id, status_id, sub) VALUES
(11, 1, TRUE) -- sub-entity (can be main, UPDATES to status.sub cascaded)
, (13, 3, FALSE) -- entity (cannot be sub, UPDATES to status.sub cascaded)
, (14, 2, NULL) -- entity (can be sub, UPDATES to status.sub NOT cascaded)
, (15, 3, NULL) -- entity (cannot be sub, UPDATES to status.sub NOT cascaded)
SQL小提琴(包括你的测试)。
单 FK 的替代方案
另一种选择是输入以下的所有组合(status_id, sub)
进入status
表(每张只能有 2 个status_id
) 并且只有一个 fk 约束:
CREATE TABLE test.status(
status_id integer
,sub bool DEFAULT FALSE
,PRIMARY KEY (status_id, sub)
);
CREATE TABLE test.entity(
entity_id integer PRIMARY KEY
,status_id integer NOT NULL -- cannot be NULL in this case
,sub bool NOT NULL -- cannot be NULL in this case
,additional_col1 text
,additional_col2 text
,FOREIGN KEY (status_id, sub) REFERENCES test.status
MATCH SIMPLE ON UPDATE CASCADE -- optionally enforce sub-status
);
INSERT INTO test.status VALUES
(1, TRUE) -- can be sub ...
(1, FALSE) -- ... and main
, (2, TRUE)
, (2, FALSE)
, (3, FALSE); -- only main
Etc.
相关回答:
- 完整匹配与简单匹配
- 仅当第三列为 NOT NULL 时才使用两列外键约束
- 当验证在另一个表上有条件时,数据库中的唯一性验证
保留所有表
如果您出于某种原因需要所有四个表,而不是在问题中,请考虑 dba.SE 上一个非常相似的问题的详细解决方案:
遗产
...可能是您所描述的另一种选择。如果你能和一些主要限制。相关回答: