实体属性值数据库与严格关系模型电子商务

Zac*_*ott 133 sql database design-patterns key-value entity-attribute-value

可以肯定地说,EAV/CR数据库模型很糟糕.那说,

问题:应该使用什么数据库模型,技术或模式来处理描述可以在运行时更改的电子商务产品的属性的"类"?

在一个好的电子商务数据库中,您将存储选项类别(如电视分辨率,然后为每个电视分辨率,但下一个产品可能不是电视,没有"电视分辨率").如何存储它们,有效搜索,并允许用户使用描述其产品的可变字段设置产品类型?如果搜索引擎发现客户通常根据控制台深度搜索电视,则可以向字段添加控制台深度,然后在运行时为每种电视产品类型添加单个深度.

良好的电子商务应用程序中有一个很好的共同特征,它们显示一组产品,然后"向下钻取"侧面菜单,您可以看到"电视分辨率"作为标题,以及前五个最常见的电视分辨率发现集.您单击一个,它只显示该分辨率的电视,允许您通过选择侧面菜单上的其他类别进一步向下钻取.这些选项是运行时添加的动态产品属性.

进一步讨论:

长话短说,互联网上是否有任何链接或模型描述可以"学术上"修复以下设置? 我感谢Noel Kennedy建议的类别表,但需要的可能还要大于此.我在下面用不同的方式描述它,试图强调其意义.我可能需要进行视点校正来解决问题,或者我可能需要深入了解EAV/CR.

喜欢对EAV/CR模型的积极响应.我的开发人员都说杰弗里·肯普在下面提到了什么:"新实体必须由专业人士建模和设计"(脱离背景,阅读下面的回复).问题是:

  • 实体每周添加和删除属性
    (搜索关键字决定未来属性)
  • 新实体每周到达
    (产品由零件组装)
  • 旧实体每周都会消失
    (存档,不太受欢迎,季节性)

客户希望为产品添加属性有两个原因:

  • 相似产品之间的部门/关键字搜索/比较图表
  • 结账前的消费品配置

属性必须具有重要性,而不仅仅是关键字搜索.如果他们想要比较所有有"奶油糖霜"的蛋糕,他们可以点击蛋糕,点击生日主题,点击生奶油糖霜,然后检查所有有趣的蛋糕,知道他们都有奶油糖霜.这不仅仅是蛋糕,只是一个例子.

Jef*_*emp 74

我可以想到一些一般的利弊,有些情况下一个比另一个好:

选项1,EAV模型:

  • 专业:设计和开发简单应用程序的时间较少
  • Pro:易于添加的新实体(甚至可能被用户添加?)
  • Pro:"通用"界面组件
  • Con:验证简单数据类型所需的复杂代码
  • Con:简单报告的SQL更复杂
  • 骗局:复杂的报道几乎不可能
  • Con:大型数据集的性能不佳

选项2,分别为每个实体建模:

  • Con:收集需求和设计需要更多时间
  • Con:新实体必须由专业人员建模和设计
  • Con:每个实体的自定义界面组件
  • Pro:数据类型约束和验证易于实现
  • Pro:SQL易于编写,易于理解和调试
  • 亲:即使是最复杂的报道也相对简单
  • Pro:大数据集的最佳性能

选项3,组合(模型实体"正确",但为某些/所有实体的自定义属性添加"扩展")

  • Pro/Con:收集要求和设计所需的时间比选项1要多,但可能没有选项2*那么多
  • Con:新实体必须由专业人员建模和设计
  • Pro:以后可能很容易添加新属性
  • Con:验证简单数据类型所需的复杂代码(用于自定义属性)
  • Con:仍然需要自定义界面组件,但自定义属性可以使用通用界面组件
  • Con:只要报表中包含任何自定义属性,SQL就会变得复杂
  • Con:通常表现良好,除非您开始需要按自定义属性进行搜索或报告

*我不确定选项3是否必然会在设计阶段节省任何时间.

我个人倾向于选项2,尽可能避免使用EAV.但是,对于某些情况,用户需要EAV附带的灵活性; 但这需要很高的成本.

  • +10000 很好的答案。如今,人们在数据库设计和需求收集方面变得吝啬。他们宁愿多写一百倍的代码,这样才能做出好的设计。 (2认同)

Jav*_*ier 62

可以肯定地说,EAV/CR数据库模型很糟糕.

不,这不对.只是它们对关系数据库的使用效率低下.纯粹的键/值存储可以很好地使用这个模型.

现在,问你真正的问题:如何存储各种属性并让它们可搜索?

只需使用EAV.在你的情况下,它将是一个额外的表.在属性名称和值上对其进行索引,大多数RDBM将对属性名称重复使用前缀压缩,使其非常快速和紧凑.

当你用它来代替'真实'字段时,EAV/CR变得丑陋.与每个工具一样,过度使用它是"坏"的,并给它一个糟糕的图像.

  • 非常务实的答案! (3认同)
  • 如果已经定义了这些"附加字段",那么它绝对最好是"真实字段".当然,在大型查询中进行未绑定数量的连接将是一个沉重的代价(但可能仍然可以!).我在一个元数据繁重的项目上做的是每个"主项目"允许任意数量的"标签"(作为EAV记录),但"大型查询"只选择一些预定义的标记名,保持连接总数有限(目前通常只有4个标签和大约5个其他连接),当用户选择特定项目时,_then_它会获取所有相关内容,但是对于单个项目. (2认同)

Vee*_*Vee 15

// At this point, I'd like to take a moment to speak to you about the Magento/Adobe PSD format.
// Magento/PSD is not a good ecommerce platform/format. Magento/PSD is not even a bad ecommerce platform/format. Calling it such would be an
// insult to other bad ecommerce platform/formats, such as Zencart or OsCommerce. No, Magento/PSD is an abysmal ecommerce platform/format. Having
// worked on this code for several weeks now, my hate for Magento/PSD has grown to a raging fire
// that burns with the fierce passion of a million suns.

http://code.google.com/p/xee/source/browse/trunk/XeePhotoshopLoader.m?spec=svn28&r=11#107

内部模型充其量是古怪的,就像有人将模式放入一个沼泽游戏中,将其密封并将其放入油漆瓶中...

现实世界:我正在开发一个中间件实现应用程序,这里有一个获取地址信息的查询.

CREATE OR REPLACE VIEW sales_flat_addresses AS
SELECT sales_order_entity.parent_id AS order_id, 
       sales_order_entity.entity_id, 
       CONCAT(CONCAT(UCASE(MID(sales_order_entity_varchar.value,1,1)),MID(sales_order_entity_varchar.value,2)), "Address") as type, 
       GROUP_CONCAT( 
         CONCAT( eav_attribute.attribute_code," ::::: ", sales_order_entity_varchar.value )
         ORDER BY sales_order_entity_varchar.value DESC
         SEPARATOR '!!!!!' 
       ) as data
  FROM sales_order_entity
       INNER JOIN sales_order_entity_varchar ON sales_order_entity_varchar.entity_id = sales_order_entity.entity_id
       INNER JOIN eav_attribute ON eav_attribute.attribute_id = sales_order_entity_varchar.attribute_id
   AND sales_order_entity.entity_type_id =12
 GROUP BY sales_order_entity.entity_id
 ORDER BY eav_attribute.attribute_code = 'address_type'
Run Code Online (Sandbox Code Playgroud)

懒惰地确定订单的地址信息

-

摘要:仅在以下情况下使用Magento:

  1. 你得到了大笔钱
  2. 你必须
  3. 享受痛苦


Luc*_*s T 15

我很惊讶没人提到NoSQL数据库.

我从来没有在生产环境中练习NoSQL(只测试了MongoDB并且给人留下了深刻的印象)但NoSQL的重点在于能够在同一个"文档"中保存具有不同属性的项目.


小智 11

在性能不是主要要求的情况下,如在ETL类型的应用中,EAV具有另一个明显的优势:差异节省.

我已经实现了许多应用程序,其中一个主要的要求是能够查看域对象从其第一个"版本"到其当前状态的历史记录.如果该域对象具有大量属性,则意味着每次更改都需要在其对应的表中插入新行(不是更新,因为历史记录将丢失,而是插入).假设这个域对象是一个Person,我有500k人跟踪人员生命周期平均100多个变化到各种属性.再加上罕见的是只有一个主要域对象的应用程序,你很快就会猜测数据库的大小会很快失控.

一个简单的解决方案是仅保存主要域对象的差异更改,而不是重复保存冗余信息.

所有模型都会随着时间而变化,以反映新的业务需 期.使用EAV只是我们使用盒子中的工具之一; 但它永远不应被自动归类为"坏".

  • +1表示“使用EAV只是我们工具箱中要使用的工具之一;但永远不要将其自动归类为“不良”。 (2认同)