这是一个场景:你有一个与一个Addresses表有一对多关系的Persons表,其中一个Address行是“主要”地址。
在规范化架构中是否更好
或
或
为什么?
答案 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”布尔值将是一个有吸引力的选择(它仍然使它不太虽然其他约束,例如“地址属于至少一个人”或反之亦然,但很难强制执行上述某些约束,但这些限制可能很难表达。
要保留的课程:准确表达您的架构需要简单表达的约束,并且为此目的的正确架构通常会非常清楚地显示出来。如果感兴趣的约束是一个谜,那么问题的答案是“什么是正确的架构”; - )。