当前位置: 首页 > news >正文

数据库三范式入门教程

数据库设计是构建高效、稳定系统的核心环节,而**三范式(3NF)**是关系型数据库设计的经典准则,旨在通过消除数据冗余、避免更新异常,确保数据的完整性和一致性。本教程将通过通俗语言和实例,帮助你快速掌握三范式的核心思想和应用方法。


一、三范式概述

1. 为什么需要范式?

  • 问题场景:假设设计一个学生选课表,包含字段:学生ID、姓名、年龄、课程ID、课程名、成绩

    • 冗余:同一学生选修多门课程时,姓名年龄会重复存储。
    • 更新异常:修改学生年龄需更新多行数据,容易遗漏。
    • 插入异常:新增课程但无学生选修时,无法单独存储课程信息。
    • 删除异常:删除某学生的选课记录时,可能意外删除其个人信息。
  • 范式目标:通过规范化设计,将数据拆分为多个表,减少冗余,避免上述问题。

2. 三范式的层级关系

  • 第一范式(1NF):基础要求,确保数据原子性。
  • 第二范式(2NF):在1NF基础上,消除部分依赖(针对复合主键)。
  • 第三范式(3NF):在2NF基础上,消除传递依赖(非主键字段间无依赖)。

关系图

原始表 → 1NF → 2NF → 3NF

二、第一范式(1NF):确保数据原子性

1. 定义

  • 每个字段的值必须是不可分割的原子值(无重复组、无嵌套结构)。
  • 例如:电话字段不能存储多个号码(如"123-456,789-012"),应拆分为多行或单独表。

2. 反例与修正

  • 反例:订单表包含商品字段,值为"苹果,香蕉"
  • 问题:无法直接查询“购买了苹果的订单”。
  • 修正:拆分为订单ID、商品ID,关联商品表。

3. 操作步骤

  1. 检查所有字段是否为单一值。
  2. 将复合值拆分为多行或关联表。

示例
原始表(不满足1NF):

学生ID姓名选修课程
001张三数学,物理

修正后(满足1NF):

学生ID姓名课程ID课程名
001张三101数学
001张三102物理

三、第二范式(2NF):消除部分依赖

1. 定义

  • 满足1NF,且非主键字段必须完全依赖于整个主键(针对复合主键)。
  • 若主键为单字段,则自动满足2NF。

2. 关键概念

  • 完全依赖:非主键字段的值必须由整个主键决定,而非部分。
  • 部分依赖:非主键字段仅依赖主键的一部分。

3. 反例与修正

  • 场景:学生选课表,主键为(学生ID, 课程ID),包含字段:
    学生ID、姓名、课程ID、课程名、成绩
  • 问题
    • 姓名仅依赖学生ID(部分依赖)。
    • 课程名仅依赖课程ID(部分依赖)。
  • 修正:拆分为三张表:
    • 学生表学生ID、姓名
    • 课程表课程ID、课程名
    • 选课表学生ID、课程ID、成绩

4. 操作步骤

  1. 确认主键是否为复合键。
  2. 找出仅依赖主键部分的字段。
  3. 将这些字段拆分到关联表中。

四、第三范式(3NF):消除传递依赖

1. 定义

  • 满足2NF,且非主键字段之间不能存在依赖关系(即非主键字段必须直接依赖主键)。

2. 关键概念

  • 传递依赖:若A→BB→C,则C传递依赖于A(通过B)。
  • 直接依赖C应直接依赖A,而非通过其他字段。

3. 反例与修正

  • 场景:学生表包含字段:学生ID、姓名、系别、系主任
  • 问题
    • 系主任依赖系别,而系别依赖学生ID
    • 修改系主任时需更新所有该系学生记录,易出错。
  • 修正:拆分为两张表:
    • 学生表学生ID、姓名、系别
    • 系别表系别、系主任

4. 操作步骤

  1. 检查非主键字段间是否存在依赖。
  2. 将传递依赖的字段拆分到新表中。

五、三范式综合应用案例

案例:图书馆管理系统

原始表设计(问题表)
图书ID书名作者出版社出版日期借阅人ID借阅人姓名借阅日期
问题
  1. 冗余:同一作者的多本书会重复存储作者名。
  2. 更新异常:修改作者姓名需更新多行。
  3. 传递依赖借阅人姓名依赖借阅人ID,而借阅人ID依赖图书ID
规范化设计(3NF)
  1. 图书表(满足1NF+2NF+3NF):

    图书ID书名作者ID出版社ID出版日期
  2. 作者表(消除冗余):

    作者ID作者姓名
  3. 出版社表(消除冗余):

    出版社ID出版社名
  4. 借阅记录表(消除传递依赖):

    借阅ID图书ID借阅人ID借阅日期
  5. 借阅人表(独立存储借阅人信息):

    借阅人ID借阅人姓名

六、范式选择的权衡

1. 范式越高越好?

  • 优点:减少冗余、避免更新异常。
  • 缺点:表数量增加,查询需多表关联,可能影响性能。

2. 实际应用建议

  • 一般场景:遵循3NF即可满足需求。
  • 特殊场景
    • 读多写少:可适当反规范化(如合并表)以提升查询速度。
    • 数据仓库:通常采用星型模型或雪花模型,不完全遵循3NF。

七、总结与练习

1. 核心总结

  • 1NF:字段原子性,无重复组。
  • 2NF:消除部分依赖(针对复合主键)。
  • 3NF:消除传递依赖(非主键字段间无依赖)。

2. 练习题

设计一个电商系统的订单表,包含字段:
订单ID、客户ID、客户姓名、商品ID、商品名、单价、数量、总价、下单时间
要求

  1. 指出当前设计的问题。
  2. 将其规范化为3NF,画出表结构。

参考答案

  1. 问题
    • 冗余:客户姓名、商品名重复存储。
    • 传递依赖:总价依赖单价和数量,而单价依赖商品ID。
  2. 3NF设计
    • 订单表:订单ID、客户ID、下单时间
    • 客户表:客户ID、客户姓名
    • 商品表:商品ID、商品名、单价
    • 订单明细表:订单ID、商品ID、数量(总价可通过计算得出,无需存储)。
http://www.dtcms.com/a/326803.html

相关文章:

  • Windows11 PowerShell CMD
  • Ascend DrivingSDK 中的 modulated_deform_conv2d(一)
  • GESP2023年9月认证C++一级( 第三部分编程题(1)买文具)
  • MATLAB实现遗传算法求解路网路由问题
  • PTE之路--03文
  • 【08-神经网络介绍】
  • 北京-4年功能测试2年空窗-报培训班学测开-第七十三天-投递简历-[特殊字符][特殊字符]
  • Linux驱动学习day27天(USB驱动理论部分)
  • SSR-code 项目复刻与3D模型生成实现
  • nomachine的安装和使用
  • 华清远见25072班C语言学习day6
  • 操作系统1.5:操作系统引导
  • 101. 孤岛的总面积
  • 下一代防火墙组网
  • 晓知识: 动态代理与静态代理的区别
  • Android模块化架构深度解析:从设计到实践
  • 强联通分量(重制版)
  • 环境配置-拉取NVIDIA Docker镜像时出现401Unauthorized错误
  • 数据填报是什么?数据填报工具有哪些?
  • 黑马程序员mysql基础篇笔记
  • 自定义switch with icon
  • 使用Pytest进行接口自动化测试(三)
  • 深入了解torch框架
  • 数据类型 string
  • 算法题——IP地址分类与子网掩码
  • CobaltStrike安装和使用教程
  • Cobalt Strike的搭建和使用
  • JDK21虚拟线程和 Golang1.24协程的比较
  • STM32——system文件夹
  • Empire--安装、使用