我应该使用EAV模型吗?

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

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

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

由于系统需要保持灵活性,我认为实现Class Tableinheritance并不现实。 这是因为,沿着轨道,我们可能在将来有更多的属性,新的产品types。

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

审查选项:

  1. 具有许多列的单一产品实体
  2. 独立属性实体(EAV)
  3. 切换到无模式持久性

我正在构build一个具有属性实体的原型,以查看它是多么的灵活,并且testing性能以及查询如何失控。

编辑:当然,我打开任何其他的解决scheme。

伟大的问题,但当然,没有“一个真正的方法”。 根据@BenV,Magento确实使用了EAV模型。 我的经验是非常积极的,但它确实让其他用户感到恐慌。 一些考虑:

1.性能。 EAV需要复杂的多表连接才能使用相关属性填充对象。 这确实会导致性能下降。 但是,可以通过小心的caching(通过堆栈的各个层次,包括查询caching)和非规范化的select性使用来缓解这个问题。 Magento的确允许pipe理员为类别和产品select一个非规范化的模型,其中SKU的数量保证(通常为数千)。 这又要求观察者触发重新索引(总是好的),并在产品数据改变时更新到“平坦”非规格化表。 这也可以通过提示给pipe理员来安排或手动触发。

2.第三方用户的复杂性如果你打算把这个应用程序提供给其他用户,许多人会发现EAV太复杂,你最终会在用户论坛上处理大量喋喋不休的问题(参考Magento !!) 。

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

4.数据types EAV中的更改确实使得更改属性数据types有点困难。 如果您的初始devise需要将来更改的特定属性数据types(例如int to varchar ),则意味着您必须将该属性的所有logging迁移到与新数据types匹配的对应表。 当然,纯粹主义者会build议你第一次得到devise,但是有时候现实会侵入!

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

开源购物车Magento允许使用EAVdevise的产品的自定义属性。 你可以在这里查看他们的数据库模式。

我build议你仔细看看Doctrine 2 ORM和OXM插件(https://github.com/doctrine/oxm)。; 它将解决你的问题与不同的属性。 当然,你将被要求build立可search的自定义属性的索引,但我不认为这会是一个问题:)

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