2012-02-27 46 views
0

比方说,我有一个ProductProductType表。我想要一个表格,可以为每种产品类型存储特殊列。特殊列(属性)可以是任何类型。Sql Table dynamic cell typ

现在我们有一个表,每ProductTypeProduct_%ProductTypeId%这是我真的不喜欢的解决方案 - 有什么建议吗?

我的想法是有一个表ProductTypeColumns用的cols:

Id | ProductTypeId | ColumnName | Value | ColumnType 

什么,我不喜欢这个就是我失去的类型安全,列Value将是一个字符串类型,这意味着我必须始终转换为和从。

此表格将用于生成报告..具有“动态”列可能是一个问题。

+1

EAV通常是这样做的一种方式,特别是如果这些属性对于很多产品可能会有所不同,并且它们可以频繁地添加到新产品中。我在这里发布了关于EAV的博客:http://sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/what-is-so-bad-about-eav-anyway.aspx – 2012-02-27 20:06:35

回答

1

这就是所谓的EAV
您可以找到有关EAV和SQL Server的一些问题在这里SO:

这是一个主题,其中很多不同的人会有不同的看法。
有人会说,你应该Product_%ProductTypeId%表贴,有的会说,你ProductTypeColumns表是更好的办法。

基本上,我在ProductTypeColumns阵营。
我们在工作中也使用类似的东西:
我们的表格包含订单商品的属性(超过一百万个订单商品和超过2.5亿个属性),我们现在使用它近十年。
缺点:无类型安全(因为你已经提到)和querying can be a bit complicated

但对于我们来说,这是唯一可能的方式,因为我们拥有超过1000个属性,超过100个产品,每个产品可以具有100到300个属性。像这样的维度,属性表是唯一可行的方法。
但它可能不是每个人的最佳解决方案,我不知道它是否是最适合您的解决方案。

如果您的产品数量和特殊属性不是那么大,也许您可​​以跳过您的第一个建议(Product_%ProductTypeId%表)。
这肯定会更容易查询,但如果产品和属性的可能组合太多,也许这不是一个选项。

通常情况下,这取决于。

+0

或者组合 - 可能有一些更重要的属性是许多产品(尺寸,颜色,价格等),可以在一个相关的表中,其余的在EAV中。 – HLGEM 2012-02-27 22:26:12

+0

我也担心会有多难查询..查询将是非常复杂的正常情况下,增加这个额外的层..可能是矫枉过正 – Zapacila 2012-02-28 09:33:27

+0

@Zapacila:只要你习惯了它并不复杂。关于查询,请务必查看[我的答案中的此链接](http://stackoverflow.com/a/231681/6884)和[Aaron Bertrand的优秀文章](http://sqlblog.com/blogs/aaron_bertrand/ archive/2009/11/19/what-is-so-bad-about-eav-anyway.aspx),他在上面的评论中将其链接起来。 – 2012-02-28 10:19:53

1

类别层次结构(又名“继承”,“子类型”,“子类”)如何?

enter image description here

我会亲自去同一个名称/值对溶液(在你的问题中所述)只有在列预先确定的。

如果您事先知道所有列并且它们不太可能发生变化,那么实施类别层次结构while not without complications将保持类型安全性,并更好地实现DBMS声明性完整性(例如,您可以具有特定产品一个唯一的,FOREIGN KEY或CHECK约束)。

+0

我希望你不是暗示EAV中不能有安全类型。 – 2012-02-27 20:57:07

+0

@AaronBertrand我暗示你不能通过声明性完整性约束在DBMS级别强制执行类型安全。如果我错了,那么我不会介意在这个话题上受到启发;) – 2012-02-27 21:14:11

+1

那么,EAV并不一定意味着'SQL_VARIANT'。如果您阅读了我的文章(链接上面),我将展示如何获取不同数据类型的值,您可以在其中放置随机字符串,并在其中预期日期时间属性值。检查约束也可能用于特定属性,例如'CHECK(AttributeID = x AND ISDATE(y)= 1)或(AttributeID <> x)'。 – 2012-02-27 21:33:26