7

I work on a financial services product that stores lots of information on the end-customer. Our clients continuously want to add new attributes, that often that aren't used to drive any process in our product. They are captured and displayed but nothing else. Due to differences in how our clients operate, they often want to store very different values. We have tried two solutions to accomodate them:

  1. Sparsely populated tables with 100s of hundred columns.
  2. Entity Attribute Value tables where the customer can define new columns as needed.

We have experienced most of the disadvantages of both solutions. Lots of columns provide comfort for us in that we know what data we are adding to our database, but can make us appear inflexible and expensive when a customer 'just' wants to store a new value, like Favourite Golf Club. EAV has shown all of its usual problems: poorly performing queries, losing control of the data, lack of validation and maintainability problems.

So is there a better pattern out there?

4

3 回答 3

10

我在Percona Live MySQL Conference & Expo 2013上做了一个关于这个主题的演讲。我的演示文稿称为可扩展数据建模

对于您的情况,由于您的 SQL 查询中未使用用户定义的属性(仅按您所说的方式捕获和显示),因此我建议您使用序列化 LOB模式。

这是我的演讲摘要。幻灯片免费提供:

设计一个支持用户定制的可扩展、灵活的模式是一个常见的需求,但很容易把自己逼入绝境。

可扩展数据库要求示例:

  • 允许用户按需声明新字段的数据库。
  • 或者一个包含许多产品的电子商务目录,每个产品都有不同的属性。
  • 或者支持自定义数据扩展的内容管理平台。

我们用来满足这些要求的解决方案过于复杂,性能也很糟糕。我们应该如何在模式和无模式数据库设计之间找到正确的平衡?

我将简要介绍实体-属性-值 (EAV) 的缺点,这是一个有问题的设计,它是称为内部平台效应的反模式的一个示例,也就是说,在 RDBMS 架构之上对属性管理系统进行建模,它已经通过列、数据类型和约束提供了属性。

然后,我们将讨论替代数据建模模式的优缺点,涉及开发人员的生产力、数据完整性、存储效率和查询性能以及易扩展性。

  • 类表继承
  • 序列化的 BLOB
  • 倒排索引

最后,我们将展示诸如 pt-online-schema-change 之类的工具以及 MySQL 5.6 的新特性,它们可以消除模式修改的痛苦。

于 2013-10-14T19:46:20.273 回答
2

我会将其建模为单独的属性表,而不是具有多个“自定义”列的表......当您有 100 列并且他们想要添加属性 #101 时会发生什么?自定义属性很少的客户呢?一百NULL列...

在这种情况下,您的存储类型可能只是VARCHAR(MAX)因为您对这些列没有执行任何逻辑,除了SELECT显示它们。结果是您可能对INTDATE类型(或您可能想要存储的任何不同类型)的存储效率低下,但这就是允许客户端在这些自定义字段中存储任何内容的本质。

考虑一个有五列的表:

  • ID
  • 父类型
  • 父 ID
  • 自定义值名称
  • 自定义值

所以现在你有足够的信息来:

  1. 明确地将您的自定义属性与数据库中的任何其他实体联系起来
  2. 如果需要,为自定义聚合命名属性类型
  3. 附加用户想要的任何值

缺点是查询这些自定义属性有些痛苦(尽管在 SQL 中可以轻松完成,但查询计划不会很有效)。

于 2013-10-14T19:00:06.487 回答
0

我不认为我可以为您指出特定的模式,但您可能听说过PostgreSQL

它是一个数据库,可以解决在开发大量数据库应用程序期间通常会出现的许多不同问题(即,可以在 CoffeeScript 中编写脚本,您可以通过 JSON 访问数据)。

他们提供了一个名为HSTORE的扩展,听起来它可以解决你所有的问题。HSTORE 基本上允许您在表中存储任意散列的数据。甚至可以查询它。

于 2013-10-14T18:52:42.940 回答