侧边栏壁纸
博主头像
月伴飞鱼 博主等级

行动起来,活在当下

  • 累计撰写 126 篇文章
  • 累计创建 31 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

什么是数据库范式,为什么要反范式?

月伴飞鱼
2025-03-22 / 0 评论 / 1 点赞 / 10 阅读 / 0 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1. 什么是数据库范式(Database Normalization)?

数据库范式是一种数据库设计规范,目的是减少数据冗余,提高数据一致性,避免更新异常

常见的数据库范式有:

✅ 第一范式(1NF):属性必须具有原子性

  • 要求:每个字段都必须是不可再分的数据项。

  • 示例

    • 不符合 1NF地址 = "北京市朝阳区三里屯某小区"

    • 符合 1NF

      province | city   | district | street  
      ---------|--------|---------|--------
      北京市    | 朝阳区  | 三里屯  | 某小区  

1NF 作用:保证数据的基本格式化,防止数据存储混乱

✅ 第二范式(2NF):所有非主键字段必须完全依赖主键

  • 要求

    • 必须有主键(唯一标识每条记录)。

    • 所有非主键字段必须完全依赖于主键,不能只依赖主键的一部分

  • 不符合 2NF

    student_id (主键) | course_id (主键) | student_name | course_name
    ------------------|----------------|-------------|------------
    1001             | 2001           | 张三        | 数学
    1001             | 2002           | 张三        | 语文
    • student_name 只依赖 student_id,而 course_name 只依赖 course_id,但 student_id + course_id 才是主键,因此违反 2NF。

  • 符合 2NF(拆分表):

    -- 学生表(student)
    student_id (主键) | student_name
    ------------------|-------------
    1001             | 张三
    
    -- 课程表(course)
    course_id (主键) | course_name
    ----------------|-------------
    2001           | 数学
    2002           | 语文
    
    -- 选课表(student_course)
    student_id (主键) | course_id (主键)
    ------------------|----------------
    1001             | 2001
    1001             | 2002

2NF 作用消除数据冗余,避免更新异常。

✅ 第三范式(3NF):非主键字段不能依赖于其他非主键字段

  • 要求

    • 所有非主键字段 只能依赖主键,不能依赖其他非主键字段。

    • 消除传递依赖

  • 不符合 3NF

    employee_id (主键) | employee_name | department_id | department_name
    -------------------|--------------|--------------|---------------
    101               | 张三         | 10           | 技术部
    102               | 李四         | 10           | 技术部
    • department_name 依赖 department_id,而 department_id 又依赖 employee_id,形成传递依赖,不符合 3NF。

  • 符合 3NF(拆分表):

    -- 员工表
    employee_id (主键) | employee_name | department_id (外键)
    -------------------|--------------|-------------------
    101               | 张三         | 10
    102               | 李四         | 10
    
    -- 部门表
    department_id (主键) | department_name
    ------------------|--------------
    10               | 技术部

3NF 作用进一步减少数据冗余,提升数据一致性

2. 为什么要“反范式化”数据库?

严格遵循范式的数据库设计虽然能减少数据冗余,但在查询性能上可能会有问题,特别是涉及多表关联(JOIN)查询时,可能会带来以下问题:

  • JOIN 操作成本高(多个表查询会增加查询时间)。

  • 数据查询复杂(需要关联多个表获取信息)。

  • 大并发场景下性能瓶颈(数据库高负载)。

✅ 反范式化(Denormalization)的概念

  • 遵循范式设计的基础上,为了提升查询性能适当增加冗余数据,减少 JOIN 操作。

3. 反范式化的典型应用场景

✅ 1. 适当增加冗余字段,减少关联查询

例子:电商订单系统

  • 范式化设计(多个表 JOIN 查询)

    -- 用户表
    user_id (主键) | user_name | user_phone
    --------------|----------|-----------
    101          | 张三     | 138xxxx
    
    -- 订单表
    order_id (主键) | user_id (外键) | total_price
    --------------|--------------|------------
    5001         | 101          | 300.00

    查询用户订单时:

    SELECT orders.*, users.user_name, users.user_phone 
    FROM orders 
    JOIN users ON orders.user_id = users.user_id;
    • 问题:每次查询订单都要 JOIN 用户表,增加查询成本。

  • 反范式化优化(减少 JOIN 查询)

    -- 订单表(增加冗余字段)
    order_id (主键) | user_id | user_name | user_phone | total_price
    --------------|--------|----------|-----------|------------
    5001         | 101    | 张三     | 138xxxx   | 300.00
    • 这样查询订单时,无需 JOIN 用户表,提高查询性能

📌 适用场景

  • 读多写少的场景(互联网电商业务)。

  • 高并发查询需求(秒杀、推荐系统)。

✅ 2. 预计算数据,减少实时计算压力

  • 例子:统计用户订单总金额

    -- 原始方式(实时计算)
    SELECT user_id, SUM(total_price) FROM orders GROUP BY user_id;
    • 问题:每次查询都需要 SUM() 聚合计算。

  • 优化方式(预计算)

    • 在用户表中增加 total_spent 字段

      ALTER TABLE users ADD COLUMN total_spent DECIMAL(10,2);
    • 每次订单更新时,同时更新 total_spent

      UPDATE users SET total_spent = total_spent + 300 WHERE user_id = 101;
    • 查询时直接获取 total_spent,避免 SUM() 计算

      SELECT user_name, total_spent FROM users;

📌 适用场景

  • 报表查询、数据统计(避免实时计算压力)

  • 大数据分析(数据仓库优化)

4. 数据库范式 vs 反范式

对比项

范式化

反范式化

目标

减少数据冗余,提高一致性

提升查询性能,减少 JOIN 操作

查询性能

查询慢,需要 JOIN 多表

查询快,减少 JOIN

数据一致性

容易保持一致性

可能需要额外维护数据一致性

存储占用

占用空间较少

需要额外存储冗余数据

适用场景

写多读少,数据一致性要求高

读多写少,查询性能优先

互联网高并发系统通常使用“范式化 + 适度反范式化”策略,在查询性能和数据一致性之间找到平衡。 🚀

公众号.png

1
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
    1. 支付宝打赏

      qrcode alipay
    2. 微信打赏

      qrcode weixin
博主关闭了所有页面的评论