我应该使用EAV模型吗?

Cob*_*bby 30 php database-design magento entity-attribute-value doctrine-orm

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

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

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

我认为实现类表继承是不切实际的,因为系统需要保持灵活性.这是因为,在未来的轨道上,我们可能会在未来使用新类型的产品时拥有更多属性.

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

审查选项:

  1. 单个产品实体,包含大量列
  2. 单独的属性实体(EAV)
  3. 切换到无模式持久性

我正在构建一个带有属性实体的原型,以查看它的灵活性,测试性能以及查询失控的方式.

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

Jon*_*Day 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层,以将其持久保存到数据库中.这确实增加了你的复杂性.

  • @Cobby Jonathan关于缓存的观点.如何为过滤器生成总计?如何为大量客户有效地提供页面?如果你坚持自己建立这个,至少帮自己一个忙,并审查Magento为他们的EAV系统做出的改变以允许扩展. (2认同)
  • EAV模型的一个优点是通常可以在不更改数据库模式的情况下实现对模式的更改.这很重要,因为在MySQL ALTER TABLE语句中锁定表以防止在架构更改期间进行所有读写操作.因此,如果您需要更改大型表上的架构,这可能会导致锁定问题以及ALTER TABLE运行时可能发生的中断.(想想电子商务网站上非常大和关键的表格,例如客户或产品). (2认同)