Database design 如果支持ORM设计扰乱了我的数据库怎么办?

Database design 如果支持ORM设计扰乱了我的数据库怎么办?,database-design,Database Design,我有一个系统,用户可以对各种类型的对象提出索赔-- 用户由“单元”表示,单元是组织饼图中自包含的一部分。为其中一个对象创建声明后,可以设置声明的状态。看起来很简单,对吧 好吧,这就是头痛的开始。如上所述,这些东西形成了一个松散的等级体系。超级用户使用少量链接表为每个对象创建模板。团队可以由设施、设备和人员组成,设施由设备和人员组成,单元可以为他们想要的任何东西创建索赔。非常灵活,但后端很烦人 团队、设施、设备和人员具有完全相同的列: Id, Name, Description, DateC

我有一个系统,用户可以对各种类型的对象提出索赔--

用户由“单元”表示,单元是组织饼图中自包含的一部分。为其中一个对象创建声明后,可以设置声明的状态。看起来很简单,对吧

好吧,这就是头痛的开始。如上所述,这些东西形成了一个松散的等级体系。超级用户使用少量链接表为每个对象创建模板。团队可以由设施、设备和人员组成,设施由设备和人员组成,单元可以为他们想要的任何东西创建索赔。非常灵活,但后端很烦人

团队、设施、设备和人员具有完全相同的列:

Id, 
Name, 
Description, 
DateCreated, 
CreatedById, 
IsArchived
为了与ORM概念保持一致,现在每一个都是一个单独的表。当用户需要创建声明时,真正的痛苦就来了。层次结构将留给我们以下表格:

TeamClaim, FacilityClaim, EquipmentClaim, PersonnelClaim, TeamFacilityClaim, 
TeamEquipmentClaim, TeamPersonnelClaim, so on and so forth.  
再加上每个索赔表的另一个状态表

显然,这只是垃圾

因此,我将我的设计更改为一个表,称为ClaimableItem。它有上面定义的列,加上一个“类型”列;那只是三个字母的陈述。然后,我创建了一个名为Claim的表——它包含所有必要的列,并使用一个复合唯一键定义为ClaimableItemId和ClaimableItemType

我已经用我的C代码测试过了。EF4可能不喜欢重用密钥,但一个小的解决方法(hack)使它相对容易完成;我可以在大约一个小时内更改所有的模型、视图和控制器代码,以适应新的内容

我的问题(最后)是:我的新单表设计是垃圾吗?它可以防止我的数据库被表弄乱,并且实际上可以加快添加新的ClaimableItem类型——无需为它们创建新对象。我的问题是,三个字母的表示法在直觉上一文不值,必须在代码中处理,这有点让我对纯粹主义者感到恼火


有人知道如何更好地做到这一点吗?

听起来是继承的好例子。让
团队、设施、设备、人员
继承
索赔项目
,并提出
索赔
参考
索赔项目

这实际上与你的建议非常相似。你说:

因此,我将我的设计更改为一个表,称为ClaimableItem。信息技术 具有上述定义的列,加上“类型”列;那只是一个玩笑 三个字母的陈述。然后我创建了一个名为 声明——它具有所有必需的列,并带有复合唯一键 定义为ClaimableItemId和ClaimableItemType

我认为您不需要复合外键。它们
类型
鉴别器列可以位于
索赔项目
表中

这是纯的吗?我想是的。这是一个完美的继承案例


最后一点意见:在这种情况下,凭直觉行事。如果你觉得一个解决方案是垃圾,你注意到自己希望得到更简单的解决方案,那就去做吧。权衡有时是不明确的选择,开发人员会随着时间的推移本能地判断长期内什么是正确的。

首先,你有一些错误的假设

  • 以任何特定的方式创建表并不是“遵循ORM概念”
  • 没有必要为每种类型都提供单独的表格
  • 没有必要到处都有链接表
  • 大多数ORM支持一种使用列鉴别器的继承形式,通常是某种类型的类型值,这与您提出的解决方案相同

    这是设计数据模型和数据库的一种非常实用的方法,但它并不完全是一种“纯粹”的数据库设计概念,因为您可以不再使用引用完整性和约束来确保只有某些值意味着某些事情

    例如,当您有一个TeamClaim链接表时,您可以(通过使用引用完整性)保证加入的每个值都是一个团队和一个声明,因为它们是数据库中不同的实体

    如果您打算将团队与索赔链接,但将设施与索赔链接,会发生什么情况?哎呀。数据库也不可能知道你犯了错误

    这类似于一个真正的查找表问题


    但是,对许多人来说,失去引用完整性只是为了获得更大的灵活性而付出的小小代价。您只需在代码中非常小心,不要让人们手动乱动表格。

    为什么您的输入必须只有3个字母?让它足够大(10-15),这样字体就可以辨认了。@GilbertLeBlanc实际上,我建议不要这样。一个具有一组已知值(实际上是一个枚举)的简单整数(甚至只是CHAR(1)或byte,具体取决于DBMS)将需要最小的空间,因此可以更好地使用缓存。没有特别的理由说明这个字段应该是人类可读的。@Branko Dimitrijevic:我同意。人类可读的名称应该放在域表中,整数id应该放在数据行中。@GilbertLeBlanc:谢谢。域表击中了我正在寻找的头部。
    TeamClaim, FacilityClaim, EquipmentClaim, PersonnelClaim, TeamFacilityClaim, 
    TeamEquipmentClaim, TeamPersonnelClaim, so on and so forth.