设计具有双向可选1:1关系的数据库时遇到困难

时间:2014-03-21 00:53:05

标签: mysql sql database relational-database erd

假设你有两个实体......汽车和破坏者。

汽车可以没有扰流板或最多只有一个扰流板。

扰流板既可以放在架子上,也可以安装在一辆车上。

系统的设计方式,扰流器详细信息将首先存储,并且可能与现有汽车在其生命周期内相关或不相关。

定义这两个表之间关系的最佳方法是什么?

我的第一个想法是在链接到另一个表的主要表的每个表中创建外键:

CARS CarId CarDesc SpoilerId

SPOILERS SpoilerId SpoilerDesc CarId

但我觉得当我尝试删除时会遇到完整性限制。

我的第二个想法是在CARS表中只有一个外键用于剧透,如果我需要检索架子上的所有剧透,我可以运行类似于 SELECT * FROM SPOILERS WHERE SPOILER.SPOILDERID NOT IN (SELECT SPOILERID FROM CARS) 但这并不意味着我每次想要找出哪些破坏者都在架子上时我必须进行全表扫描?如果我期望每张表中有数十万条记录,这会对性能产生影响吗?

我的第三个想法是创建一个汇合表:

CARS CarId CarDesc

CARS_SPOILERS SpoilerId CarId

SPOILERS SpoilerId SpoilerDesc

但这不会为汽车定义多个扰流板的可能性,反之亦然?我应该将CARS_SPOILERS.SpoilerId和CARS_SPOILERS.CarId设置为唯一吗?

除了上面提到的之外,还有更好的方法吗?

由于

2 个答案:

答案 0 :(得分:0)

考虑使用带有扰流器引用(id)的Car表作为描述扰码器(不引用Car)的Spoiler表的外键。

你可以找到卸载的破坏者(选择*来自Spoiler,其中不包括spoilerid(从汽车中选择spoilerid)。如果存在性能问题,你可以在汽车中索引spoilerid。

简单的。

答案 1 :(得分:0)

我将使用“收敛”表(我称之为联结或关联表)来捍卫你的最后一种方法。

首先,您可以通过要求CarIdSpoilerId都是唯一的来强制执行唯一性。当MySQL可以强制执行关系约束而不必使用触发器时非常方便。

但主要原因是审美。我想要描绘你的汽车,破坏者和货架的世界。然后我在想:“嗯,也许有不止一个架子。”如果有,它包含什么扰流板?我不想拥有一张Shelves_Spoilers桌子,以便我可以回答有关架子及其剧透的问题吗?

美学原因是对称性Shelves_SpoilersCars_Spoilers