具有“主要”实体的子集合的最佳模式设计是什么

时间:2010-05-18 04:13:53

标签: database-design database-schema

这是一个场景:你有一个与一个Addresses表有一对多关系的Persons表,其中一个Address行是“主要”地址。

在规范化架构中是否更好

  • 使用Persons.PrimaryAddressID访问人员的“主要”地址

  • 使用Addresses.IsPrimary位列通过Addresses.PersonID
  • 引用人员的“主要”地址

  • 其他

为什么?

3 个答案:

答案 0 :(得分:1)

这取决于人与地址之间的关系是一对多加一对还是一对一加。

如果要求某人拥有主要地址,我会将其放在Persons表中(因为它是必需的属性)。


另一方面,如果一个人可以在没有地址的模式中存在,我会将Addresses表中的所有地址保持相等,并使用Persons表的属性来选择primary(NULL或指向相关Addresses行的指针)。

如果您在Addresses表中存储地址的素数,当Bob Smith的两个地址都声称是主要地址时,您会怎么做?您可以使用触发器来停止它,但是正确设计架构会更有效率。

并且,如果两个室友共用同一个地址,但是一个人一直住在那里,而另一个人大部分时间都和他的女朋友一起度过,那么会发生什么呢?如果素数在地址表中,您将无法在人员之间共享地址行。


我想要了解的是,您需要将属性分配给正确的对象。一个人的主要地址属于一个人,而不是一个地址。

为了获得最大的效率和灵活性,我将拥有以下架构:

Persons:
    Id                 primary key
    PrimaryAddressId
    OtherStuff
Addresses:
    Id                 primary key
    OtherStuff
PersonAddresses:
    Id                 primary key
    PersonId           foreign key on Persons(Id)
    AddressId          foreign key on Addresses(Id)

您有轻微的数据完整性问题Persons.PrimaryAddressId可能是悬挂指针。您不能将其作为其中一个主键的外键,因为您希望它允许NULL。这意味着您必须满足它可能指向不存在的Addresses.Id的可能性。

我只是将其修复为Addresses上的删除前触发器,以便更新相关的Persons行(将PrimaryAddressid设置为NULL)。

或者你可能会很棘手并且Addresses表中有一个“未知”地址,因此Persons中的每一行都至少有一个地址(主要地址未知的地址会自动获取{ {1}}设置为“未知”地址行。

然后你可以使它成为一个适当的约束关系并在某种程度上简化你的SQL。实用主义经常在现实世界中击败教条主义: - )

答案 1 :(得分:0)

我会选择“使用Persons.PrimaryAddressID来访问”人员的“主要”地址“。 仅当Person链接到地址时,主地址才有意义。所以它应该属于Person。考虑以下第二种方法失败的情况。

a)地址与另一个实体一起使用,但没有引用Addresses.IsPrimary毫无意义的人。

b)两个人使用相同的地址,其中第一个用作主要用途而第二个用作主要用途。

答案 2 :(得分:0)

如果您希望约束是一个人最多只有一个主要地址,那么Persons.PrimaryAddressID显然更简单 - 实际上,它是由该模式强制执行的。也很容易确保每人只有一个主要地址(只需使该列不为空),如果需要,甚至可以说没有两个人可以共享主地址(只需要创建该列)是独一无二的。)

当然,正是因为这种方法擅长强制执行这样简单的约束,所以当你想要这些约束时这很糟糕 - 例如,如果你想让一个人可以如果有一个以上的“主要”地址,那么这种方法就行不通。

顺便说一句,我不认为单人/多地址关系特别好除非你想强制执行这样一个事实:没有两个人可以共享同一个地址:一般来说,一个正常化的情绪,我宁愿有一张人,一个地址和一个关系的表(在大多数情况下,这自然是多对多的,因为很多人可以,在现实生活中,可以分享同一地址)。

如果你选择走这条路,那么,特别是如果你需要很高的灵活性(多个主要地址和c),让关系表带有“primality”布尔值将是一个有吸引力的选择(它仍然使它不太虽然其他约束,例如“地址属于至少一个人”或反之亦然,但很难强制执行上述某些约束,但这些限制可能很难表达。

要保留的课程:准确表达您的架构需要简单表达的约束,并且为此目的的正确架构通常会非常清楚地显示出来。如果感兴趣的约束是一个谜,那么问题的答案是“什么是正确的架构”; - )。