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

MySql三大范式

数据库的三大范式(Normal Forms,简称 NF)是用于设计关系型数据库的规则,它们的目的是消除数据冗余,确保数据的一致性和完整性。下面是对前三个范式的详细解释:

第一范式(1NF)—— 原子性

  • 要求:每个字段(列)的值必须是原子的,不可再分。

  • 意思:每个表中的每一列必须包含最基本的数据单元,也就是说,列中的每一个值都应该是不可再分的单一数据项。

    例子:假设有一个“学生”表,其中有一个列为“电话”,如果这个“电话”列中存储了多个电话号码(例如,123-4567, 234-5678),则违反了第一范式。为了满足第一范式,应该将每个电话号码单独存储到一个独立的记录中。

    不符合1NF的示例

    学号 | 姓名   | 电话
    ------------------------
    1001 | 张三   | 123-4567, 234-5678
    1002 | 李四   | 345-6789
    

    符合1NF的示例

    学号 | 姓名   | 电话
    ------------------------
    1001 | 张三   | 123-4567
    1001 | 张三   | 234-5678
    1002 | 李四   | 345-6789
    

第二范式(2NF)—— 消除部分依赖

  • 要求:在满足 1NF 的基础上,所有非主属性必须完全依赖于主键(即没有部分依赖)。

  • 意思:第二范式要求消除表中某些字段(非主键字段)对主键的部分依赖关系,特别是在主键是复合主键(由多个列组成)时。具体来说,不能有某些字段仅依赖于主键的一部分。

    例子:假设有一个表用于存储学生成绩信息,其中包含学生的学号、课程号和成绩。学号和课程号一起组成复合主键。如果课程名称是通过课程号来确定的,那么课程名称依赖于课程号,而不是整个复合主键,这就是部分依赖。

    不符合2NF的示例

    学号 | 课程号 | 课程名称 | 成绩
    --------------------------------
    1001 | 101    | 数学     | 90
    1001 | 102    | 英语     | 85
    1002 | 101    | 数学     | 88
    

    符合2NF的示例

    • 将“课程”表单独提取,消除部分依赖:
    学号 | 课程号 | 成绩
    ---------------------
    1001 | 101    | 90
    1001 | 102    | 85
    1002 | 101    | 88
    
    • 新的“课程”表:
    课程号 | 课程名称
    ----------------
    101    | 数学
    102    | 英语
    

第三范式(3NF)—— 消除传递依赖

  • 要求:在满足 2NF 的基础上,消除所有非主属性对主键的传递依赖。

  • 意思:第三范式要求非主属性只能直接依赖于主键,而不能间接依赖。即如果存在通过其他非主属性间接依赖主键的情况,就应该将这种依赖关系分解到不同的表中。

    例子:假设有一个“学生”表,其中包括学生的学号、学生所在的学院和学院的地址。如果学院地址只依赖于学院,而不是学生,这就是一种传递依赖,应该将地址信息单独存储在另一个表中。

    不符合3NF的示例

    学号 | 姓名   | 学院   | 学院地址
    -----------------------------
    1001 | 张三   | 计算机 | 北京
    1002 | 李四   | 数学   | 上海
    

    符合3NF的示例

    • 将“学院”信息单独存储,消除传递依赖:
    学号 | 姓名   | 学院
    --------------------
    1001 | 张三   | 计算机
    1002 | 李四   | 数学
    
    • 新的“学院”表:
    学院   | 学院地址
    ----------------
    计算机 | 北京
    数学   | 上海
    

总结:

  • 1NF:要求字段原子化,每列存储单一数据。
  • 2NF:在 1NF 基础上,消除非主键字段对主键的部分依赖。
  • 3NF:在 2NF 基础上,消除非主键字段对主键的传递依赖。

通常来说,随着范式的增加,数据库的冗余会减少,但复杂度和查询的性能可能会受到影响。因此,在实际应用中,有时也会根据需求选择适当的范式,不一定严格要求达到 3NF。

在关系型数据库设计中,部分依赖完全依赖传递依赖 是影响范式(尤其是第二范式和第三范式)实现的关键概念。下面是这三者的详细解释:

1. 部分依赖(Partial Dependency)

定义:部分依赖是指一个非主键属性仅依赖于复合主键的一部分,而不是依赖于整个复合主键。

  • 复合主键:指一个主键由两个或更多列组成的主键。
  • 部分依赖:如果某个非主键列只依赖于复合主键中的其中一列,而不是完全依赖于整个复合主键,那就是部分依赖。

例子

假设有一个表 StudentCourse,包含以下字段:

  • StudentID(学号)
  • CourseID(课程号)
  • CourseName(课程名称)
  • Grade(成绩)

假设主键是由 StudentIDCourseID 组成的复合主键。

StudentIDCourseIDCourseNameGrade
1001101MathA
1001102EnglishB
1002101MathC

这里,课程名称(CourseName) 只依赖于 课程号(CourseID),而不是依赖于整个复合主键(StudentID + CourseID)。所以,CourseName 依赖于主键的一部分(CourseID),这是一个部分依赖。

如何消除:可以将表拆分,将课程信息提取到单独的表中,避免部分依赖。

2. 完全依赖(Full Dependency)

定义:完全依赖是指一个非主键属性完全依赖于整个主键(在复合主键的情况下),而不是仅依赖于主键的一部分。

  • 如果某个非主键属性依赖于复合主键的全部列,而不是依赖于其中的一部分,那么这就是完全依赖。

例子

继续上述 StudentCourse 表:

  • Grade(成绩)显然依赖于整个复合主键(StudentID + CourseID)。如果我们删除 StudentIDCourseIDGrade 将无法确定。

    因此,成绩(Grade) 依赖于 整个复合主键,这叫做完全依赖。

如何处理:完全依赖本身并不需要特别拆分,但它是第二范式的基础要求。表中所有的非主键字段都应该完全依赖于主键。

3. 传递依赖(Transitive Dependency)

定义:传递依赖是指某个非主键属性依赖于另一个非主键属性,而这个非主键属性又依赖于主键。

  • 如果 A → BB → C,那么 A → C 就是传递依赖。也就是说,非主键属性 C 依赖于非主键属性 B,而 B 又依赖于主键 A。

例子

假设有一个表 Student,包含以下字段:

  • StudentID(学号)
  • StudentName(姓名)
  • Department(系别)
  • DepartmentHead(系主任)
StudentIDStudentNameDepartmentDepartmentHead
1001AliceCSDr. Smith
1002BobMathDr. Johnson
  • DepartmentHead(系主任)依赖于 Department(系别),而 Department 又依赖于 StudentID(学号)。因此,DepartmentHead 间接依赖于 StudentID,这是一个传递依赖。

如何消除:为了消除传递依赖,可以将 DepartmentDepartmentHead 信息分离到一个新的表中,避免它们依赖于非主键属性。

完全依赖 vs 传递依赖:
  • 完全依赖:是指一个非主键属性完全依赖于主键(或复合主键)。
  • 传递依赖:是指非主键属性依赖于其他非主键属性,形成链条,从而间接依赖于主键。

总结:

  • 部分依赖:非主键属性依赖于复合主键的一部分,而不是整个复合主键。
  • 完全依赖:非主键属性依赖于整个主键(或复合主键)。
  • 传递依赖:非主键属性依赖于另一个非主键属性,形成间接依赖。

2NF(第二范式)的目标是消除部分依赖,而 3NF(第三范式)的目标是消除传递依赖。


http://www.kler.cn/a/556474.html

相关文章:

  • VSCode本地python包“无法解析导入”
  • 网络安全-攻击流程-用户层
  • C++:线程当中的锁专题
  • Ollama Docker 镜像部署
  • java(spring boot)实现向deepseek/GPT等模型的api发送请求/多轮对话(附源码)
  • 数据库-SQLite
  • 为什么docker 容器有的没有PORTS
  • 长尾关键词优化三步法:提升SEO搜索排名实战
  • Linux基础 -- 中断子系统之级联中断
  • 【问题】Qt c++ 因编码问题解析json失败
  • 多环境日志管理:使用Logback与Logstash集成实现高效日志处理
  • 《炒股养家心法.pdf》 kimi总结
  • 腾讯云开源Deepseek-V3与R1大模型API免费使用 + Chatbox本地化部署指南:从零到一的AI探索之旅
  • stm32单片机个人学习笔记16(SPI通信协议)
  • 论文解读 | AAAI'25 Cobra:多模态扩展的大型语言模型,以实现高效推理
  • ZLG嵌入式笔记 | 为什么你的网卡工作会不正常?(中)
  • Mysql测试连接失败
  • 【Day45 LeetCode】图论问题 Ⅲ
  • 为什么要用 const 和 let,而不是 var?
  • 使用 Docker 部署 Apache Spark 集群教程