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

数据库的规范化设计方法---3种范式

第一范式(1NF):确保表中的每个字段都是不可分割的基本数据项。
第二范式(2NF):在满足1NF的基础上,确保非主属性完全依赖于主键。
第三范式(3NF):在满足2NF的基础上,确保非主属性不传递依赖于主键。

使用 StudentCourse 表作为基础,来解释第一范式(1NF)。

第一范式 (1NF) 的核心要求:
确保表中的每一个单元格(字段值)都包含单一、不可再分割的基本数据项。换句话说,表中的每一列都必须是原子性的,不能包含多个值或复合值。
回顾之前的 StudentCourse 表:

StudentID (学号)StudentName (姓名)StudentDepartment (系别)CourseID (课程号)CourseName (课程名)Professor (教授)
1001张三计算机系CS101数据结构李教授
1001张三计算机系CS201数据库原理王教授
1002李四电子系EE101电路基础赵教授
1003王五计算机系CS101数据结构李教授
1003王五计算机系CS301操作系统刘教授

分析 StudentCourse 表是否满足 1NF:
现在我们来逐一检查这个表中的每一列,看看它们是否都满足原子性(不可分割)的要求:

  1. StudentID (学号): 例如 “1001”。这是一个单一的数值,不能再分割成更小的有意义的部分(比如不能把它分成 ‘1’, ‘0’, ‘0’, ‘1’ 并认为每个都有独立意义)。满足 1NF。
  2. StudentName (姓名): 例如 “张三”。虽然姓名可以拆分成姓氏和名字(“张” 和 “三”),但在数据库设计中,通常将整个姓名视为一个不可分割的字符串来处理,特别是当我们不需要单独查询姓氏或名字时。如果业务上需要单独处理姓氏和名字,才需要拆分成两列。通常认为满足 1NF。
  3. StudentDepartment (系别): 例如 “计算机系”。这是一个单一的文本值,表示一个系别。满足 1NF。
  4. CourseID (课程号): 例如 “CS101”。这是一个单一的标识符,不能再分割。满足 1NF。
  5. CourseName (课程名): 例如 “数据结构”。这是一个单一的文本值。满足 1NF。
  6. Professor (教授): 例如 “李教授”。这是一个单一的文本值。满足 1NF。
    结论: 在这个例子中,StudentCourse 表的每一列都只包含单一、不可分割的数据项。因此,这个表满足第一范式 (1NF)
    一个不满足 1NF 的例子:
    假设我们有一个 StudentInfo 表,其中存储了学生的联系电话,但允许一个学生有多个电话:
StudentIDStudentNamePhoneNumbers
1001张三13812345678, 13987654321
1002李四13700001111
1003王五13611112222, 13833334444, 13955556666

在这个表中,PhoneNumbers 列包含了多个电话号码,用逗号分隔。这违反了 1NF,因为该列的单元格包含了多个基本数据项(多个电话号码)。
要使其满足 1NF,我们需要将每个电话号码放在单独的一行,或者创建一个单独的 StudentPhone 表。
希望这个例子能帮助你理解第一范式的要求!

好的,我们来通过具体的例子来解释“完全依赖”和“不传递依赖”这两个概念,它们是第二范式(2NF)和第三范式(3NF)的核心。
假设我们有一个存储学生选修课程信息的表:
表:StudentCourse (学生选课表)

StudentID (学号)StudentName (姓名)StudentDepartment (系别)CourseID (课程号)CourseName (课程名)Professor (教授)
1001张三计算机系CS101数据结构李教授
1001张三计算机系CS201数据库原理王教授
1002李四电子系EE101电路基础赵教授
1003王五计算机系CS101数据结构李教授
1003王五计算机系CS301操作系统刘教授

这个表的主键是 (StudentID, CourseID),因为一个学生可以选多门课,一门课可以被多个学生选,只有同时知道学号和课程号才能唯一确定一行记录。

2. 第二范式 (2NF) - 完全依赖 (Full Dependency)

定义: 在满足第一范式(1NF)的基础上,非主属性必须完全依赖于整个主键,而不仅仅是主键的一部分。
问题: 如果主键是由多个属性组成的(复合主键),我们需要检查每个非主属性是否依赖于所有主键属性。
在 StudentCourse 表中:

  • 主键: (StudentID, CourseID)
  • 非主属性: StudentName, StudentDepartment, CourseName, Professor
    现在我们检查每个非主属性是否完全依赖于 (StudentID, CourseID)
  1. StudentName (姓名): 姓名是由学号 StudentID 决定的,和选了哪门课 CourseID 无关。所以 StudentName 依赖于 StudentID,而不是 (StudentID, CourseID)。这叫部分依赖 (Partial Dependency)
  2. StudentDepartment (系别): 系别也是由学号 StudentID 决定的,和课程号 CourseID 无关。所以 StudentDepartment 依赖于 StudentID,而不是 (StudentID, CourseID)。这也是部分依赖
  3. CourseName (课程名): 课程名是由课程号 CourseID 决定的,和学生的学号 StudentID 无关。所以 CourseName 依赖于 CourseID,而不是 (StudentID, CourseID)。这同样是部分依赖
  4. Professor (教授): 教授通常是由课程号 CourseID 决定的(假设一门课只有一个固定教授),和学生的学号 StudentID 无关。所以 Professor 依赖于 CourseID,而不是 (StudentID, CourseID)。这也是部分依赖
    结论: StudentCourse 表不满足 2NF,因为存在非主属性(StudentName, StudentDepartment, CourseName, Professor)部分依赖于主键 (StudentID, CourseID) 的子集(要么只依赖 StudentID,要么只依赖 CourseID)。
    如何修正 (分解): 我们需要将表分解,使得每个表的非主属性都完全依赖于该表的主键。
  • Student (学生表): 主键 StudentID
    StudentID (学号)StudentName (姓名)StudentDepartment (系别)
    1001张三计算机系
    1002李四电子系
    1003王五计算机系
  • Course (课程表): 主键 CourseID
    CourseID (课程号)CourseName (课程名)Professor (教授)
    CS101数据结构李教授
    CS201数据库原理王教授
    EE101电路基础赵教授
    CS301操作系统刘教授
  • StudentSC (学生选课关系表): 主键 (StudentID, CourseID)
    StudentID (学号)CourseID (课程号)
    1001CS101
    1001CS201
    1002EE101
    1003CS101
    1003CS301

现在检查这些新表:

  • Student 表的主键是 StudentID,所有非主属性 (StudentName, StudentDepartment) 都完全依赖于 StudentID
  • Course 表的主键是 CourseID,所有非主属性 (CourseName, Professor) 都完全依赖于 CourseID
  • StudentSC 表的主键是 (StudentID, CourseID),它没有其他非主属性,所以自然满足。
    这些分解后的表都满足了 2NF。

3. 第三范式 (3NF) - 不传递依赖 (No Transitive Dependency)

定义: 在满足第二范式(2NF)的基础上,非主属性必须不传递依赖于主键。也就是说,非主属性不能依赖于另一个非主属性。
问题: 我们需要检查是否存在“主键 -> 非主属性 A -> 非主属性 B”这样的依赖链条,其中 B 就是传递依赖于主键。
在修正后的 Student 表中:

  • 主键: StudentID
  • 非主属性: StudentName, StudentDepartment
    检查是否存在传递依赖:
  • StudentID -> StudentDepartment (学号决定系别)
  • StudentDepartment -> ? 这个系别 (StudentDepartment) 是否又决定了其他的非主属性?在我们的 Student 表中,系别只决定了它自己,没有决定其他非主属性 (StudentName)。所以没有传递依赖。
    在修正后的 Course 表中:
  • 主键: CourseID
  • 非主属性: CourseName, Professor
    检查是否存在传递依赖:
  • CourseID -> Professor (课程号决定教授)
  • Professor -> ? 这个教授 (Professor) 是否又决定了其他的非主属性?在我们的 Course 表中,教授只决定了它自己,没有决定其他非主属性 (CourseName)。所以没有传递依赖。
    假设我们有一个不满足 3NF 的表:
    表:StudentDept (学生系别表 - 假设大学有系主任)
StudentID (学号)StudentName (姓名)StudentDepartment (系别)DepartmentHead (系主任)
1001张三计算机系陈主任
1002李四电子系吴主任
1003王五计算机系陈主任
  • 主键: StudentID (假设学号唯一)
  • 非主属性: StudentName, StudentDepartment, DepartmentHead
    检查依赖关系:
  1. StudentID -> StudentName (满足)
  2. StudentID -> StudentDepartment (满足)
  3. StudentID -> DepartmentHead ? 不完全是。学号本身不直接决定系主任。但是,我们可以通过学号找到系别 (StudentID -> StudentDepartment),然后通过系别找到系主任 (StudentDepartment -> DepartmentHead)。所以,DepartmentHead传递依赖于主键 StudentID 的。StudentID -> StudentDepartment -> DepartmentHead
    结论: StudentDept 表不满足 3NF,因为存在非主属性 DepartmentHead 传递依赖于主键 StudentID
    如何修正 (分解): 我们需要将传递依赖的非主属性分离出来。
  • Student (学生表): 主键 StudentID
  • StudentID (学号)StudentName (姓名)StudentDepartment (系别)
    1001张三计算机系
    1002李四电子系
    1003王五计算机系
  • Department (系别表): 主键 StudentDepartment (可以用系别名称或系编号作为主键,这里简化用名称)
    StudentDepartment (系别)DepartmentHead (系主任)
    计算机系陈主任
    电子系吴主任

现在检查这些新表:

  • Student 表满足 3NF。
  • Department 表的主键是 StudentDepartment,唯一的非主属性 DepartmentHead 完全依赖于它,并且没有其他非主属性可以依赖,所以也满足 3NF。

总结:

  • 完全依赖 (2NF): 非主属性不能只依赖于复合主键的“一部分”。它们必须依赖于整个主键。
  • 不传递依赖 (3NF): 非主属性不能依赖于另一个非主属性。它们必须直接依赖于主键,不能通过中间的非主属性间接依赖。
    通过满足这些范式,可以减少数据冗余,避免数据更新异常(插入、删除、修改异常)。

相关文章:

  • scss additionalData Can‘t find stylesheet to import
  • WebXR教学 07 项目5 贪吃蛇小游戏
  • 阿里巴巴开源移动端多模态LLM工具——MNN
  • 北京市工程技术人才职称评价基本标准条件解读
  • 力扣HOT100之二叉树:98. 验证二叉搜索树
  • JAVA的常见API文档(上)
  • AtCoder AT_abc406_c [ABC406C] ~
  • 蓝牙耳机什么牌子好?倍思值得冲不?
  • Typecho博客为文章添加AI摘要功能(Handsome主题优化版)
  • AGI大模型(20):混合检索之rank_bm25库来实现词法搜索
  • Redis配置与优化:提升NoSQL数据库性能的关键策略
  • 【AI算法工程师面试指北】ResNet为什么用avgpool结构?
  • 超长文本能取代RAG吗
  • 图像超分-CVPR2022-Multi-scale Attention Network for Single Image Super-Resolution
  • 黑马k8s(十)
  • 打造文本差异对比工具 TextDiffX:从想法到实现的完整过程
  • 企业级电商数据对接:1688 商品详情 API 接口开发与优化实践
  • 信道编码技术介绍
  • 数值分析知识重构
  • 我与 CodeBuddy 携手打造 FontFlow 字体预览工坊
  • 从良渚到三星堆:一江水串起了5000年的文明对话
  • 当“诈骗诱饵”盯上短剧
  • 以色列媒体:哈马斯愿意释放部分人员换取两个月停火
  • “80后”萍乡市安源区区长邱伟,拟任县(区)委书记
  • 信俗与共:清代新疆回疆儒释道庙宇的中华政教
  • 因港而兴,“长江黄金水道”上的宜宾故事