我应该使用EAV数据库设计模型还是许多表?

4
我新建了一个应用程序,现在我正在考虑两种路径,不知道哪种是继续的好方法。
我正在构建类似电子商务网站的东西,其中包含类别和子类别。
问题在于,网站上有不同类型的产品,每种产品都有不同的属性,并且网站必须可以通过这些产品属性进行过滤。
这是我的初始数据库设计:
Products{ProductId, Name, ProductCategoryId}
ProductCategories{ProductCategoryId, Name, ParentId}
CategoryProperties{CategoryPropertyId, ProductCategoryId, Name}
ProductPropertyValues{ProductId, CategoryPropertyId, Value}

现在经过一些分析,我发现这个设计实际上是EAV模型,我读到人们通常不推荐这种设计。
似乎需要为所有事情都使用动态SQL查询。

这是一种方法,我正在考虑它。
另一种方式可能被称为“LOT WORK WAY”,但如果更好的话,我想去那里。 制作表格
Product{ProductId, CategoryId, Name, ManufacturerId}

并且可以在数据库中实现表继承,这意味着可以创建类似以下的表:

Cpus{ProductId ....}
HardDisks{ProductId ....}
MotherBoards{ProductId ....}
erc. for each product (1 to 1 relation).

我知道这将是一个非常大的数据库和非常大的应用程序领域,但它是否比使用EAV设计的选项一更好、更容易且性能更好。


1
我不同意你的初始设计是EAV。 - Walter Mitty
那个ProductPropertyValues表不是EAV吗?得了吧。 - Erwin Smout
为什么你认为它不是呢? - 1110
EAV是一种反模式。如果可以的话,请避免使用它。 - Neil McGuigan
@NeilMcGuigan,你认为我的另一个选项“每个产品一张表”是更好的选择? - 1110
1
是的。您还可以考虑使用带有 SQLXML 函数的 XML 列来处理一些列,这些列可能只需要搜索,但不需要计数或排序。 - Neil McGuigan
3个回答

5
EAV 很少是一种胜利的方案。在您的情况下,我能看到 EAV 的吸引力,因为不同类别将拥有不同的属性,否则很难进行管理。然而,假设有人想要搜索“所有使用 SATA 接口、以 10k rpm 旋转的硬盘中超过 3 个盘片的硬盘?”您在 EAV 中的查询将会很痛苦。如果您希望支持这样的查询,那么 EAV 就不合适了。
然而,还有其他方法。您可以考虑使用扩展数据的 XML 字段,或者如果您使用的是 PostgreSQL 9.2,则可以使用 JSON 字段(但 XML 更易于搜索)。这将为您提供更广泛的可能性搜索,而无需 EAV 带来的麻烦。但是,代价是模式执行将更加困难。

是的,那正是让我不得不提出这个问题的问题。我已经建立了EAV结构,并且按不同类别过滤产品迫使我使用动态SQL和很多痛苦。所以我开始重新构建数据库到更小的表格,现在我对我的40个继承产品表感到舒适。但仍在分析问题... - 1110

4

这个问题似乎更详细地讨论了这个问题。

除了在那里讨论的性能、可扩展性和复杂性之外,还要考虑以下因素:

  • SQL数据库(如SQL Server)具有全文搜索功能;因此,如果您只有一个描述产品的字段-全文搜索将对其进行索引,并能够提供高级语义搜索

  • 看看现在非常流行的无SQL系统;它们的可扩展性应该很好,并且它们支持非结构化数据,例如您拥有的数据。Hadoop和Casandra是很好的起点。


非关系型数据库不是我在这个项目中感兴趣的,所以我不能考虑它们。通过“...描述产品的单个字段...”,您是否意味着将所有可能的属性作为列添加到产品中?那将是一个有1000个列的表,我做不到:( - 1110
不是,所有这些属性应该放在单个列中。 - Bogdan Gavril MSFT

0

你可以很好地使用EAV模型。 我们在物流应用程序中做了类似的事情。不过它是基于.net构建的。 除了表格之外,你的应用程序代码必须正确处理对象。 看看是否可以为每个对象添加通用表格。这对我们很有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接