65.9K
CodeProject 正在变化。 阅读更多。
Home

我遵循的 11 条重要数据库设计规则

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.80/5 (105投票s)

2012年4月3日

CPOL

9分钟阅读

viewsIcon

924211

本文将讨论 11 条重要的数据库设计规则。

目录

图片来源:来自电影的图片

引言

在您开始阅读本文之前,我先向您声明,我不是数据库设计的专家。以下 11 点是我通过项目、个人经验和阅读学到的。我个人认为这些对我进行数据库设计帮助很大。欢迎任何批评。

我写这篇完整文章的原因是,当开发人员设计数据库时,他们倾向于像灵丹妙药一样遵循三个范式。他们倾向于认为规范化是设计的唯一途径。由于这种思维方式,随着项目的进展,他们有时会遇到瓶颈。

如果您是规范化新手,请点击观看 3 个范式的演示,其中分步解释了所有三个范式。

尽管如此,规范化规则是重要的指导方针,但将它们奉为圭臬可能会导致问题。以下是我在进行数据库设计时脑海中始终牢记的 11 条规则。

规则 1:应用程序的性质是什么(OLTP 或 OLAP)?

当您开始数据库设计时,首先要分析的是您正在为其设计应用程序的性质,是事务性的还是分析性的。您会发现许多开发人员默认应用规范化规则,而不考虑应用程序的性质,然后稍后会遇到性能和定制化问题。如前所述,有两种类型的应用程序:基于事务的应用程序和基于分析的应用程序,让我们了解这些类型。

事务性:在这种类型的应用程序中,您的最终用户更关心 CRUD,即创建、读取、更新和删除记录。此类数据库的正式名称是 OLTP。

分析性:在这些类型的应用程序中,您的最终用户更关心分析、报告、预测等。这些类型的数据库的插入和更新次数较少。主要目的是尽快获取和分析数据。此类数据库的正式名称是 OLAP。

换句话说,如果您认为插入、更新和删除更为突出,则选择规范化的表设计,否则创建扁平化的反规范化数据库结构。

下面是一个简单的图表示例,显示了左侧的名称和地址如何成为一个简单的规范化表,以及通过应用反规范化结构,我们如何创建了一个扁平的表结构。

规则 2:将数据分解为逻辑单元,让生活更简单

这条规则实际上是第一范式的第一条规则。违反此规则的一个迹象是,如果您的查询使用了过多的字符串解析函数,如 substring、charindex 等,那么可能需要应用这条规则。

例如,您可以查看下面的表,其中包含学生姓名;如果您想查询姓“Koirala”而不是“Harisingh”的学生姓名,您可以想象您将得到什么样的查询。

因此,更好的方法是将此字段分解为更小的逻辑单元,以便我们能够编写清晰且最优化的查询。

规则 3:不要过度遵循规则 2

开发人员是可爱的生物。如果您告诉他们这是方法,他们会一直这样做;嗯,他们会过度这样做,导致不必要的后果。这也适用于我们刚才讨论的规则 2。当您考虑分解时,请暂停一下,问问自己,这是必要的吗?如前所述,分解应该是逻辑的。

例如,您可以查看电话号码字段;您很少会单独操作电话号码的国际区号(除非您的应用程序需要)。因此,将其保留原样可能是一个明智的决定,因为它可能导致更多复杂性。

规则 4:将重复的不一致数据视为最大的敌人

关注并重构重复数据。我个人对重复数据的担忧不是因为它占用硬盘空间,而是它造成的混淆。

例如,在下面的图中,您可以看到“5th Standard”和“Fifth standard”是相同的。现在您可以说数据由于不良的数据输入或糟糕的验证而进入了您的系统。如果您想生成报告,它们将显示为不同的实体,这对最终用户来说非常令人困惑。

一种解决方案是将数据移到一个不同的主表中,并通过外键引用它们。您可以在下面的图表中看到,我们如何创建了一个名为“Standards”的新主表,并通过一个简单的外键将其链接。

规则 5:注意被分隔符分隔的数据。

第一范式的第二条规则是避免重复组。下面图表解释了重复组的一个例子。如果您仔细查看 syllabus 字段,在一个字段中我们塞满了太多的数据。这些类型的字段被称为“重复组”。如果我们必须操作这些数据,查询将很复杂,而且我也怀疑查询的性能。

这些包含被分隔符分隔的数据的列需要特别关注,更好的方法是将这些字段移到一个单独的表中,并通过键将它们链接起来以进行更好的管理。

那么,让我们应用第一范式的第二条规则:“避免重复组”。您可以在上图中看到,我创建了一个单独的 syllabus 表,然后与 subject 表建立了一个多对多关系。

通过这种方法,主表中的 syllabus 字段不再重复,并且没有数据分隔符。

规则 6:注意部分依赖。

注意部分依赖于主键的字段。例如,在上表中,我们可以看到主键是在 roll number 和 standard 上创建的。现在仔细观察 syllabus 字段。syllabus 字段与 standard 相关,而不是直接与 student 相关(roll number)。

syllabus 与学生就读的 standard 相关,而不是直接与学生相关。因此,如果明天我们要更新 syllabus,就必须为每个学生更新,这是非常麻烦且不合逻辑的。将这些字段移出并与 Standard 表关联更有意义。

您可以看到我们如何移动了 syllabus 字段并将其附加到了 Standards 表。

这条规则就是第二范式:“所有键都应该依赖于完整的原键,而不是部分依赖”。

规则 7:谨慎选择派生列

如果您在 OLTP 应用程序中工作,摆脱派生列是一个好主意,除非出于性能方面的迫切原因。在 OLAP 中,我们进行大量的求和、计算,这些类型的字段对于提高性能是必要的。

在上图中,您可以看到 average 字段如何依赖于 marks 和 subject。这也是一种冗余。因此,对于这些由其他字段派生出来的字段,请思考:它们真的有必要吗?

这条规则也称为第三范式:“任何列都不应该依赖于其他非主键列”。我个人的想法是不要盲目应用这条规则,要看具体情况;并非冗余数据总是坏事。如果冗余数据是计算数据,请查看情况,然后决定是否要实现第三范式。

规则 8:如果性能是关键,不要过于执着于避免冗余

不要将其视为严格的规则,即您总是会避免冗余。如果出于性能的迫切需求,请考虑反规范化。在规范化中,您需要与许多表进行连接,而在反规范化中,连接减少,从而提高性能。

规则 9:多维数据是完全不同的一个领域

OLAP 项目主要处理多维数据。例如,您可以看到下面的图表,您想获得按国家、客户和日期划分的销售额。简单来说,您正在查看具有三个维度数据交叉点的销售数据。

对于这类情况,维度和事实设计是更好的方法。简单来说,您可以创建一个简单的中央销售事实表,其中包含销售额字段,并通过外键关系与所有维度表连接。

规则 10:集中化名称-值表设计

我经常遇到名称-值表。名称和值表意味着它有一个键和与该键相关的一些数据。例如,在下面的图表中,您可以看到我们有一个 currency 表和一个 country 表。如果您仔细观察数据,它们实际上只有一个键和值。

对于这些类型的表,创建一个中央表并通过使用 type 字段来区分数据更有意义。

规则 11:对于无限的层次化数据,使用自引用主键和外键

我们经常遇到具有无限父子层级的数据。例如,考虑一个多层次营销场景,其中一名销售人员可以有多个销售人员在其之下。对于这种情况,使用自引用的主键和外键将有助于实现这一点。

本文并非意在说明不要遵循范式,而是不要盲目遵循。首先要考虑项目的性质以及您正在处理的数据类型。

下面是一个视频,它使用一个简单的学校表分步解释了三个范式。

如需进一步阅读,请观看以下面试准备视频和分步视频系列。

© . All rights reserved.