【问题标题】:EAV Database SchemeEAV 数据库架构
【发布时间】:2010-04-19 14:08:20
【问题描述】:
我有一个记录超过 10 万条的数据库。
许多类别和许多项目(每个类别具有不同的属性)
一切都存储在 EAV 中。
如果我试图打破这个方案并为任何类别创建一个唯一的表
是我必须避免的事情吗?
是的,我知道我可能会有很多表,我需要更改它们
如果我想添加一个额外的字段,但是这是错误的吗?
我还读到,我有很多表,数据库将填充更多文件
这对任何文件系统都不利。
有什么建议吗?
【问题讨论】:
标签:
database
entity-attribute-value
【解决方案1】:
作为数据库设计中的主要结构,该结构将随着数据的增长而失效。您知道数据库模式不适合业务模型的方式是当您需要查询它以进行报告时。 EAV 需要许多变通方法和非本地数据库功能才能获得合理的报告。即,即使是最小的查询,您也会不断地创建交叉表/数据透视查询。获取 EAV 并将其放入可查询格式的所有处理都会占用 CPU 周期,并且极易出错。此外,数据的规模呈几何级数增长。如果您有 10 个属性,则标准设计中的 10 行将生成 100 EAV 行。 100 个标准行相当于 1000 个 EAV 行,依此类推。
数据库管理系统旨在处理大量表,这不必担心。
可以创建一个混合解决方案,其中 EAV 结构是解决方案的一部分。但是,规则必须是您永远不能包含查询[AttributeCol] = 'Attribute'。即,您永远不能过滤、排序、限制任何属性的范围。您不能将特定属性放置在报告或屏幕上的任何位置。它只是一团数据。结合系统其余部分的良好架构,拥有一个存储数据块的 EAV 可能很有用。完成这项工作的关键是在您自己和开发人员之间强制执行,永远不要越过对属性进行过滤或排序。一旦你走上黑暗的道路,它将永远主宰你的命运。
【解决方案2】:
有专门用于运行 EAV 模型的数据库引擎。我不认识他们,所以我不能推荐一个。但是将 EAV 模型推入关系引擎是灾难的根源。灾难会发生,真的只是时间问题。
您的数据可能会保持足够小,并且您的查询足够简单以使其正常工作,但这种情况很少发生。
【解决方案3】:
EAV DB 架构对于添加更多关系数据库的“列”非常灵活,但代价是查询性能下降并丢失了保留在关系数据库架构中的业务逻辑。
因为您必须创建多个视图才能实际旋转结果,如果表包含数十亿行,这将导致性能问题。 EAV 模式的另一个性质是,当您将数据表与元数据表连接时,总是会进行查询,并且同一数据表上可能存在多个连接。
这是基于我的经验。
【解决方案4】:
我在大约 4 年前为电子学习构建的创作系统上采用了这种方法。当时我不知道我在做 EAV,但我认为我只是在使用名称/值类型对时很狡猾。我想我会增加记录,但减少重新设计,因为每次我们有更改请求时我都厌倦了将列向左调整。
我进行了第一次测试,在一个表中构建了系统的层次结构。这在大约 4 个项目、25 个产品和 4 到 5 个工具中表现出色,每个项目都分配了链接回其主键的层整数。
我一直在记录通过系统传递的资产,这意味着 FLV 文件、SWF、JPG、PNG、GIF、PDF、MP3 等......以及关于它们的所有 mime 类型细节。每个文件只有 4 到 10 个属性。它总共有多达 800 万条“资产数据”记录,其中我们有大约 800K 资产(est)。
我要求将所有这些信息放入报告的列中。 SQL 语句必须自己进行许多表连接,更不用说如果他们想知道它用于的内容、产品或项目,它只是一系列 JOIN。
从细粒度的角度来看效果很好。从 Excel 报告的角度来看,系好安全带。我已经通过对表格进行快照来缓解它,这些表格反映了某人在报告中想要的方式反映数据,但是编译需要我将需要卸载(SQL 转储)到另一台服务器的信息需要一段时间。
我发现自己在问这是否是正确的做法,对于这个项目,我可以回答这个要求大规模报告的“是”。但这让服务器汗流浃背地把这一切联系起来。真的取决于他们提出的深层查询。
自从我从 2002 年开始涉足 SQL 并将它用于支持工具以来,它没有大规模地幸存下来。如果它是一个更大的百万人,TB+ 数据库,我可能会把头发拉出来。
特别注意:我发现这个系统是在 RedHat 上的,它是 32 位的。许多 PHP 处理线程无法在超过 1 个 CPU 内核上运行,并且服务器还有 7 个空闲的内核!在这台机器上运行最多需要 45 分钟的查询,实际上可以在正确配置的 64 位系统上运行 14-25 秒。在考虑性能时也值得深思。