一、第一范式
数据表中的所有字段都是不可分割的原子值
设计的越详细,对于某些实际情况更有利,一般根据实际情况来看,并非所有情况都有利。
例如下表不满足第一范式吗,此表把地名街道写到一起,是可拆分的:
create table student2(
id int primary key,
name varchar(20),
address varchar(30)
);
insert into student2 values(1,'batman1','USA NewYork Gotham001');
insert into student2 values(2,'batman2','USA NewYork Gotham002');
insert into student2 values(3,'batman3','USA NewYork Gotham003');
更改为下表则满足第一范式,地名街道不可再拆分:
create table student3(
id int primary key,
name varchar(20),
country varchar(30),
province varchar(30),
city varchar(30),
details varchar(30)
);
insert into student3 values(1,'batman1','USA','NewYork','Gotham','001');
insert into student3 values(2,'batman2','USA','NewYork','Gotham','002');
insert into student3 values(3,'batman3','USA','NewYork','Gotham','003');
二、第二范式
满足第一范式的前提下,第二范式要求,除主键外的每一列都必须完全依赖主键。
比如下表不满足第二范式,其主键为 product_id 和 customer_id,但是 product_name 只依赖于 product_id ,customer_name 只依赖于 customer_id ,所以此表除主键以外的其他列只依赖于主键的部分字段,则不满足第二范式。
create table myorder(
product_id int,
customer_id int,
product_name varchar(20),
customer_name varchar(20),
primary key(product_id,customer_id)
);
此时需要进行拆表:
分成三个表之后,就满足了第二范式的设计。
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)
);
三、第三范式
必须先满足第二范式,除开主键列的其他列之间不能有传递依赖关系。
下表不满足第三范式,因为 customer_id 和 customer_phone 之间有依赖关系,应该把 customer_phone 放到 customer 表里面。
create table myorder(
order_id int primary key,
product_id int,
customer_id int,
customer_phone varchar(20)
);
更改成如下形式,则满足第三范式:
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(20)
);