我应该使用EAV模型吗?

时间:2010-11-01 03:21:08

标签: php database-design magento entity-attribute-value doctrine-orm

我正在为电子商务应用程序设计我的数据库/域名,而我很难搞清楚如何存储产品。

该网站将出售各种产品,钢笔,丁字裤,纹身,雨伞,应有尽有。这些产品中的每一个都会分享一些常见的属性,高度,宽度,长度,重量等,但有些产品有特殊数据。例如,笔具有不同的墨水颜色,并且提示/盖子和小册子可以具有不同类型的折叠。到目前为止,我已经考虑了20多个额外属性,但这些属性可能仅适用于网站上1%的产品。

所以我想知道是否适合实施EAV模型来处理额外的数据。请记住,当客户在前端查看网站时,会有一个过滤侧边栏,如eBay和carsales.com.au。 (所以请记住会有相当多的查询)

我认为实现类表继承是不切实际的,因为系统需要保持灵活性。这是因为,沿着轨道,我们将来可能会有更多属性的新属性。

我考虑的另一件事是使用NoSQL数据库(可能是MongoDB)但是我对这些类型的数据库没什么经验,它甚至可以解决我的问题吗?

审查选项:

  1. 包含大量列的单个产品实体
  2. 单独的属性实体(EAV)
  3. 切换到无架构持久性
  4. 我正在使用属性实体构建原型,以查看它的灵活性,测试性能以及查询失控的程度。

    编辑:我当然对任何其他解决方案持开放态度。

3 个答案:

答案 0 :(得分:67)

很好的问题,但当然,没有“一个真正的方式”。根据@BenV,Magento确实使用了EAV模型。我对它的体验非常积极,但它确实绊倒了其他用户。一些注意事项:

<强> 1。性能 EAV需要复杂的多表连接,以使用相关属性填充对象。这确实会带来性能损失。但是,可以通过仔细缓存(在堆栈的所有级别,包括查询缓存)和选择性使用非规范化来缓解这种情况。 Magento允许管理员为SKU数量保证的类别和产品选择非规范化模型(通常为数千)。这反过来要求Observers触发重新索引(总是好!),并在产品数据更改时更新“平面”非规范化表。也可以通过向管理员发出提示来安排或手动触发。

<强> 2。第三方用户复杂性 如果您计划将此应用程序提供给其他用户,很多人会发现EAV过于复杂,您最终会在用户论坛上处理很多咩咩叫和无知的滥用行为(参考Magento !!)。

第3。未来的可扩展性和插件架构。 毫无疑问,当可扩展性是一个因素时,EAV模型真正进入了自己的模型。将新属性添加到模型中非常简单,同时最大限度地降低破坏现有ORM和控制器代码的风险。

<强> 4。数据类型的更改 EAV确实使得更改属性数据类型变得有点困难。如果您的初始设计要求将来更改的特定属性数据类型(例如intvarchar),则意味着您必须将该属性的所有记录迁移到与之匹配的相应表中新的数据类型。当然,纯粹主义者会建议你第一次获得正确的设计,但现实有时会侵入!

<强> 5。手动产品导入 EAV几乎不可能做的一件事是使用SQL和/或phpMyAdmin样式的CSV / XML将产品(或其他实体)导入数据库。您需要编写一个Importer模块,该模块接受结构化数据并将其传递到应用程序的Model层以将其持久保存到数据库中。这确实增加了你的复杂性。

答案 1 :(得分:0)

开源购物车Magento允许使用EAV设计为其产品定制属性。您可以查看他们的数据库架构here

答案 2 :(得分:0)

我建议你仔细研究Doctrine 2 ORM和OXM插件(https://github.com/doctrine/oxm)。它将使用不同的属性解决您的问题。当然,您将需要为可搜索的自定义属性构建索引,但我认为这不会是一个问题:)

如果您不关心社区成员的数量,那么您也可以使用MongoDB。