EAV 是“坏的”,但类表继承的可维护性如何?

Posted

技术标签:

【中文标题】EAV 是“坏的”,但类表继承的可维护性如何?【英文标题】:EAV is 'bad', but how about the maintainability of class table inheritance? 【发布时间】:2016-08-28 21:04:14 【问题描述】:

我正在构建一个包含数百种不同产品类型的产品目录。这些产品类型有很多不同的属性。有些是共享的,但大多数是特定于产品类型的。

我最初的想法是使用 EAV 类型的结构,但我理解为什么这可能是一个糟糕的选择。特别是因为我希望我的数据库强制执行正确性和一致性,这将与 EAV 混淆。

在我的例子中,替代方案是类表继承。不过,我有点担心可维护性……我将如何维护数百个迁移和模型?这真的是一个理想的情况吗?我了解好处,但可维护性不是一个巨大的缺点吗?

【问题讨论】:

抱歉,这对于 Stack Overflow 来说太基于意见了。我认为在我们的案例中,EAV 可能是合适的。为什么会变得一团糟? EAV 具有参照完整性。它只是实体和属性之间的多对多关联,其中联结记录是一个值。它使一些事情更难,尤其是。用搜索条件查询,但那不一样混乱 也许混乱不是正确的术语。使用 EAV 很难满足某些要求,例如强制执行正确的属性值、数据类型和非空值。这些都很好地描述了 EAV 的缺点。如果我使用 EAV,我会接受这些后果。不过,我的问题特别是关于类表继承的可维护性。 Entity-Attribute-Value Table Design的可能重复 【参考方案1】:

这里有一个替代方案,类似于 EAV,但对同一类型产品之间的“一致性”有特殊考虑。

表格列表: 产品 产品类型 属性 ProductTypes-Attributes-Allowed 产品属性

Product-Attributes-Allowed 对产品类型具有 FK,对属性具有 FK。如果表中存在产品类型和属性的特定组合的条目,则该产品类型可以具有该属性。

Product-Attributes 使用 FK 直接引用 Product 和 ProductTypes-Attributes-Allowed 表。 Product-Attributes 表将保存特定于该产品的信息,而 Attributes 表将保存有关一般属性的信息(显示名称、单位等)。您将不得不跳转一个额外的表来将属性值与属性“元数据”链接起来,但您至少可以强制执行产品类型相似性。

编辑,不适合作为下面的评论:

@Willem-Aart 这些都可以是属性的属性,存储在“属性”表中。例如,您可以有一个字符串“DataType”,其中包含有关要存储在“产品属性”表中的值的数据类型的信息。这将要求将数据存储为 Product-Attributes 表中的 blob(或其他一些通用可转换数据类型,如 char[])。或者,您可以为每个预见的数据类型设置单独的列,并将属性的“错误”数据类型留空。您可以有一个约束来强制至少其中一列不为空。

要强制执行一系列值,至少对于数字属性,您也可以将它们设置为属性表中的列。例如,“Max_Allowable_Value”。

向数据库添加功能/灵活性通常会增加复杂性。

【讨论】:

虽然它是对 EAV 的改进,但它仍然让我解决了强制执行正确的属性值、数据类型和非空值的问题。我知道应用程序可以处理这些事情,但我宁愿依靠数据库来确保正确性和一致性。 我同意迈克尔的观点——数据库就是数据存储。应用程序是您放置“业务逻辑”的地方。数据库可以保留业务逻辑的“规则”(例如 AllowedAttributes),但在提供类型检查、范围检查等方面受到限制和/或笨拙。

以上是关于EAV 是“坏的”,但类表继承的可维护性如何?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 SonataAdminBundle (Symfony) 管理 Doctrine ORM 类表继承?

Visual Studio 中的代码度量计算

java面向对象

理解类表继承

C++虚基类表指针字节对齐模型

java之继承