【发布时间】:2016-12-10 18:15:18
【问题描述】:
对于现有的数据库,我们正在考虑改进部分数据库设计。
25 个表具有非常相似的结构,大约 90% 的列和数据类型相同。并且对表进行了相当频繁的更改,例如我们可能需要在这 25 个表中的 7 个表中添加 2 个新列。几个月后,另外 5 个表中可能需要 2 个新列,等等。我们还会收到诸如这些表中有多少行有 IsActive (参见下面的示例)= TRUE 之类的问题。这目前意味着创建 25 个 SQL 语句,并且这些语句比这个简单的示例要复杂得多。查询25张表然后合并结果感觉不对。
我们讨论的一个选项是将所有数据存储在主表中。但是总的来说,这意味着有一个相当宽的表和相当多的 NULL 值。
我们讨论的另一个想法是保留 25 个表并创建一个主视图,它将这些表组合在一起。然而,视图需要大量手动维护,更新可能会被遗忘,视图仍然可以工作。
在数据库设计中,主要概念之一是:“为了获得最大的灵活性,数据存储在列中,而不是列名中。”,这将我们引向主要问题。有没有人有在表中存储列的经验?这些列实际上包含业务逻辑的过滤条件。
这是一个例子:
表 1:业务规则 1
CustomerID (int) | IsPremiumCust (bool) | HasCreditCard (bool) | IsActive (bool) | OrderThreshold (int)
表 2:业务规则 2
CustomerID (int) | IsPremiumCust (bool) | HasCreditCard (bool) | IsActive (bool) | Discount (int)
还有 23 个这样的表格。所有列都比本示例中的多。
建议:Criteria 表
Criteria ID | Criteria | Data Type
1 | IsPremiumCust | bool
2 | HasCreditCard | bool
3 | IsActive | bool
4 | OrderThreshold | int
5 | Discount | int
建议:业务规则表
Business Rule ID | Name
1 | Business Rule 1
2 | Business Rule 2
建议:交集表
CustomerID | Business Rule ID | Criteria ID | Criteria Value
------------------------------------------------------------
1 | 1 | 1 | TRUE
2 | 2 | 1 | FALSE
我知道这并不真正有效,因为 Criteria Value 字段可能有不同的数据类型。但是我希望有人可能遇到过类似的情况,并且可以为这个问题想出一个完整的解决方案。
这将允许我们添加标准,而无需不断更改许多表结构。
【问题讨论】:
-
用“eav 数据库模式”打你最喜欢的搜索引擎...
-
听起来你即将踏上EAV(实体属性值)的道路。它提供了令人难以置信的灵活性。但是,当像这样在整个数据库中完成时,也会提供令人难以置信的复杂查询,并且数据完整性具有挑战性。 EAV 有它的位置,但你所描述的听起来像是一场噩梦的开始。这是一篇很棒的文章,讨论了 EAV 的优缺点。 sqlblog.com/blogs/aaron_bertrand/archive/2009/11/19/… 在这里出现了可怕的错误。 simple-talk.com/opinion/opinion-pieces/bad-carma
-
感谢您提供有关 EAV 的 cmets。这两篇文章都很有趣。我仍在与开发团队讨论我们是否应该尝试类似于 Aaron Betrand 的解决方案。
-
与整体设计有些相关的问题。一个客户可以同时落入多个业务规则表吗?他们是否一直在所有表中都有记录?业务规则结果是否需要持久化,还是可以即时计算?或者为什么不使用一个包含所有不同列的表和另一种计算它们遵守规则的方法?
标签: sql-server database database-design