这取决于人与地址的关系是一对零加还是一对一加。
如果一个人需要有一个主要地址,我会把它放在Persons 表本身中(因为它是一个必需的属性)。
另一方面,如果一个人可以在没有地址的情况下存在于您的架构中,我会将Addresses 表中的所有地址保持相同,并使用Persons 表的属性来选择主要的(NULL或指向相关Addresses 行的指针)。
如果您将地址的素数存储在 Addresses 表中,当 Bob Smith 的两个地址都声称是主要地址时,您会怎么做?您可以使用触发器来阻止这种情况,但正确设计架构会更有效。
而且,如果两个室友共享同一个地址,但一个人一直住在那里,而另一个人大部分时间都和他的女朋友同居,那会发生什么?如果素数在 Addresses 表中,您将无法在人员之间共享地址行。
我想要表达的是,您需要将属性分配给正确的对象。一个人的主要地址属于一个人,而不是一个地址。
为了最大限度地提高效率和灵活性,我将采用以下架构:
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 中的每一行都至少有一个地址(那些主地址未知的人会自动将他们的PrimaryAddressid 设置为“未知”地址行。
然后你可以使它成为一个适当的约束关系并稍微简化你的 SQL。在现实世界中,实用主义往往胜过教条主义:-)