--- title: Normal Form localeTitle: 正常形式 --- ## 正常形式 归一化首先作为关系模型的一部分引入。它是以减少冗余和提高完整性的方式组织数据表和列的过程。这可以通过以下方式完成: * 合成:基于一组已知的依赖关系创建规范化的数据库设计。 * 分解:采用现有的(规范不足的)数据库设计,并根据已知的依赖关系集对其进行改进 有三种常见的常规形式(第1,第2和第3)加上一种称为BCNF的相当高级的形式。它们是渐进的:除了符合第3范式之外,数据库模式必须满足第2范式的规则,对于第1范式也是如此。 * **第一范式** :信息存储在表中,每列包含原子值,并且没有重复的列组。这个 : 1. 消除各个表中的重复组。 2. 为每组相关数据创建单独的表。 3. 使用主键标识每组相关数据 ##### 例 违反第一范式的设计,“电话”列不包含原子值 |客户ID |名字|姓氏|电话| | ------------- | ------------ | ----------- | ---------- ---------------------------- | | 123 | Pooja |辛格| 555-861-2025,192-122-1111 | | 789 |约翰| Doe | 555-808-9633 | | 456 | San |张| (555)403-1659分机53; 182-929-2929 | 一种解决方案是为每个电话号码增加一列。但是,这将在概念上重复相同的属性(电话号码)。此外,添加额外的电话号码将需要通过添加更多列重新组织表。这绝对不是实际的。 另一个解决方案是为关联客户提供一个单独的表< - >电话:这尊重第一个普通表格,每个客户可以根据需要设置多个行。 |客户ID |名字|姓氏| | ------------- | ------------ | ----------- | | 123 | Pooja |辛格| | 789 |约翰| Doe | | 456 | San |张| |客户ID |电话| | ------------- | ------------------------ | | 123 | 555-861-2025 | | 123 | 192-122-1111 | | 789 | 555-808-9633 | | 456 | (555)403-1659分机53 | | 456 | 182-929-2929 | * **第二范式** :表格为第一范式,所有非键列依赖于表的主键。这缩小了桌子的目的。 ##### 例 违反第二范式的设计。模型全名是主键,还有其他候选键,如{manufacturer,model}。 “制造商国家/地区”列取决于非键列(制造商)。 |制造商|型号|型号全名|制造商国家| | --------------------- | -------------- | ------------ ---------- | ---------------------- | |复地| X-Prime | Forte X-Prime |意大利| |复地| Ultraclean | Forte Ultraclean |意大利| | Dent-o-Fresh | EZbrush | Dent-o-Fresh EZbrush |美国| |小林| ST-60 |小林ST-60 |日本| | Hoch | Toothmaster | Hoch Toothmaster |德国| | Hoch | X-Prime | Hoch X-Prime |德国| 规范化设计将分为两个表,如下所示: |制造商|制造商国家| | --------------------- | ---------------------- | |复地|意大利| | Dent-o-Fresh |美国| |小林|日本| | Hoch |德国| |制造商|型号|型号全名| | --------------------- | -------------- | ------------ ---------- | |复地| X-Prime | Forte X-Prime | |复地| Ultraclean | Forte Ultraclean | | Dent-o-Fresh | EZbrush | Dent-o-Fresh EZbrush | |小林| ST-60 |小林ST-60 | | Hoch | Toothmaster | Hoch Toothmaster | | Hoch | X-Prime | Hoch X-Prime | * **第3范式** :表格为第二范式,其所有列都不可传递地依赖于主键。 如果可以从中导出列,则称该列依赖于另一列,例如,年龄可以从生日得到。传递性意味着这种依赖性可能涉及其他列。例如,如果我们考虑三列`PersonID BodyMassIndex IsOverweight` ,则列'IsOverweight'通过'BodyMassIndex'过渡依赖于'personID'。 ##### 例 违反第3范式的设计。 {Tournament,Year}是表格的主键,“Winner出生日期”栏目过渡依赖于它。 |比赛|年|获胜者|获胜者出生日期| | ---------------------- | ------------- | ------------ ---- | ---------------------- | |印第安纳州邀请赛| 1998年| Al Fredrickson | 1975年7月21日| |克利夫兰公开赛1999年| Bob Albertson | 1968年9月28日| |得梅因大师赛1999年| Al Fredrickson | 1975年7月21日| |印第安纳州邀请赛| 1999年| Chip Masterson | 1977年3月14日| 符合第3范式的设计将是: |比赛|年|获胜者| | ---------------------- | ------------- | ------------ ---- | |印第安纳州邀请赛| 1998年| Al Fredrickson | |克利夫兰公开赛1999年| Bob Albertson | |得梅因大师赛1999年| Al Fredrickson | |印第安纳州邀请赛| 1999年| Chip Masterson | |获胜者|出生日期| | ---------------- | ------------------- | | Chip Masterson | 1977年3月14日| | Al Fredrickson | 1975年7月21日| | Bob Albertson | 1968年9月28日| #### 更多信息: * [维基百科上的](https://en.wikipedia.org/wiki/Database_normalization)数据库规范化 * [维基百科](https://en.wikipedia.org/wiki/First_normal_form)上的第一个普通表格 * [维基百科](https://en.wikipedia.org/wiki/Second_normal_form)上的第二个普通表格 * [维基百科](https://en.wikipedia.org/wiki/Third_normal_form)上的第三范式