假设我正在编写供派对策划者使用的软件。这是我当前的数据库架构的样子:
Parties ( PartyId, ClientId, DateTime )
Tents ( PartyId, TentDetails... )
Clowns ( PartyId, ClownDetails... )
SecurityAgentAssignment ( PartyId, AgentId, fromTime, untilTime )
如您所见,一个派对可以有多个帐篷、小丑和安全特工分配给它。
现在,派对策划师经常策划相同类型的派对:大多数有一个帐篷,一个小丑,没有保安;但还有另一种常见的派对类型,有三个帐篷,没有小丑,三个保安人员参加派对。他们希望能够存储“预设”(也称为“派对包”或“派对模板”),选择这些预设会在数据库中添加必要的帐篷、小丑和安全行。派对仍然可以像往常一样自定义,当然,这只是最小化初始数据输入的一种手段。
现在的问题是,我将如何实现它?
最直接的方法是复制Tents
、Clowns
和SecurityAgentAssignment
表并添加一个新Packages
表,如下所示:
Packages ( PackageId, Name )
Package_Tents ( PackageId, TentDetails... )
Package_Clowns ( PackageId, ClownDetails... )
Package_Security ( PackageId, AgentId )
然后 biz 逻辑必须Tent
从行创建Package_Tent
行,它不能通过INSERT INTO SELECT FROM
语句来完成,因为两个模式不同(例如,Package_Security
缺少fromTime
anduntilTime
字段)。
这种方法简单且有效,但存在一些问题:
- 这意味着只为 Package 系统复制大量表。这就是项目变得臃肿的方式。
- 它引入了额外的维护层:如果我修改原始表,那么我也必须修改这些表。
- 不知何故,这似乎是“错误的”。
第二种方法意味着使用现有表,但添加一个新表,如下所示:
Packages ( PackageId, Name, PartyId )
此Packages
表链接到现有Party
行(及其关联的帐篷、小丑和安全行)。它链接到的派对不存在(或者更确切地说,它的细节无关紧要),它成为新派对的模板,只需在单个表中复制行,而不是在另一个表中创建新表中的行桌子。这种方法还有一个优点是允许用户使用现有的 GUI 来修改包作为原型方,而不是拥有单独的 GUI 工具/区域。
但是它存在“杂质”:现在一个政党的状态如何作为“政党”而不是“政党模板”取决于它是否是Packages
表中的外键。这也意味着存在无效或无意义的数据(例如,在聚会模板中使用fromTime
and for Security 是没有意义的)。untilTime
StackOverflow 是否偏爱一种方法而不是另一种方法,还是有第三种方法?