关系数据库设计模式?[关闭]


283

设计模式通常与面向对象的设计有关。
有用于创建和编程关系数据库的设计模式吗?
当然,许多问题必须具有可重用的解决方案。

示例包括表设计,存储过程,触发器等的模式。

是否存在类似于martinfowler.com的此类模式的在线存储库?


模式可以解决的问题示例:

  • 存储分层数据(例如,具有类型的单个表与具有1:1密钥和差异的多个表...)
  • 存储具有可变结构的数据(例如,通用列vs xml vs分隔列...)
  • 对数据进行非规范化(如何在影响最小的情况下进行处理等)

:我会在这里宣称自己最好的Q&A分层数据存储stackoverflow.com/questions/4048151/...
orangepips

1
根据我们的主题指南,“ 即使某些问题属于上述类别之一,它们仍然是题外话: ...要求我们推荐或查找书籍,工具,软件库,教程或其他内容的问题场外资源不在主题范围内……”
罗伯特·哥伦比亚

@RobertColumbia ,当有人问这个问题时这个问题在2008年成为话题 ……
Sklivvz

在关系数据库和软件工程的许多领域中查看此设计模式资源列表github.com/DovAmir/awesome-design-patterns
dov.amir,2018年

Answers:


150

Martin Fowler的签名系列中有一本书叫Refactoring Databases。这提供了重构数据库的技术列表。我不能说我已经听到这么多数据库模式列表。

我也强烈推荐David C. Hay的数据模型和后续的元数据地图,该地图建立在第一个基础上,并且更具雄心和吸引力。仅前言就具有启发性。

Len Silverston的数据模型资源手册丛书第1卷包含通用的数据模型(员工,帐户,运输,购买等),也是查找某些罐头数据库模型的好地方,第2卷包含行业特定的数据模型(会计,医疗保健等),第3卷提供了数据模型模式。

最后,尽管这本书表面上是关于UML和对象建模的,但Peter Coad的“ 使用UML进行颜色建模”提供了一个“原型”驱动的实体建模过程,前提是任何对象/数据模型都有4种核心原型


1
这本书由Scott W. Ambler和Pramod J. Sadalage题为[重构数据库:演化数据库设计] [1],确实非常好。[1]:ambysoft.com/books/refactoringDatabases.html
Panos

3
关于Ambler书籍:否,出于相同的原因,您不能将“插入列”或“创建FK约束”列为一种模式。《 4人帮》一书并未将“ for”循环列为一种模式。
Tegiri Nenashi

这不是模式,而是重构。类似于提取方法或重命名参数。重构和模式齐头并进。
迈克尔·布朗

要添加的内容:Fowler的“分析模式”。类似于Hay的东西
Neil McGuigan

2
Len Silverston的第3卷是我唯一认为的“设计模式”。前2个显示示例数据模型,这些模型在编写书的时间范围内很常见。第3卷实际上针对给定的问题场景具有多种设计模式。例如,第4章介绍了层次结构/聚合/点对点方案,然后提供了多种解决方案,以解决每种方案的优缺点。
DarrellNorton 2013年

46

设计模式并非简单可重用的解决方案。

根据定义,设计模式是可重用的。它们是在其他好的解决方案中检测到的模式。

模式不可重用。但是,您可以按照该模式实施向下设计。

关系设计模式包括:

  1. 使用外键的一对多关系(主从,父子关系)。

  2. 与桥表的多对多关系。

  3. 在FK列中使用NULL管理的可选一对一关系。

  4. 星型图:维度和事实,OLAP设计。

  5. 完全标准化的OLTP设计。

  6. 一个维度中的多个索引搜索列。

  7. “查找表”,包含一个或多个应用程序使用的PK,描述和代码值。为什么要有代码?我不知道,但是当必须使用它们时,这是一种管理代码的方式。

  8. 单表。[有人称其为反模式;这是一种模式,有时是不好的,有时是好的。]这是一个包含很多预先连接的东西的表,它违反了第二和第三范式。

  9. 数组表。该表通过在列中包含数组或值序列来违反第一范式。

  10. 混合用途数据库。这是一个规范化的数据库,用于事务处理,但具有许多用于报告和分析的额外索引。这是一种反模式-不要这样做。人们还是这样做,所以它仍然是一种模式。

设计数据库的大多数人都可以轻松地打出六打“这是其中的另一个”。这些是他们定期使用的设计模式。

并且这不包括使用和管理的管理和运营模式。


我看到的其他一些模式是多父级子表(例如,具有可链接到任何其他表的objecttype和objectid的全局注释)或自引用FK(例如,employee.manager-> employee)。 ID)。另外,我使用了具有许多列的单例配置表。
r00fus

1
为什么混合用途数据库确实是一种反模式。如果要从数据库中提取报告,该怎么办?
橄榄色

3
@lhnz:你可以不拉很多的事务数据库设计报告-锁定了报告会减慢交易。复杂的连接(一遍又一遍地执行)是另一个阻碍交易性能的因素。您不能在一个数据库中同时做这两个事情。要进行大量大型报告,必须将数据移入星型模式。星型模式已针对报告进行了优化。移动数据将消除任何锁争用。
S.Lott

如果使表包含更多“内聚”数据,规范化架构是否会减少行锁争用?我的想法是,如果一个大表正在处理对两种数据集的写入,但它们都在同一行中,则这将导致不必要的锁争用。
CMCDragonkai 2015年

6

AskTom可能是有关Oracle数据库最佳实践的最有用的单个资源。(我通常只键入“问号”作为针对特定主题的google查询的第一个单词)

我认为用关系数据库来谈论设计模式确实不合适。关系数据库已经是问题的“设计模式”的应用(问题是“如何在保持数据完整性的同时表示,存储和使用数据”,而设计是关系模型)。其他方法(通常认为已过时)是“导航”和“层次”模型(我敢肯定还有很多其他方法)。

话虽如此,您可能会认为“数据仓库”是数据库设计中某种独立的“模式”或方法。特别是,您可能对阅读Star模式感兴趣。


4

经过多年的数据库开发,我可以说在开始之前还有一些不可行和一些问题需要回答:

问题:

  • 您将来是否要使用另一个DBMS?如果是,则不使用当前DBMS的特殊SQL内容。在您的应用程序中删除逻辑。

不使用:

  • 表名和列名中的空格
  • 表和列名称中的非Ascii字符
  • 绑定到特定的小写或大写字母。切勿使用仅与小写和大写字母不同的2个表或列。
  • 对于表或列名称(例如“ FROM”,“ BETWEEN”,“ DELETE”等),不使用SQL关键字

建议:

  • 使用NVARCHAR或同等版本的unicode支持,则代码页没有问题。
  • 给每列一个唯一的名称。这使得在连接时更容易选择列。如果每个表都具有“ ID”或“ Name”或“ Description”列,这将非常困难。使用XyzID和AbcID。
  • 对于复杂的SQL表达式,请使用资源束或等于资源束。这使得切换到另一个DBMS更容易。
  • 不对任何数据类型强制转换。另一个DBMS不能具有此数据类型。例如,Oracle敢于没有SMALLINT只有一个数字。

我希望这是一个良好的起点。


7
尽管您的评论很有启发性和有用,但它们不是设计模式。它们是最佳实践。谢谢,
Sklivvz

7
我不同意关于唯一列名的建议。我宁愿说customer.id来消除歧义,也不愿说出customerid,即使没有什么歧义。
Paul Tomblin

1

您的问题有点含糊,但我想UPSERT可以认为是一种设计模式。对于未实现的语言MERGE存在许多解决问题的替代方法(如果存在合适的行UPDATE;否则INSERT)。


UPSERT是命令和SQL语言的一部分。这不是一个模式。
Todd R

UPSERT是SQL语言的某些变体中的命令-许多平台都没有,或者只是最近才有了。
史蒂夫·荷马

@ToddR-我听说过(有点讽刺地)说,“模式”实际上只不过是用户必须为其创建变通方法的语言或模型的缺陷。我不知道UPSERT做什么,但是虽然已将它添加到某些 SQL中,而不是其他SQL中,但这是一种模式。
Martin F

1

取决于您所说的模式。如果您正在考虑人员/公司/交易/产品等,那么可以-已经有很多通用的数据库模式可用。

如果您在考虑Factory,Singleton ...那么就不用了-您不需要任何这些,因为它们对于DB编程来说太低了。

如果您在考虑数据库对象的命名,那么它属于约定类别,而不是设计本身。

BTW,S.Lott,一对多和多对多关系不是“模式”。它们是关系模型的基本构建块。


诸如(人,客户,员工)之类的数据库继承又如何呢?也许可以将这种事情视为设计模式?
Muflix
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.