数据库中的专有弧是什么?为什么它是邪恶的?


10

我正在阅读开发人员对Stackoverflow进行问答时最常见的数据库设计错误。最初的答案是关于专有弧的短语:

如果用两个或多个外键创建一个表,并且其中一个只能为非空,则独占弧是一个常见错误。大错。一方面,维护数据完整性变得更加困难。毕竟,即使具有参照完整性,也无法阻止设置两个或多个这些外键(尽管有复杂的检查约束)。

我真的不明白为什么排斥弧是邪恶的。可能我不了解它的基本知识。排他弧线有什么好的解释吗?

Answers:


8

据我很久以前的了解,在一个专有弧中,一个表包含许多列,这些列是其他表的外键,但是一次只能设置其中的一个(由于对域的某些逻辑约束)以下来自现实世界)。由于无法在数据库上强制执行此规则,因此可能会创建损坏的记录,其中多个外键中的一个具有一个值。

我举一个例子。考虑一个公司跟踪其用于运送货物的卡车的应用。卡车只能同时位于三个位置之一:可以与员工一起使用,可以在停车场中或可以在维修店中使用。可以通过创建一个包含employeeId,parkingGarageId和maintenanceShopId的Truck表来建模,并引用Employee,ParkingGarage和MaintenanceShop表。无法强制执行以下规则:仅在数据库级别填写这些字段之一。错误的代码或可以直接访问数据库的人可能会插入一条记录,该记录具有两个或三个填充的字段,这将导致数据库中的数据损坏。


4
这三个可能的卡车位置是超类“卡车位置”的子类。在许多情况下,子类是互斥的。挑战在于如何在关系表中对类和子类建模。
Walter Mitty 2014年

我同意在某些情况下使用这种设计是合理的。但是,我也可以同意原始文章,即使用此模式的次数要多得多。它也有一些很大的缺点...
JDT 2014年

6
无法使用检查约束?例如alter table mytable add constraint myconstraint check ((col1 is not null and col2 is null and col3 is null) or (col1 is null and col2 is not null and col3 is null) or (col1 is null and col2 is null and col3 is not null))。我不喜欢专有弧,但是可以通过检查约束来强制执行。当然也必须存在FK约束。
图兰斯·科尔多瓦

1
因此,上面引用的帖子中的“尽管有复杂的检查约束”。您可能能够使用检查约束或异常(甚至触发器)进行真正复杂的验证,但这并不是一个好主意或良好设计的代名词。想象一下在具有四或五列的互斥弧上执行检查约束...另外,我相当确定不是所有的数据库引擎都支持CHECK约束。MySQL在文档中明确声明已解析CHECK子句,但被忽略了……
JDT 2015年

此消息来源推荐排他弧。有什么想法吗?
Alex Moore-Niemi

4

专有弧没有什么坏处。只需使用检查约束来实施相应的业务规则。大多数主要的数据库管理系统都支持检查约束(Oracle,SQL Server,PostgreSQL)。如果您使用的是数据建模工具,那么您的工具很有可能会自动生成代码以实现检查约束。


-1

专有弧在概念或逻辑设计中非常有用。这并不意味着您必须采用这种方式。在较早的示例中,设计人员可以决定使用三个表来实现设计。一种用于停车位,一种用于员工,另一种用于维修店。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.