–1. 第一范式 1NF
数据表中的所有字段都是不可分割的原子值。
create table student2(
id int primary key,
name varchar(20),
address varchar(30)
);
insert into student2 values (1,'张三','江苏省南京市栖霞区仙林大道163号');
insert into student2 values (2,'李四','江苏省南京市栖霞区中山大道100号');
insert into student2 values (3,'王五','江苏省南京市栖霞区天赋大道50号');
+----+------+---------------------------------+
| id | name | address |
+----+------+---------------------------------+
| 1 | 张三 | 江苏省南京市栖霞区仙林大道163号 |
| 2 | 李四 | 江苏省南京市栖霞区中山大道100号 |
| 3 | 王五 | 江苏省南京市栖霞区天赋大道50号 |
+----+------+---------------------------------+
– 字段值还可以继续拆分的是不满足第一范式,例如address字段。
重新设计一个表: 假设details 是不可再继续拆分的列
create table student3(
id int primary key,
name varchar(20),
province varchar(30),
city varchar(30),
details varchar(30)
);
insert into student3 values(1,'张三','江苏省','南京市','栖霞区仙林大道163号');
insert into student3 values (2,'李四','江苏省','南京市','栖霞区中山大道100号');
insert into student3 values (3,'王五','江苏省','南京市','栖霞区天赋大道50号');
+----+------+----------+--------+---------------------+
| id | name | province | city | details |
+----+------+----------+--------+---------------------+
| 1 | 张三 | 江苏省 | 南京市 | 栖霞区仙林大道163号 |
| 2 | 李四 | 江苏省 | 南京市 | 栖霞区中山大道100号 |
| 3 | 王五 | 江苏省 | 南京市 | 栖霞区天赋大道50号 |
+----+------+----------+--------+---------------------+
– 范式,设计的越详细,对于某些实际操作可能更好,但也会带来一些麻烦。
–第二范式 2NF
–必须在满足第一范式的前提,第二范式要求每列(除主键外)都必须完全依赖于主键。
– 如果出现不完全依赖,只可能发生在联合主键的情况下。
举例:
订单表
create table myorder(
product_id int,
customer_id int,
product_name varchar(20),
customer_name varchar(20),
primary key (product_id,customer_id)
);
上表的主键是商品id和消费者id,那么一个问题是商品名只依赖于商品id,消费者名只依赖于消费者id。
除主键外的其他列,只依赖于主键的部分字段,那么不满足第二范式。
不满足第二范式的表,通常会造成数据冗余:
例如,一个消费者对同一间商品买了n次,因此产生了n个订单数据。那么此时相同的商品名和消费者名被重复出现n次。
那么如何满足呢?
拆表:
下述的三个表,每个除主键的其他列都完全依赖于主键,满足第二范式。
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)
);
3、第三范式 3NF
必须先满足第二范式。除开主键列的其它列之间不能有传递依赖关系。
例如下表,尽管商品id,消费者id和消费者电话号 都完全依赖于主键订单id,但是消费者手机可能还依赖于消费者的id,这是传递依赖。
create table myorder(
order_id int primary key,
product_id int,
customer_id int,
customer_phone varchar(15)
);
应该将phone字段移动到customer表中,让其完全依赖主键。