多态数据库设计:这种方法有名吗?

时间:2013-03-20 23:37:13

标签: sql-server-2008 database-design

我有一个基础enitiy(项目),它将托管大量不同属性的项目类型(> 200)。我想要一个干净的便携式快速解决方案,并想出了一个maby有一个我不知道的名字的想法。

这就是:

  • items-entity包含基类字段+子类字段的附加字段,但包含dummie-names,ItemID,ItemNo,ItemTypeID,int1,int2,dec1,dec2,dec3,str1,str2

  • 引用的itemtype-record包含类型名称和子enity(1:n):

  • itemtypefields [itemtypeid,name,type,realfield] 例如[53,MaxPressure,dec,dec3]

这是局限性:

  • 很难估计基类中的字段要求
  • 更难根据子类型添加域/检查约束
  • 需要应用层将标记的sql转换为真实的查询
  • 一次只能查询一种类型,因为共享属性可能被定义为不同的“真实字段”。

第3个子弹解释:

select ItemNo,_MaxPressure_ from items where ItemTypeID=10 and _MaxPressure_>42
should translate to:
select ItemNo,dec3 as MaxPressure from items where ItemType=10 and dec3>42

(不能用sp或udf做对 - 或者可能吗?)

但是好处:

  • 性能
  • 轻松进行CRUD操作
  • 更容易在应用程序级别进行排序/过滤。

现在 - 它有名字吗?

1 个答案:

答案 0 :(得分:8)

此反模式称为One True Lookup Table

在关系数据库中,每列需要定义为一种逻辑类型。我不是指一个像INT或VARCHAR这样的SQL数据类型,我的意思是该列中从开始到结束的所有内容都必须来自同一组值,并且您应该能够将一个值与另一个值区分开来。

您不能将鞋码,平均温度和每英寸线程放入给定表格的同一列中,仍然称之为关系。

基本上,您的数据库根本不是数据库 - 它将是电子表格

阅读C. J. Date的几乎所有书籍,例如SQL and Relational Theory,以便正确解释关系和类型。


重新评论:

  

在阅读有关初级书籍和嘲笑半结构化数据之前,再次阅读Q.

好的,我已经重新阅读了你的帖子。

One True Lookup Table的经典用法并非完全你在做什么,但你所做的与OTLT有着同样的问题。

假设您在ItemType 10的列dec3中存储了“MaxPressure”。假设有一组固定的MaxPressure值的有效选项,并且您希望将它们放在另一个查找表中,这样就不会可以输入无效的MaxPressure值。

现在:在dec3上声明一个引用MaxPressures查找表的外键约束。 你不能 - 问题是外键约束适用于所有行中的dec3列,而不仅仅是那些ItemType为10的行。

原因是您在一列中存储了多组值。任何其他类型的约束都会出现同样的问题 - 唯一约束,检查约束,甚至NOT NULL。并且您也不能为该列声明DEFAULT值,因为您可能对每个ItemType有一个不同的正确默认值(并且某些ItemTypes对该属性没有默认值)。

我之所以提到C. J.日期书是因为他为类型提供了一个清晰的定义:它是一个命名的有限集,在其上定义了相等操作。也就是说,您可以判断一行中的值“42”是否与另一行上的值“42”相同。在关系列中,必须为true,因为它们必须来自相同的原始值集。在您的表中,dec3在MaxPressure时可以具有值“42”,而在每英寸线程时可以具有“42”作为另一个ItemType。因此,它们不是相同的值“42”。如果你有一个独特的约束,这两个42不会被视为重复。如果你有一个外键,每个不同的42将引用不同的查找表等。

您所做的不是有效的关系数据库设计。

除非你理解这一点,否则不要指责我关于关系数据库设计的资源。