Database design 如何为多种产品设计产品表,其中每种产品都有许多参数

Database design 如何为多种产品设计产品表,其中每种产品都有许多参数,database-design,relational-database,database-schema,Database Design,Relational Database,Database Schema,我在桌子设计方面没有太多经验。我的目标是创建一个或多个满足以下要求的产品表: 支持多种产品(电视、手机、PC等)。每种产品都有一组不同的参数,如: 手机将有颜色,大小,重量,操作系统 电脑将有CPU,硬盘,RAM 参数集必须是动态的。您可以添加或编辑任何喜欢的参数 如果没有针对每种产品的单独表格,如何满足这些要求?您可以有一个产品表格和一个单独的ProductAdditionInfo表格,其中包含3列:产品ID、附加信息名称、附加信息值。如果许多但不是所有种类的产品都使用颜色,则可以在产

我在桌子设计方面没有太多经验。我的目标是创建一个或多个满足以下要求的产品表:

  • 支持多种产品(电视、手机、PC等)。每种产品都有一组不同的参数,如:

    • 手机将有颜色,大小,重量,操作系统

    • 电脑将有CPU,硬盘,RAM

  • 参数集必须是动态的。您可以添加或编辑任何喜欢的参数


如果没有针对每种产品的单独表格,如何满足这些要求?

您可以有一个产品表格和一个单独的ProductAdditionInfo表格,其中包含3列:产品ID、附加信息名称、附加信息值。如果许多但不是所有种类的产品都使用颜色,则可以在产品表中将其设置为可为空的列,或者将其放在ProductAdditionalInfo中

这种方法不是关系数据库的传统技术,但我已经看到它在实践中被大量使用。它可以是灵活的,并具有良好的性能


史蒂夫·耶格(Steve Yegge)称之为此,并写了一篇关于使用它的长文章

您至少有以下五个选项用于对所描述的类型层次结构建模:

  • :一个用于所有产品类型的表,具有足够的列来存储所有类型的所有属性。这意味着有很多列,其中大多数在任何给定行上都是空的

  • :一个产品表,存储所有产品类型的通用属性。然后,每个产品类型一个表,存储特定于该产品类型的属性

  • :没有常用产品属性的表。相反,每个产品类型一个表,存储通用产品属性和产品特定属性

  • :一个产品表,存储所有产品类型的通用属性。一个额外的列存储XML、YAML、JSON或其他格式的半结构化数据块。此BLOB允许您存储特定于每种产品类型的属性。您可以使用奇特的设计模式来描述这一点,例如正面和纪念品。但不管怎样,你有一大堆属性,在SQL中很难查询;您必须将整个blob提取回应用程序并在那里进行排序

  • :一个表用于产品,另一个表用于将属性透视到行而不是列。就关系范式而言,EAV不是一种有效的设计,但许多人还是使用它。这就是另一个答案提到的“属性模式”。有关一些陷阱,请参阅关于StackOverflow的其他问题

我在一次演讲中写了更多关于这方面的内容


关于EAV的其他想法:虽然许多人似乎喜欢EAV,但我不喜欢。这似乎是最灵活的解决方案,因此也是最好的。然而,记住这句格言。以下是EAV的一些缺点:

  • 无法强制设置列(相当于
    非NULL
  • 无法使用SQL数据类型验证条目
  • 无法确保属性名称的拼写一致
  • 无法在任何给定属性的值上放置外键,例如查找表
  • 在传统的表格布局中获取结果既复杂又昂贵,因为要从多行获取属性,需要对每个属性执行
    JOIN
EAV给您带来的灵活性要求您在其他方面做出牺牲,这可能会使您的代码比以更传统的方式解决原始问题更复杂(或更糟糕)

在大多数情况下,没有必要有那么大的灵活性。在OP关于产品类型的问题中,为每个产品类型为特定于产品的属性创建一个表要简单得多,因此您至少可以为相同产品类型的条目执行一些一致的结构

只有当必须允许每一行都有一组不同的属性时,我才会使用EAV。当您有一组有限的产品类型时,EAV是一种过度杀伤力。类表继承将是我的首选


2019年更新:我越是看到人们使用JSON作为“许多自定义属性”问题的解决方案,我就越不喜欢这个解决方案。这使得查询变得过于复杂,即使使用特殊语言来支持查询也是如此。与普通的行和列存储相比,存储JSON文档需要更多的存储空间

基本上,在关系数据库中,这些解决方案都不是简单有效的。拥有“可变属性”的整个想法从根本上与关系理论相悖


归根结底,你必须选择一个对你的应用最不坏的解决方案。因此,在选择数据库设计之前,您需要知道如何查询数据。没有办法选择一个“最佳”的解决方案,因为任何解决方案都可能最适合给定的应用程序。

如果我使用
类表继承
意味着:

一个产品表,存储所有产品类型的通用属性。然后,每个产品类型一个表,存储特定于该产品类型的属性。 -比尔·卡温

我最喜欢Bill Karwin的建议。。我可以预见一个缺点,我将尝试解释如何避免成为问题

当一个属性仅对1种类型通用,然后对2种类型通用,然后对3种类型通用时,我应该制定什么应急计划?

例如:(这只是一个例子,不是我真正的问题)

如果我们出售家具,我们可能会出售椅子、灯具、沙发、电视等。电视可能是我们携带的唯一一种耗电类型。因此,我将把
功耗
属性放在
tv\u type\u表上
。然后我们就开始带回家了