【发布时间】:2016-02-01 10:41:36
【问题描述】:
我遇到了一个相当有趣的情况,我需要指导来帮助我设计遵循“最佳实践”或“推荐方式”的数据库架构。
我的困境如下:
我有一个 Event 表,其中包含 Id、Name、Date 等基本属性。它需要地址信息,因此最直接的方法是使用街道、城市、国家等字段扩展表。好吧,我还有一个 User 表,它也需要存储地址数据。所以正确的做法是创建第三个名为 Address 的表,并在 Address/User 和 Address/Event 之间建立关系。这是棘手的部分。哪个表应该保存主键/外键。
-
一种方法是使用诸如
EventId和UserId之类的列来扩展表Address。所以表Event和User将是“父”表,地址将是“子”表。Address表将保存用户/事件的 Id 主键的外键。|EventTable:| |UserTable: | |AddressTable| | | | | | | |EventId PK | |UserId PK | |AddresId PK | |Name | |Name | |Street | |OtherColumn| |OtherColumn| |City | |EventId FK | |UserId FK |我从这种设计中看到的两个缺点是,对于每一行
AddressTable将包含额外的不必要的 Null 字段。例如,如果地址指定用户地址,则列EventId将为空,如果地址行指定事件地址,则列UserId将为空。第二个缺点是,每当我添加一个也需要连接到地址表的新表时,我就需要向表地址添加另一列,该列将引用新表的主键。
-
第二种可能性是使用
Address的主键列扩展表Event和User,以便它们成为关系中的外键。|EventTable:| |UserTable: | |AddressTable| | | | | | | |EventId PK | |UserId PK | |AddresId PK | |Name | |Name | |Street | |OtherColumn| |OtherColumn| |City | |AddressId FK| |AddressId FK|除了在外键上启用级联删除时我现在有疑问之外,这个解决方案一切都将是完美的。对我来说,自然的想法是,当我删除数据库的事件或用户时,我也希望删除他们的地址。但在这样的设计中,地址表是父表,用户/事件是子表。因此,当我删除启用级联删除的地址条目时,我也会删除事件/用户条目。从逻辑上讲,这对我来说没有太大意义。应该是相反的,这是我无法解决的问题。也许第二种设计是可以接受的,我只是无缘无故地让自己感到困惑。
理想情况下,我很想提出这样的设计,通过启用级联删除,我首先删除事件或用户,然后他们的地址将被自动删除。
我知道联合表有第三种选择,但这仅适用于多对多关系,如果用户/事件应该只包含一个地址。
谢谢!
【问题讨论】:
标签: sql sql-server entity-framework database-design table-relationships