Skip to content

范式化:1NF、2NF、3NF、BCNF ​

为什么需要范式化 ​

问题:数据冗余导致更新异常

sql
-- 非范式化表
CREATE TABLE orders (
    order_id INT,
    user_name VARCHAR(100),
    user_email VARCHAR(255),
    product VARCHAR(100),
    amount DECIMAL(10,2)
);

问题:

  1. 更新异常:用户改邮箱需要更新多行
  2. 插入异常:无法插入没有订单的用户
  3. 删除异常:删除订单会删除用户信息

第一范式(1NF) ​

定义:每列都是原子值(不可再分)。

违反 1NF ​

sql
CREATE TABLE orders (
    id INT,
    products VARCHAR(255)  -- 'Laptop, Mouse, Keyboard'
);

符合 1NF ​

sql
CREATE TABLE orders (
    id INT,
    product VARCHAR(100)  -- 每行一个产品
);

第二范式(2NF) ​

定义:符合 1NF,且非主属性完全依赖于主键。

违反 2NF ​

sql
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    product_name VARCHAR(100),  -- 只依赖 product_id
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);

符合 2NF ​

sql
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    quantity INT,
    PRIMARY KEY (order_id, product_id)
);

CREATE TABLE products (
    id INT PRIMARY KEY,
    name VARCHAR(100)
);

第三范式(3NF) ​

定义:符合 2NF,且非主属性不依赖于其他非主属性。

违反 3NF ​

sql
CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT,
    user_name VARCHAR(100),  -- 依赖于 user_id
    user_email VARCHAR(255)  -- 依赖于 user_id
);

符合 3NF ​

sql
CREATE TABLE orders (
    id INT PRIMARY KEY,
    user_id INT,
    FOREIGN KEY (user_id) REFERENCES users(id)
);

CREATE TABLE users (
    id INT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(255)
);

BCNF(Boyce-Codd 范式) ​

定义:符合 3NF,且每个决定因素都是候选键。

在大多数情况下,3NF 已经足够。

反范式化 ​

为了提高查询性能,有时故意引入冗余。

场景:频繁查询用户名 ​

sql
-- 范式化(需要 JOIN)
SELECT o.id, u.name FROM orders o JOIN users u ON o.user_id = u.id;

-- 反范式化(直接查询)
SELECT id, user_name FROM orders;

权衡:

  • 优点:查询更快
  • 缺点:更新复杂,数据可能不一致

实际设计原则 ​

  1. 先范式化:消除冗余
  2. 根据需求反范式化:提高性能
  3. 使用视图:隐藏复杂性
  4. 使用触发器:维护冗余数据一致性

练习 ​

  1. 识别违反 1NF 的表
  2. 将违反 2NF 的表范式化
  3. 将违反 3NF 的表范式化
  4. 设计电商系统的表结构(用户、订单、产品)
  5. 设计博客系统的表结构(用户、文章、评论、标签)
  6. 分析何时应该反范式化
  7. 使用视图简化范式化表的查询
  8. 设计完整的项目数据库(至少 5 个表)

完成练习后,打开本章答案页核对。

本章小结 ​

第七章学习了数据定义与约束:

  • DDL 操作:CREATE、ALTER、DROP
  • 数据类型:整数、字符串、日期时间、JSON
  • 约束:PRIMARY KEY、FOREIGN KEY、UNIQUE、CHECK
  • 范式化:1NF、2NF、3NF、BCNF

至此,SQL 七章全部完成!

回到第七章概览 · 返回SQL 学习路线

用心记录每一步成长