一、第一范式 1NF

 数据表中的所有字段都是不可分割的原子项。

mysql> create table student2(
    -> id int,
    -> name varchar(20),
    -> address varchar(30)
    -> );

向表中插入数据:

mysql> INSERT INTO student2 VALUES(1,'Rose','SiChuanChengDuROAD311');
mysql> INSERT INTO student2 VALUES(2,'Mary','SiChuanChengDuROAD321');
mysql> INSERT INTO student2 VALUES(3,'Bob','SiChuanChengDuROAD8974');

mysql> select * from student2;
+------+------+------------------------+
| id   | name | address                |
+------+------+------------------------+
|    1 | Rose | SiChuanChengDuROAD311  |
|    2 | Mary | SiChuanChengDuROAD321  |
|    3 | Bob  | SiChuanChengDuROAD8974 |
+------+------+------------------------+

字段值还可以继续拆分的,就不满足第一范式。比如address就还可以在拆分出country,city等更细的划分。

范式设计的越详细,对于某些实际操作可能更好,但是不一定都好,要依据具体应用场景而定。

二、第二范式 2NF

必须是满足第一范式的前提下,第二范式要求,除主键外的每一列都必须完全依赖于主键。

如果要出现不完全依赖,只可能发生在联合主键的情况下。

创建一张订单表:

mysql> create table my_order(
    -> product_id int,
    -> customer_id int,
    -> product_name varchar(20),
    -> customer_name varchar(20),
    -> primary key(product_id,customer_id)
    -> );

product_id与customer_id共同组成主键。

有什么问题?

customer_name只与customer_id有关,与product_name及product_id无关。同理,product_name只与product_id有关,与customer无关。

这就叫做:除主键之外的列(eg.product_name)不完全依赖于主键(eg.customer_id)。

也就是:这些主键之外的其他列(eg.product_name),只依赖于主键的部分字段(eg.product_id)。

即:不满足第二范式。

如何做才能让它满足第二范式?拆表!

mysql> create table my_order(
    -> order_id int primary key,
    -> customer_id int,
    -> product_id int
    -> );

mysql> create table product(
    -> id int primary key,
    -> name varchar(20)
    -> );

mysql> create table customer(
    -> id int primary key,
    -> name varchar(20)
    -> );

此上三个表中,除主键之外的列是完全依赖于主键的。

为什么要分表?因为分表之后让其满足第二范式设计。

三、第三范式 3NF

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

mysql> create table my_order1(
    -> order_id int primary key,
    -> customer_id int,
    -> product_id int,
    -> customer_tel varchar(15)
    -> );

在上述这张表中,通过order_id可以知道customer_id,也可以知道customer_tel,但是通过customer_id没准也可以知道customer_tel,所以,这张表中出现了关系冗余。

修改之后:

mysql> create table my_order1(
    -> order_id int primary key,
    -> customer_id int,
    -> product_id int
    -> );

mysql> create table customer1(
    -> customer_id int primary key,
    -> customer_name varchar(20),
    -> customer_tel varchar(15)
    -> );
12-29 16:15