8

SQL 中实体-属性-值数据库设计的主要缺点似乎都与能够高效快速地查询和报告数据有关。由于这些问题以及几乎所有应用程序的查询/报告的共性,我阅读的有关该主题的大多数信息都警告不要实施 EAV。

我目前正在设计一个系统,其中一个实体的字段在设计/编译时是未知的,并且由系统的最终用户定义。EAV 似乎很适合这个要求,但由于我读到的问题,我在实施它时犹豫不决,因为这个系统也有一些非常繁重的报告要求。我我已经想出了解决这个问题的方法,但想向 SO 社区提出这个问题。

鉴于典型的规范化数据库 (OLTP) 并不总是运行报告的最佳选择,一个好的做法似乎是拥有一个“报告”数据库 (OLAP),将规范化数据库中的数据复制到该数据库中,并对其进行广泛索引,并且可能非规范化以便于查询。是否可以使用相同的想法来解决 EAV 设计的缺点?

我看到的主要缺点是将数据从 EAV 数据库传输到报告的复杂性增加,因为您可能最终不得不更改报告数据库中的表,因为在 EAV 数据库中定义了新字段。但这几乎是不可能的,而且对于 EAV 设计所赋予的更大灵活性而言,这似乎是一个可以接受的折衷方案。如果我使用非 SQL 数据存储(即 CouchDB 或类似数据)作为主要数据存储,也会存在此缺点,因为所有标准报告工具都期望 SQL 后端进行查询。

如果您有一个单独的报告数据库进行查询,EAV 系统的问题是否大部分都消失了?

编辑:感谢到目前为止的评论。关于我正在研究的系统的重要事情之一是我实际上只是在谈论将 EAV 用于其中一个实体,而不是系统中的所有内容。

该系统的整个要点是能够从多个不同的来源提取数据,这些来源事先不知道,并对数据进行处理以得出一些关于特定实体的“最知名”数据。因此,我处理的每个“字段”都是多值的,我还需要跟踪每个“字段”的历史记录。对此的规范化设计最终是每个字段 1 个表,这使得查询它无论如何都是痛苦的。

这是我正在查看的表模式和示例数据(显然与我正在研究的内容有所不同,但我认为它很好地说明了这一点):

EAV 表

Person
-------------------
-  Id - Name      -
-------------------
- 123 - Joe Smith -
-------------------

Person_Value
-------------------------------------------------------------------
- PersonId - Source - Field       - Value         - EffectiveDate -
-------------------------------------------------------------------
-      123 -    CIA - HomeAddress - 123 Cherry Ln -    2010-03-26 -
-      123 -    DMV - HomeAddress - 561 Stoney Rd -    2010-02-15 -
-      123 -    FBI - HomeAddress - 676 Lancas Dr -    2010-03-01 -
-------------------------------------------------------------------

报告表

Person_Denormalized
----------------------------------------------------------------------------------------
-  Id - Name      - HomeAddress   - HomeAddress_Confidence - HomeAddress_EffectiveDate - 
----------------------------------------------------------------------------------------
- 123 - Joe Smith - 123 Cherry Ln -                  0.713 -                2010-03-26 -
----------------------------------------------------------------------------------------

标准化设计

Person
-------------------
-  Id - Name      -
-------------------
- 123 - Joe Smith -
-------------------

Person_HomeAddress
------------------------------------------------------
- PersonId - Source - Value         - Effective Date - 
------------------------------------------------------
-      123 -    CIA - 123 Cherry Ln -     2010-03-26 -
-      123 -    DMV - 561 Stoney Rd -     2010-02-15 -
-      123 -    FBI - 676 Lancas Dr -     2010-03-01 -
------------------------------------------------------

此处的“信心”字段是使用 SQL 无法轻松表达(如果有的话)的逻辑生成的,因此除了插入新值之外,我最常见的操作是为所有字段提取有关一个人的所有数据,以便我可以生成记录报告表。这在 EAV 模型中实际上更容易,因为我可以执行单个查询。在规范化设计中,我最终不得不对每个字段进行 1 次查询,以避免大量笛卡尔积将它们连接在一起。

4

4 回答 4

6

在这个方案中,首先我们提出了一个系统,该系统允许用户存储任何类型的数据,无论其结构如何,也无论未来的预期用途如何。然后,到了发布报告的时候,我们必须弄清楚我们拥有什么,以及它与我们需要什么的关系。

由于您清楚地将问题的性质归因于“处于此方案中”,因此在我看来,EAV 的问题确实由于 EAV 本身造成的。

事实上,想想看:“一个允许用户存储任何类型数据的系统”相当于一个允许用户定义他们的相关变量的系统。但是该系统的哪个部分允许用户定义每个属性的约束?哎呀,EAV人群似乎错过了数据管理的一个不太重要的方面,似乎......

于 2010-03-26T22:04:16.417 回答
3

EAV的问题不是由于EAV本身。这是由于在设计和构建数据库时没有了解数据的真正需求是什么,以及数据必须具有什么样的逻辑结构才能满足这些需求。EAV 以及任何其他允许用户设计自己的数据的系统都颠覆了这一点。

在这个方案中,首先我们提出了一个系统,该系统允许用户存储任何类型的数据,无论其结构如何,也无论未来的预期用途如何。然后,到了发布报告的时候,我们必须弄清楚我们拥有什么,以及它与我们需要什么的关系。

祝你好运。

于 2010-03-26T19:39:01.160 回答
3

简短的回答 - 是的,报告数据库是解决 EAV 数据模型报告问题的合理方法。

我花了数年时间研究一个信息管理解决方案,它允许最终用户完全自由地定义他们自己的数据模型,架构和数据都使用 EAV 模型存储。有趣的是,该产品提供了用于满足报告要求的元模式对象(例如,提供对象导航的图表、执行投影的视图等)。这意味着最终用户可以使用他们最初用于构建数据模型的相同术语和概念来自由定义查询。报告的行为本质上是通过导航这些定义来计算数据集,并将结果交给传统的报告编写工具,就好像它是关系数据一样。

这种方法的优势之一是已经存在的将 EAV 模型转换为用户可以使用的东西的相同机制可以重用并应用于报告功能。

于 2010-06-14T08:04:26.970 回答
1

EAV 没有问题 我花费了大量时间从 MASSIVE EAV 数据库中查询。任何说从 EAV 报告困难或不可能的人都有 2 个问题中的 1 个,要么他们的 EAV 系统设计得很差,要么他们不明白如何从其中查询。一旦您完成了几次,从 EAV 数据库中获取可报告的数据非常容易。不需要报告数据库或任何特殊的东西,只需几个很好的查询。

If you're building an EAV DB spend A LOT of time designing it, the design will either make or break your application and it will be a nightmare trying to fix or deal with a poorly designed one.

于 2012-04-08T02:15:34.237 回答