【问题标题】:Entity-Attribute-Value Table Design实体-属性-值表设计
【发布时间】:2012-07-31 12:43:13
【问题描述】:

我目前正在为电子商务平台的产品部分设计数据库结构。它需要以这样一种方式设计,即可以销售具有无限数量不同属性的无限数量的不同类型的产品。

例如笔记本电脑的属性可以是 RAM、屏幕尺寸、重量等。一本书的属性可以是 Author、ISBN、Publisher 等。

似乎 EAV 结构最合适。

  • 选择产品
  • 产品属于属性集
  • 属性集包含属性 x 和 y
    • 属性 x 是数据类型日期时间(值存储在属性值日期时间中)
    • 属性 y 是 int 数据类型(值存储在 attribute_values_int 中)
  • 每个属性定义都表示类型(即 x 具有列类型 -> 日期类型)

假设上述情况,我是否可以将选择加入attribute_values_datetime 表以获取正确的数据,而无需获取结果集并在该表已知的情况下构建第二个查询?构建这种类型的查询是否会对性能造成很大影响,或者下面的查询是否更合适(尽管功能较少)

  • 选择产品
  • 产品属于属性集
  • 属性集包含属性 x 和 y
    • 属性 x 是数据类型日期时间,但在属性值中存储为 TEXT
    • 属性 y 是数据类型 int,但在属性值中存储为 TEXT

【问题讨论】:

  • 不要使用 EAV。不要介意性能问题(只会不断增长的海量表),请考虑如何查询它。在大多数情况下,EAV 是过度标准化。
  • 我倾向于同意@Oded,您最终会在数据库中构建数据库。我想知道大型在线零售商采取什么方法(好的方法)。
  • 将数据库用作数据库...为您最终拥有的实际产品类型创建表。我会反对不合理的要求——“无数种不同类型的产品具有无数种不同的属性”对我来说当然听起来不合理。从您的业务中获取一些估计限制。
  • @Oded:EAV 与规范化无关。没有任何分解规则说:“将属性的名称作为数据存储在表中的一行中,并将其值(无论数据类型如何,作为 varchar(n) 存储在同一行中)”。不过,它可能是过于抽象了。
  • @Oded,没有人可以遵循规范化规则,无论是否落水,并到达 EAV。只有当他们根本不了解标准化意味着什么时,他们才能达到 EAV。存储 EAV 数据的物理表和它试图建模的虚拟表都不是关系。如果表格不是关系,则不能以任何正常形式放置表格。这是一个先决条件,好像有一个“第 0 范式”。

标签: mysql sql database-design database-schema entity-attribute-value


【解决方案1】:

我不知道这应该是评论还是答案。尽管如此,我还是走了。

我不知道你在做什么。但是你看过Magento EAV database structure吗?是的,它可能很慢,查询可能很大,但对我们来说,优点多于缺点。另一方面,magento 负责查询。

我们正在将我们的在线商店(大中型商店)迁移到使用 Magento,目前我们对 EAV 方法非常满意。

【讨论】:

    【解决方案2】:

    是的,在为 EAV 模型组装查询时通常会有很大的损失。检查数据的自我一致性会带来更大的性能损失,因为 DBMS 无法为您做这件事。如果出现问题,DBMS 无法告诉您。

    采用更正统的数据库设计,正如 cmets 中 Oded 所推荐的那样,DBMS 可确保数据库中的数据更加接近一致。我强烈建议使用常规(非 EAV)设计。

    【讨论】:

      【解决方案3】:

      我将在这个问题上与大多数 cmets 提出相反的意见。虽然EAV 是邪恶的,您可以在 SO 和 DBA.SE 和其他地方找到多次详细解释的所有原因,但有一个真正常见的应用程序,其中大多数错误EAV 在很大程度上是无关紧要的,EAV 的(少数)优势非常密切相关。该应用程序是在线产品目录。

      EAV 的主要问题是它不会让数据库做它真正擅长的事情,这有助于通过将不同实体的信息的不同属性安排在 模式中来为它们提供适当的上下文。拥有架构可以在访问、解释和强制执行数据完整性方面带来许多优势。

      关于产品目录的事实是,产品的属性几乎完全与目录系统无关。产品目录系统(最多)对产品属性做三件事。

      1. 以列表形式向最终用户显示产品属性:{attribute name}: {attribute value}。

      2. 在比较网格中显示多个产品的属性,其中不同产品的属性相互排列(产品通常是列,属性通常是行)

      3. 根据特定的属性/值组合为某事制定规则(例如定价)。

      如果您的系统所做的只是反刍与语义无关的信息(与系统无关),那么该信息的架构基本上是无用的。事实上,模式阻碍了在线产品目录,尤其是当您的目录包含许多不同类型的产品时,因为您总是不得不返回模式来修改它以允许用于新的产品类别或属性类型。

      由于它的使用方式,即使是产品目录中属性值的数据类型也不一定(至关重要)重要。对于某些属性,您可能需要施加约束,例如“必须是数字”或“必须来自此列表 {...}”。这取决于属性一致性对您的目录的重要性以及您希望实现的详细程度。看看几家在线零售商的产品目录,我想说大多数人都准备好以简单性换取一致性。

      是的,EAV 是邪恶的,除非它不是。

      【讨论】:

      • 1) 使用eav,如果我们使用eav,我们可以采取什么措施来防止性能问题,如果我们有成千上万的产品,肯定是performance problems will happen
      • @PhpBeginner 为什么你说使用 EAV 作为产品目录的性能问题是不可避免的?我不认为这是一个公平的评论。请具体说明什么会表现更差?这种概括正是我在这个答案中所说的。对于大多数应用程序来说,EAV 邪恶的。在线产品目录不是其中之一。在这种特定情况下,您不能说“EAV 很慢”,或“EAV 使您的查询变得复杂”,或“EAV 从数据中删除了意义”或任何其他通常对 EAV 有效的批评。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-20
      • 2011-02-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多