Entity-Attribute-Value(实体-属性-值)数据库设计在SQL中的主要缺点似乎都与能够高效快速地查询和报告数据有关。我阅读的大部分关于这个主题的信息都警告说由于这些问题以及几乎所有应用程序的查询/报告的普遍性,不要实现EAV。
我目前正在设计一个系统,其中一个实体的字段在设计/编译时未知,并由系统的最终用户定义。对于此要求,EAV似乎是一个很好的选择,但由于我读到的问题,我在实施它时感到犹豫,因为该系统还有一些相当重要的报告要求。我认为我想出了一个解决方法,但我想向SO社区提问。
考虑到典型的规范化数据库(OLTP)仍然不总是运行报告的最佳选项,良好的做法似乎是拥有一个“报告”数据库(OLAP),其中从规范化数据库复制的数据被广泛索引,并可能被去规范化以便更容易查询。是否可以使用相同的思路来解决EAV设计的缺陷?
我看到的主要缺点是将数据从EAV数据库传输到报告中的复杂性,因为您可能需要在报告数据库中更改表格,因为在EAV数据库中定义了新字段。但这几乎是不可能的,并且似乎是EAV设计带来的灵活性所能接受的权衡。如果我使用非SQL数据存储(即CouchDB或类似产品)作为主要数据存储,由于所有标准报告工具都期望针对SQL后端进行查询,因此也存在此缺点。
如果有一个单独的报告数据库用于查询,那么EAV系统的问题是否基本上消失?
编辑:感谢到目前为止的评论。我正在处理的系统中一个重要的事情是,我只是在谈论将EAV用于一个实体,而不是系统中的所有内容。
整个系统的要旨是能够从多个不知道的异构来源获取数据,并对数据进行计算以获得有关特定实体的“最佳已知”数据。因此,我处理的每个“字段”都是多值的,并且还需要跟踪每个历史记录。规范化设计会导致每个字段的1个表格,这使得查询变得有点困难。
以下是我正在查看的表模式和示例数据(显然与我正在处理的内容不同,但我认为它很好地说明了问题)。
我目前正在设计一个系统,其中一个实体的字段在设计/编译时未知,并由系统的最终用户定义。对于此要求,EAV似乎是一个很好的选择,但由于我读到的问题,我在实施它时感到犹豫,因为该系统还有一些相当重要的报告要求。我认为我想出了一个解决方法,但我想向SO社区提问。
考虑到典型的规范化数据库(OLTP)仍然不总是运行报告的最佳选项,良好的做法似乎是拥有一个“报告”数据库(OLAP),其中从规范化数据库复制的数据被广泛索引,并可能被去规范化以便更容易查询。是否可以使用相同的思路来解决EAV设计的缺陷?
我看到的主要缺点是将数据从EAV数据库传输到报告中的复杂性,因为您可能需要在报告数据库中更改表格,因为在EAV数据库中定义了新字段。但这几乎是不可能的,并且似乎是EAV设计带来的灵活性所能接受的权衡。如果我使用非SQL数据存储(即CouchDB或类似产品)作为主要数据存储,由于所有标准报告工具都期望针对SQL后端进行查询,因此也存在此缺点。
如果有一个单独的报告数据库用于查询,那么EAV系统的问题是否基本上消失?
编辑:感谢到目前为止的评论。我正在处理的系统中一个重要的事情是,我只是在谈论将EAV用于一个实体,而不是系统中的所有内容。
整个系统的要旨是能够从多个不知道的异构来源获取数据,并对数据进行计算以获得有关特定实体的“最佳已知”数据。因此,我处理的每个“字段”都是多值的,并且还需要跟踪每个历史记录。规范化设计会导致每个字段的1个表格,这使得查询变得有点困难。
以下是我正在查看的表模式和示例数据(显然与我正在处理的内容不同,但我认为它很好地说明了问题)。
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个查询,以避免从将它们全部连接起来产生大量笛卡尔积。