概述:我试图在数据库中表示几种类型的实体,它们有许多共同的基本字段,然后每个都有一些不与其他类型的实体共享的附加字段。工作流程经常涉及将实体列在一起,所以我决定有一个包含公共字段的表,然后每个实体都有自己的表和附加字段。
实施:所有实体都有一个公共字段“状态”;但是,某些实体仅支持所有可能状态的子集。我还希望每种类型的实体都强制使用其状态子集。最后,我还希望在将实体一起列出时包含该字段,因此将其从公共字段集中排除似乎是不正确的,因为这需要特定类型表的联合,并且 SQL 中缺少“实现接口”意味着列入该领域将是惯例。
为什么我在这里:下面是一个功能性的解决方案,但如果有更好或更常见的方法来解决问题,我很感兴趣。特别是,这个解决方案需要我做一个冗余的unique
约束和一个冗余的状态字段,这让人感觉很不雅。
create schema test;
create table test.statuses(
id integer primary key
);
create table test.entities(
id integer primary key,
status integer,
unique(id, status),
foreign key (status) references test.statuses(id)
);
create table test.statuses_subset1(
id integer primary key,
foreign key (id) references test.statuses(id)
);
create table test.entites_subtype(
id integer primary key,
status integer,
foreign key (id) references test.entities(id),
foreign key (status) references test.statuses_subset1(id),
foreign key (id, status) references test.entities(id, status) initially deferred
);
一些数据:
insert into test.statuses(id) values
(1),
(2),
(3);
insert into test.entities(id, status) values
(11, 1),
(13, 3);
insert into test.statuses_subset1(id) values
(1), (2);
insert into test.entites_subtype(id, status) values
(11, 1);
-- Test updating subtype first
update test.entites_subtype
set status = 2
where id = 11;
update test.entities
set status = 2
where id = 11;
-- Test updating base type first
update test.entities
set status = 1
where id = 11;
update test.entites_subtype
set status = 1
where id = 11;
/* -- This will fail
insert into test.entites_subtype(id, status) values
(12, 3);
*/