数据库设计三大范式

数据库的三大设计范式

1NF

字段需要是最小的单元,如果字段还可以继续拆分,就不满足第一范式。

比如创建地址字段,填成“中国河南省郑州市中原区”,这样就可以继续划分成“国家”、“省份”,“市区” 字段,所以就不满足第一范式。

范式设计得越详细,对某些实际操作可能会更好,但并非都有好处,需要对项目的实际情况进行设定。

2NF

在满足第一范式的前提下,其他列都必须完全依赖于主键列。如果出现不完全依赖,只可能发生在联合主键的情况下:

1
2
3
4
5
6
7
8
-- 订单表
CREATE TABLE myorder (
product_id INT,
customer_id INT,
product_name VARCHAR(20),
customer_name VARCHAR(20),
PRIMARY KEY (product_id, customer_id)
);

这张订单表中,product_name只依赖 product_id ,而customer_name 只依赖 customer_id。

所以这张表就不满足第二范式:其他列必须完全依赖主键列。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CREATE TABLE myorder (
order_id INT PRIMARY KEY,
product_id INT,
customer_id INT
);

CREATE TABLE product (
id INT PRIMARY KEY,
name VARCHAR(20)
);

CREATE TABLE customer (
id INT PRIMARY KEY,
name VARCHAR(20)
);

拆分后,就可以满足第二范式。

3NF

在满足第二范式的前提下,除了主键列之外,其他列之间不能有传递依赖关系。

1
2
3
4
5
6
CREATE TABLE myorder (
order_id INT PRIMARY KEY,
product_id INT,
customer_id INT,
customer_phone VARCHAR(15)
);

表中 customer_phone 有可能依赖 order_id 和customer_id 两个列,也就不满足第三范式的要求,其他列之间不能有传递依赖关系。

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE myorder (
order_id INT PRIMARY KEY,
product_id INT,
customer_id INT
);

CREATE TABLE customer (
id INT PRIMARY KEY,
name VARCHAR(20),
phone VARCHAR(15)
);

修改后就不存在其他列之间的传递依赖关系,其他列都只依赖于主键列,满足了第三范式的设计!