规范化共享实体并应用约束

Lou*_*ers 2 normalization database-design design-pattern subtypes

我正在寻找关于在不同实体之间共享的实体的特定“最佳实践”或“模式”,这些实体与众多实体中的一个有关系。

例如,可能有通用实体“地址”,它可用于存储客户、供应商、员工等的公共地址字段......

经验丰富的 DBA 会采取这种方式,还是宁愿将字段添加到相应的实体中?我也在考虑可维护性,可能(将来)会因实体而异的约束,诸如此类。

我很想得到有关该主题的任何权威或既定作品的参考。

Joe*_*own 5

将各种地址堆积到单个表中的动机通常是对代码重用概念的误解和误用。

人们可能会错误地假设,因为您有两个具有一些公共属性集的实体,这些属性属于它们自己的表。有时,实体巧合地具有相似或相同的列。人们不会为您的数据库中的每个NAMEDESCRIPTION或其中创建一个表EFFECTIVE_DATE,至少我希望人们不会这样做。

有些人错误地将所有删除列到他们自己的表中的实例称为规范化。规范化涉及将列删除到它们自己的表中,但并非每个以这种方式删除列的实例实际上都是规范化。规范化规定了从表中删除列的非常具体的原因。如果这些原因都不适用,那么您就没有正常化,只是让事情变得复杂。

你有两种正确的思考方式:要么你的地址都属于一个堆,因为你有一个实体超类型,它包含了几个实体子类型的所有共同特征,包括地址,或者 - 你的地址属于不同的堆(表)根据具有地址的每种事物,然后针对为每个地址表实现的 IAddress 接口编写程序代码。

如果你确实有一个实体的超类型,说LEGAL_ENTITY其具有亚型像CUSTOMERVENDOREMPLOYEE等等,然后有一个ADDRESS表,它的孩子LEGAL_ENTITY是合法的做法。如果您的客户、供应商、员工(或您正在跟踪的任何对象)之间存在大量重叠,这甚至可能是一种有价值的方法,因为您可以在法人实体移动时更改地址一次,而不是在多个位置。另一方面,如果你没有这样的超级类型,那么你将面临Richard Tallent指出的问题。

如果您根据拥有地址的实体类型将地址保存在不同的表中,那么您仍然可以实现代码重用,假设您使用的语言支持接口。

顺便说一句:tvCa 在评论中指出地址可以存储为列而不是单独表中的行。这在很大程度上取决于每个实体需要多少地址。如果您要跟踪两个地址(物理地址、邮寄地址),或者您要存储地址历史记录,请使用地址表。如果您只为每个收件人存储一个地址,那么单独的表可能有点过分。