【数据库】Mysql数据库的三大范式1NF 2NF 3NF

时间:2021-04-18 01:16:12

文章目录

简述

  • 1NF:字段不可拆分
  • 2NF:有主键,非主键字段依赖主键
  • 3NF:非主键字段不能互相依赖

1NF

属性不可分割,即每个属性都是不可分割的原子项(实体中的属性即表中的列)。只要字段值还可以继续拆分,就不满足第一范式。

例如:数据表中存在address地址该属性,若每条数据的值为“xx省xx市”,则该属性即可分割属性,分为“xx省”、“xx市”两个属性。

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

2NF

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

例如某订单表为:

-- 订单表
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_idcustomer_name 只依赖于 customer_idproduct_namecustomer_id 是没有关系的,customer_nameproduct_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)
);

拆分之后,myorder 表中的 product_idcustomer_id 完全依赖于 order_id 主键,而 productcustomer 表中的其他字段又完全依赖于主键,即满足第二范式。

3NF

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

CREATE TABLE myorder (
    order_id INT PRIMARY KEY,
    product_id INT,
    customer_id INT,
    customer_phone VARCHAR(20)
);

表中的 customer_phone 有也许依赖于 customer_id ,也就不满足第三范式:其他列之间不能有传递依赖关系

改进:

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)
);

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

面试相关

如何通俗理解三个范式?

  • 第一范式是对原子性的约束,要求属性具有原子性,不可拆分。
  • 第二范式是对记录的唯一性约束,要求具有唯一标识,即实体的唯一性
  • 第三范式是对字段冗余性的约束,即任何字段不能由其他字段派生出来

范式设计的优缺点?

  • 优点:减少数据冗余
  • 缺点:查询时需要关联多个表,更难进行索引优化

参考:
https://www.bilibili.com/video/BV1Vt411z7wy