目前我有一个看起来像这样的模式:
create table person(
id uuid primary key default gen_random_uuid() not null,
);
create table car(
id uuid primary key default gen_random_uuid() not null,
);
create table extra(
id uuid primary key default gen_random_uuid() not null,
);
create table car_extra_m2m(
car_id uuid not null references car(id) on delete cascade,
extra_id uuid not null references extra(id) on delete cascade,
primary key (car_id, extra_id)
);
create table person_extra_m2m(
person_id uuid not null references person(id) on delete cascade,
extra_id uuid not null references extra(id) on delete cascade,
primary key (person_id, extra_id)
);
是否可以在一个多对多表中表示两个多对多表?由于我们使用的是 uuid,所以 id 永远不会发生冲突,所以有可能仅从 uuid 知道类型?
像这个伪代码:(编辑:postgresql 中的语法无效,是否存在有效的语法?)
create table extra_m2m(
person_or_car_id uuid not null references (person(id) or car(id)) on delete cascade,
extra_id uuid not null references extra(id) on delete cascade,
primary key (person_or_car_id, extra_id)
);
是的,如果它更适合您的用例,那么没有理由不这样做,这种设计没有任何问题。我唯一的建议是添加一个
extra_type
字段来明确标识记录是类型person
还是car
. 您以后可能会发现类似的字段会有所帮助。但是,是的,这是一个有效的模式设计。在评论中进一步澄清之后,您必须进行一些更改才能在本地完成此操作,以便仍然能够支持数据库中的外键约束(否则您要寻找的是多态外键,它不是本机支持)。
第一个变化是您必须将您的
person
和car
表合并到一个表中,例如person_or_car
使用person_or_car_id
主键字段。第二个更改是您需要extra_type_id
在表中添加一个字段以person_or_car
区分两者。最后,您需要将extra_type_id
字段添加到extra_m2m
表中,并在其上创建外键约束。extra_type_id
如评论中所述,第 3 步的字段示例查询:我认为两者都是有效的,它归结为其他要求,特别是报告。
如果您需要报告额外内容,而不管它们与什么相关(或它们与什么相关),那么将所有关系放在一个表中将比需要合并两个选择更有效。
但是,如果您最终需要额外的字段来详细说明额外人员和其他实体之间的每个关系,并且这些详细信息在汽车/人/其他之间有所不同,那么您最终会开始想要使用表继承模式再次拆分事物,因此最终会得到三个桌子代替你的两个。
在不知道现在或将来此类要求的可能性的情况下,尚不清楚哪种方式最适合您的需求,但我想说这两种方式都不是绝对错误的。