数据库规范化,数据库范式,和规范化实例

文章目录

  • 什么是数据库规范化
  • 术语
  • 数据库的3个范式介绍
    • 第一范式
    • 第二范式
    • 第三范式
  • 根据数据库范式优化数据库结构
    • 满足第一范式
    • 满足第二范式
    • 满足第三范式
  • 参考链接

什么是数据库规范化

维基百科的定义如下:

数据库规范化,又称数据库或资料库的正规化、标准化,是数据库设计中的一系列原理和技术,以减少数据库中数据冗余,增进数据的一致性

数据库范式是埃德加·科德设计出来的。在1970年代初,他定义了第一范式(First normal form)第二范式(Second normal form),和**第三范式(Third normal form)**的概念。数据库范式可以理解成一系列的规范或者规则,为了实现数据库规范化的目标,我们需要按照这些范式的规则来优化数据库。

关于这些范式的规则我会在文章后续部分说明。

现在数据库设计最多满足第三范式,普遍认为范式过高,虽然具有对数据关系更好的约束性,但也导致数据关系表增加而令数据库IO更易繁忙,原来交由数据库处理的关系约束现更多在数据库使用程序中完成。

因此,本文数据库的优化实例只做到第三范式。

术语

为了更准确,简洁地定义各个范式的规则,我们需要知道一些术语的含义。对于有些术语来说,我不打算写出它标准化的定义,这是因为标准化定义十分晦涩。对于这样的术语,俺直接给出相应的例子,理解它代表的是什么东西就行。

  • 关系(relation):数据库中的「表」
  • 元组(tuple):数据库表中的「行」
  • 属性(attribute ):数据库表中的「列」
  • 超键(superkey):数据库关系中能够唯一标示元组(即,行)的属性集合。超键例子
  • 候选键(candidate key):不含有多余属性的超键。也就是说,这个超键属性集合的任何一个真子集(proper subset),都不能唯一标示元组。候选键有时也被称为主键(primary key)。一个表中的候选键可能不唯一
  • 主属性(prime attributes):候选键中包含的属性
  • 非主属性(non-prime attribute):任何一个候选键都没有包含的属性

下面俺给出一个关于上面部分术语的例子。这个例子来源于 yangyang17

假如有以下学生和教师两个表:

Student(student_no, student_name, student_age, student_sex, student_credit, teacher_no)

Teacher(teacher_no, teacher_name, teacher_salary)

超键:Student表中可根据学生编号(student_no),或身份证号(student_credit),或(学生编号,姓名)(student_no,student_name),或(学生编号,身份证号)(student_no,student_credit)等来唯一确定是哪一个学生,因此这些组合都可以作为此表的超键

候选键:候选键属于超键,且是最小的超键,即如果去掉超键组合中任意一个属性就不再是超键了。Student表中候选键为学生编号(student_no),身份证号(student_credit)

主键:主键是候选键中的一个,可人为决定,通常会选择编号来作为表的主键。

数据库的3个范式介绍

在这个小节,俺会用具体的例子来说明每个范式所包含的规则。

第一范式

第一范式的定义:

First normal form (1NF) is a property of a relation in a relational database. A relation is in first normal form if and only if the domain of each attribute contains only atomic (indivisible) values, and the value of each attribute contains only a single value from that domain.

第一范式必须符合下面3个标准:

  1. Eliminate repeating groups in individual tables
  2. Create a separate table for each set of related data
  3. Identify each set of related data with a primary key

下表是一个不符合第一范式的 例子,Telephone Number 列并不是原子的,它可以继续拆分下去。

数据库规范化,数据库范式,和规范化实例_第1张图片

解决上面问题的一个直观方法是多引入一列,如下图所示。但是,这种方法仍然有3个问题。第一、下表仍然包含 “repeating group”,即包含概念上相似的属性,电话号。第二、这样做会引入没有意义的顺序。比如,为什么 555-861-2025 放到 Telephone Number1 列,而不是放到 Telephone Number2 列呢?第三、当一个客户再多一个号码时,会修改表结构,增加一列。

数据库规范化,数据库范式,和规范化实例_第2张图片

下面的表结构可以解决上面的问题。由于第一范式要求能唯一地标识出一个元组,而现在 Customer ID 重复了,所以我们需要 Telephone Number 与 Customer ID 的组合才能标识出一个元组。

数据库规范化,数据库范式,和规范化实例_第3张图片

另一种设计方案如下所示,它是使用两张表。

数据库规范化,数据库范式,和规范化实例_第4张图片

第二范式

第二范式必须满足下面2个条件:

  1. be in first normal form (1NF)
  2. not have any non-prime attribute that is dependent on any proper subset of any candidate key of the relation

第2个条件翻译过来的含义为:任何一个非主属性不能依赖于候选键属性集合的真子集属性。

下表的每个值都是单一值,所以它符合第一正规化。但它不符合第二范式。这是因为,一个元件 ID 和供应商 ID 合在一起组成一个主键,但供应商的名称和住址却只和供应商 ID 有关(部分依赖)。

数据库规范化,数据库范式,和规范化实例_第5张图片

把上表的结构改成下面的结构,就符合第二范式了。

数据库规范化,数据库范式,和规范化实例_第6张图片

第三范式

第三范式必须满足下面2个条件:

  1. 符合第二范式
  2. all the attributes in a table are determined only by the candidate keys of that relation and not by any non-prime attributes

也就是说,符合第三范式的表结构不应该包含 transitive dependency. 即,非主属性之间不能有依赖关系。比如下表的结构就包含 transitive dependency,因为非主属性 Author 决定了另一个非主属性 Author Nationality.

数据库规范化,数据库范式,和规范化实例_第7张图片

根据数据库范式优化数据库结构

在这个小节中,俺会给出一个数据库表的初始结构,它不符合数据库范式。我会一步一步地改进它,直到让它满足数据库的第三范式。下表是一个不符合范式的初始结构:

数据库规范化,数据库范式,和规范化实例_第8张图片

满足第一范式

初始表中的 Subject 列并不是原子的,一种方式是将其拆分成3个列。如下所示:

数据库规范化,数据库范式,和规范化实例_第9张图片

如果用上面的方式,当某本书增加一个 subject 时,就需要更改表结构,增加一列。因此,用下面的方式修改表,使其符合第一范式会更好一些。

数据库规范化,数据库范式,和规范化实例_第10张图片

拆分成上面的结构以后,我们需要把 Subject 表与 Book 表连接起来。由于一本书可能对应多个 subject,而一个 subject 也可能对就多本书,这是一个典型的 多对多 关系。因此我们需要新建一张关联表:

数据库规范化,数据库范式,和规范化实例_第11张图片

满足第二范式

从下表可以看出,{Book} 和 {Book Type} 是一个候选键。但是,只有一个 price 属性是由这2个主属性共同影响的(这是合理的,因为同样一本书,电子版与精装的价格肯定是不同的)。其它的属性都是只由 Book 这个主属性影响的。因此,这不符合第二范式。

数据库规范化,数据库范式,和规范化实例_第12张图片

按照下面的方式修改以后,就符合第二范式了。

数据库规范化,数据库范式,和规范化实例_第13张图片

满足第三范式

由于下表中的非主属性 Genre ID 决定了另一个非主属性 Genre Name,即存在 transitive dependency,所以它并不符合第三范式。

数据库规范化,数据库范式,和规范化实例_第14张图片

改成下面的结构以后,就符合第三范式了。至此,我们从一个不符合任何范式的初始表结构,一步一步地改成了现在这个结构。
数据库规范化,数据库范式,和规范化实例_第15张图片

参考链接

数据库规范化

Database normalization

第二范式

你可能感兴趣的:(数据库)