【问题标题】:Sql Table dynamic cell typSql Table动态单元格类型
【发布时间】:2012-02-27 20:01:58
【问题描述】:

假设我有一个Product 和一个ProductType 表。我想要一个可以存储每种产品类型的特殊列的表。特殊列(属性)可以是任何类型。

现在我们每个 ProductType 都有一个名为 Product_%ProductTypeId% 的表,这是我非常不喜欢的解决方案 - 有什么建议吗?

我的想法是有一张表ProductTypeColumns 和cols:

Id | ProductTypeId | ColumnName | Value  | ColumnType

我对此不满意的是我失去了类型安全性,Value 列将是一个字符串类型,这意味着我必须始终转换为和从。

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

【问题讨论】:

标签: sql sql-server dynamic sql-types


【解决方案1】:

这叫EAV
您可以在 SO 上找到有关 EAV 和 SQL Server 的一些问题:

这是一个很多不同的人会有不同意见的主题。
有人会说你应该坚持使用Product_%ProductTypeId% 表,有人会说你的ProductTypeColumns 表是更好的方法。

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

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

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

通常情况下,这取决于。

【讨论】:

  • 或组合 - 可能有一些更重要的属性是许多产品共有的(尺寸、颜色、价格等),这些属性可能在一个相关表中,其余的则在 EAV 中。跨度>
  • 我也担心进行查询会有多困难.. 查询通常会非常复杂,添加这个额外的层.. 可能有点矫枉过正
  • @Zapacila:一旦你习惯了它并没有那么复杂。关于查询,请务必查看他在上面的评论中链接的 this link from my answerAaron Bertrand's excellent article
【解决方案2】:

类别层次结构(又名“继承”、“子类型”、“子类”)怎么样?

仅当列预先确定时,我才会亲自使用名称/值对解决方案(在您的问题中描述)。

如果您事先知道所有列并且它们不太可能更改,那么实现类别层次结构while not without complications 将保持类型安全并更好地支持 DBMS 执行声明完整性(例如,您可以有一个产品-指定一个 UNIQUE、FOREIGN KEY 或 CHECK 约束)。

【讨论】:

  • 我希望你没有暗示你不能在 EAV 中使用类型安全。
  • @AaronBertrand 我的意思是您不能通过声明性完整性约束在 DBMS 级别强制执行类型安全。如果我错了,那么我不介意在这个话题上有所启发;)
  • 嗯,EAV 不一定是指SQL_VARIANT。如果您阅读了我的文章(上面链接),我将展示如何拥有不同数据类型的值,您不能只将随机字符串放在期望日期时间属性值的位置。检查约束也可以用于特定属性,例如CHECK (AttributeID = x AND ISDATE(y) = 1) OR (AttributeID <> x).
  • Partners_TypeId 有点像一个类别继承。我们只有一个常见的类型(字符串,int date time..)
猜你喜欢
  • 2019-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
相关资源
最近更新 更多