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

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

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

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

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

进一步讨论:

所以长话短说,我感谢诺埃尔肯尼迪建议一个类别表,但需要可能比这更大。我在下面用另一种方式来描述它,试图强调它的重要性。我可能需要一个视角修正来解决这个问题,或者我可能需要更深入地研究 EAV/CR。

我喜欢 EAV/CR 模式的积极回应。我的开发伙伴们都说了 Jeffrey Kemp 在下面提到的: “新的实体必须由专业人员建模和设计”(断章取义,请阅读他在下面的回复)。问题是:

  • 实体每周添加和删除属性 < br/> < em > (搜索关键字指定未来的属性)
  • 每周都会有新的实体到来(产品由零部件组装而成)
  • 旧的实体每周都会消失(存档的,不太流行的,季节性的)

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

  • 同类产品的部门/关键字搜索/比较图
  • 消费者产品结帐前配置

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

56809 次浏览

可以肯定地说,EAV/CR 数据库模型是不好的。

不,不是的。只是它们对关系数据库的使用效率低下。一个纯粹的键/值存储在这个模型中工作得很好。

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

使用 EAV。在你的情况下,它将是一个单一的额外的表。对属性名和属性值进行索引,大多数关系数据库会对属性名重复使用前缀压缩,这使得它非常快速和紧凑。

当您使用 EAV/CR 替换“实际”字段时,它会变得很丑陋。和每个工具一样,过度使用它是“坏”的,并给它一个坏的形象。

我能想到一些普遍的利弊,有些情况下一个比另一个好:

选择一:

  • 优点: 设计和开发简单应用程序的时间更少
  • 优点: 新的实体很容易添加(甚至可能 是否由使用者加入?)
  • 优点: “通用”接口组件
  • 缺点: 验证简单数据类型所需的复杂代码
  • 缺点: 简单的 SQL 要复杂得多 报告
  • 缺点: 复杂的报告几乎可以变成 不可能
  • 缺点: 大型数据集的性能较差

备选案文2,分别对每个实体进行建模:

  • 缺点: 需要更多的时间收集 规定及设计
  • 缺点: 必须对新实体进行建模,并且 由专业人士设计
  • 缺点: 每个 实体
  • 赞成: 数据类型约束和验证简单实现
  • 正方: SQL 易于编写,易于 理解和调试
  • 正方: 即使是最复杂的报告也相对简单
  • 优点: 大型数据集的最佳性能

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

  • 赞成/反对: 收集需求和设计需要比选项1更多的时间,但可能不如选项2 * 多
  • 缺点: 新的实体必须由专业人士建模和设计
  • 优点: 以后可以很容易地添加新属性
  • 缺点: 验证简单数据类型(用于自定义属性)所需的复杂代码
  • 缺点: 仍然需要自定义接口组件,但是可以为自定义属性使用通用接口组件
  • 缺点: 一旦报表中包含任何自定义属性,SQL 就会变得复杂
  • 缺点: 通常性能良好,除非您开始需要通过自定义属性进行搜索或报告

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

就个人而言,我倾向于选项2,并尽可能避免 EAV。然而,对于某些场景,用户需要 EAV 所带来的灵活性; 但这需要付出很大的代价。

我也在纠结这个问题。您可能有兴趣查看以下关于两个现有电子商务解决方案的讨论: Magento (EAV)和 Joomla (常规关系结构) : Https://forum.virtuemart.net/index.php?topic=58686.0

看起来,Magento 的 EAV 表演是一个真正的精彩表演。

这就是为什么我倾向于一个正常的结构。为了克服缺乏灵活性的问题,我正在考虑在未来添加一些可以编辑的单独数据字典(XML 或单独的 DB 表) ,在此基础上,将生成用于显示和比较带有新属性集的产品类别的应用程序代码,以及 SQL 脚本。

在这种情况下,这样的体系结构似乎是最佳点——同时具有灵活性和性能。

这个问题可能是在实时环境中频繁使用 ALTERTABLE 造成的。我正在使用 Postgres,所以它的 MVCC 和事务性 DDL 有望缓解疼痛。

我仍然支持在 EAV 的最低原子级别建模。让面向特定用户群体的标准、技术和应用程序来决定内容模型、属性的重复需求、粒度等。

// 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'

精确地址信息为一个订单,懒惰

--

摘要: 只有在以下情况下才使用 Magento:

  1. 你会得到一大袋钱
  2. 你必须这么做
  3. 享受痛苦吧

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

我从来没有在生产环境中实践过 NoSQL (只是测试了 MongoDB,并且印象深刻) ,但是 NoSQL 的全部意义在于能够在同一个“文档”中保存具有不同属性的项目。

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

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

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

所有的模型都会随着时间的推移而变化,以反映新的业务需求。就这样。使用 EAV 只是我们方框中可以使用的工具之一,但它绝不应该被自动归类为“坏”。

如果只是关于产品目录属性,因此这些属性的验证需求相当有限,EAV 的唯一真正缺点是查询性能,即使这只是一个问题,当您的查询处理多个“事物”(产品)的属性,查询的性能“给我所有的产品的属性与 id 234”,而不是最优的仍然很快。

一种解决方案是只对产品目录的管理/编辑部分使用 SQL 数据库/EAV 模型,并使用一些过程将产品反规范化为可搜索的内容。因为您已经有了属性,所以很有可能需要分面,所以可以使用 Solr 或 ElasticSearch。这种方法基本上避免了 EAV 模型的所有缺点,并且增加的复杂性仅限于在更新时将完整的产品序列化为 JSON。

交通意外伤亡援助计划有很多缺点:

  1. 随着时间的推移性能下降 一旦应用程序中的数据量增长到超过一定的大小,对该数据的检索和操作可能会变得越来越低效。
  2. SQL 查询非常复杂,难以编写。
  3. 数据完整性问题。 不能为所有需要的字段定义外键。
  4. 您必须定义和维护自己的元数据。

我有一个稍微不同的问题: 与许多具有稀疏值的属性(这可能是使用 EAV 的一个很好的理由)不同,我希望存储更像电子表格的东西。工作表中的列可以更改,但是在工作表中,所有单元格都将包含数据(不是稀疏的)。

我做了一个 一套小测试基准两个设计: 一个使用 EAV,另一个使用 Postgres ARRAY 存储细胞数据。

EAV enter image description here

数组 enter image description here

两个架构在适当的列上都有索引,而索引由规划者使用。

它生成了用于插入和查询的 基于数组的模式数量级更快。从快速测试来看,两者似乎都呈线性伸缩。不过检查不是很彻底。建议和叉子欢迎-他们在麻省理工学院执照。