我从事金融服务产品的工作,该产品可以存储有关最终客户的大量信息。我们的客户不断希望添加新属性,这些属性通常不会用于驱动我们产品中的任何流程。它们被捕获并显示但没有别的。由于客户的运营方式不同,他们通常希望存储非常不同的价值。我们尝试了两种解决方案来适应它们:
我们遇到了两种解决方案的大部分缺点。很多专栏为我们提供了舒适感,因为我们知道我们在数据库中添加了哪些数据,但是当客户“只是”想要存储新价值时,例如最喜欢的高尔夫俱乐部,这些数据可能会让我们变得不灵活和昂贵。 EAV已经显示了所有常见问题:查询性能低下,数据失控,缺乏验证和可维护性问题。
那么有更好的模式吗?
答案 0 :(得分:8)
我在Percona Live MySQL Conference & Expo 2013做了关于这个主题的演讲。我的演讲名为Extensible Data Modeling。
根据您的情况,由于您的SQL查询中未使用用户定义的属性(仅按您的说法捕获和显示),我建议使用Serialized LOB模式。
这是我演讲的摘要。幻灯片可免费获得:
设计支持用户的可扩展,灵活的架构 定制是一个常见的要求,但很容易自己画画 进入一个角落。
可扩展数据库要求的示例:
- 允许用户按需声明新字段的数据库。
- 或包含许多产品的电子商务目录,每个产品都具有不同的属性。
- 或支持自定义数据扩展的内容管理平台。
我们用来满足这些要求的解决方案过于复杂 表现很可怕。我们应该如何找到合适的平衡点 架构和无架构数据库设计之间?
我将简要介绍实体 - 属性 - 值(EAV)的缺点, 一个有问题的设计,这是反模式的一个例子,叫做 内部平台效应,即对属性管理进行建模 系统基于RDBMS架构,已经提供 属性通过列,数据类型和约束。
然后我们将讨论替代数据建模的优缺点 模式,关于开发人员的生产力,数据完整性, 存储效率和查询性能,以及易于扩展性。
- 类表继承
- 序列化BLOB
- 反向索引
最后,我们将展示pt-online-schema-change和新功能等工具 MySQL 5.6带来了模式修改的痛苦。
答案 1 :(得分:2)
我会将其建模为一个单独的属性表,不一个包含多个“自定义”列的表...当您有100列且他们想要添加属性#101时会发生什么?那些自定义属性很少的客户呢?一百NULL
列......
在这种情况下,您的存储类型可以只是VARCHAR(MAX)
,因为除了SELECT
之外,您在这些列上不执行逻辑并显示它们。结果是,您可能存储INT
或DATE
类型(或您可能想要存储的任何不同类型)的低效存储,但这是允许客户端存储任何内容的性质在这些自定义字段中。
考虑一个包含五列的表:
所以现在你有足够的信息:
缺点是查询这些自定义属性有点痛苦(尽管可以在SQL中轻松完成,但查询计划效率不高)。
答案 2 :(得分:0)
我认为我不能指出你的具体模式,但你可能听说过PostgreSQL。
它是一个数据库,可以解决在数据库繁重的应用程序开发过程中经常出现的许多不同问题(即可以在CoffeeScript中编写脚本并且可以通过JSON访问数据)。
他们提供了一个名为HSTORE的扩展程序,听起来它会消除您的所有问题。 HSTORE基本上允许您在表中存储任意数据哈希。它甚至可以查询它。