ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

简单说明1NF,2NF,3NF

简单说明1NF,2NF,3NF 数据库范式是关系型数据库设计中的一种理论用于消除数据冗余和更新异常提高数据的一致性和完整性。根据定义主要有以下四种范式第一范式1NF、第二范式2NF、第三范式3NF以及第四范式4NF。第一范式1NF在符合第一范式的关系模式中每个属性都是不可再分的最小单元也被称为原子性。简单来说就是数据表中的每一列每个字段都必须具备原子性不能进一步分解。第二范式2NF在满足第一范式的基础上消除了非主属性对码的部分函数依赖。也就是说表中的所有列都必须依赖于主键而不能有任何一列与主键没有关系。这样的设计能确保一个表只描述一件事情。第三范式3NF必须先满足第二范式要求表中的每一列只与主键直接相关而不是间接相关。换句话说表中的每一列只能依赖于主键。假设有一个学生表Student包含以下字段学号StudentID主键唯一标识每个学生。姓名Name学生的姓名。年龄Age学生的年龄。班级Class学生所在的班级。班主任Teacher负责该班级的班主任。根据上述定义可以对表进行范式分析第一范式1NF表中的每一列都是不可再分的最小单元满足原子性要求。因此Student表已经符合第一范式。第二范式2NF消除非主属性对码的部分函数依赖。在这个例子中StudentID是主键其他列都依赖于主键。但是存在一个问题Class和Teacher列都依赖于同一个非主属性Class和Teacher都属于同一个实体“班级”这违反了第二范式的要求。为了解决这个问题可以将表拆分为两个表一个学生表Student和一个班级表Class。学生表中只包含与学生相关的信息班级表中包含与班级相关的信息。这样每个表只描述一件事情满足第二范式的要求。第三范式3NF必须先满足第二范式要求表中的每一列只与主键直接相关而不是间接相关。在拆分后的表结构中学生表中的每个列都只依赖于主键StudentID而班级表中的每个列也只依赖于主键ClassID。因此拆分后的表结构满足第三范式的要求。一个违反第一范式1NF的例子学生IDStudentID主键唯一标识每个学生。学生的姓名和年龄Name, Age学生的姓名和年龄。在这个例子中“学生的姓名和年龄”是一个可以进一步分解的数据项它包含了两个原子数据项“学生的姓名”和“学生的年龄”。然而在表中这两个数据项却被合并成了一个列这就违反了第一范式的规定因为根据定义每一列都应该是原子的、不可再分的。为了符合第一范式应该将这个表拆分为两个表一个用于存储学生的姓名另一个用于存储学生的年龄。一个违反第二范式2NF的例子学生IDStudentID主键唯一标识每个学生。学生的姓名Name学生的姓名。学生的成绩Score学生的成绩。在这个例子中“学生的成绩”依赖于主键“学生ID”但是“学生的成绩”本身又包含了多个属性例如数学成绩、语文成绩、英语成绩等。这就违反了第二范式的规定因为根据定义非主属性必须完全依赖于主键而不能存在只依赖于部分主键的情况。为了符合第二范式应该将这个表拆分为两个表一个用于存储学生的基本信息包括学生ID和姓名另一个用于存储学生的成绩信息包括学生ID和各个科目的成绩。一个违反第三范式3NF的例子学生IDStudentID主键唯一标识每个学生。学生的姓名Name学生的姓名。学生的成绩Score学生的成绩。学生的班级Class学生所在的班级。班级的班主任Teacher负责该班级的班主任。在这个例子中“学生的班级”和“班级的班主任”都依赖于主键“学生ID”但是它们本身又包含了其他属性。这就违反了第三范式的规定因为根据定义非主属性必须直接依赖于主键而不能存在传递依赖的情况。为了符合第三范式应该将这个表拆分为三个表一个用于存储学生的基本信息包括学生ID和姓名一个用于存储学生的成绩信息包括学生ID和各个科目的成绩另一个用于存储班级信息包括班级ID、班级名称和班主任。这样每个表只描述一件事情并且每个非主属性都直接依赖于主键。下面我用现实生活中的数据表例子一步步讲清楚1NF、2NF、3NF、BCNF、4NF的区别。不讲公式只讲“为什么不行 怎么改”。一、1NF第一范式列不可再分✅ 核心要求每个字段都必须是“最小不可再分”的原子值❌ 不符合 1NF 的例子学生表错误学号姓名电话1张三1380000,1390000❌ 问题“电话”字段里存了多个值无法按单个电话查询、索引、更新✅ 符合 1NF 的写法学号姓名电话1张三13800001张三1390000✅ 每个字段都是单一值二、2NF第二范式消除“部分函数依赖”✅ 核心要求非主键字段必须依赖“整个主键”而不是主键的一部分只和联合主键有关❌ 不符合 2NF 的例子选课表学号课程号学生姓名课程名称成绩1C01张三数据库90主键(学号, 课程号)❌ 问题学生姓名只依赖学号课程名称只依赖课程号它们不依赖整个主键✅ 符合 2NF 的拆分学生表学号学生姓名1张三课程表课程号课程名称C01数据库选课表学号课程号成绩1C0190✅ 非主键字段完全依赖主键三、3NF第三范式消除“传递依赖”✅ 核心要求非主键字段不能依赖另一个非主键字段❌ 不符合 3NF 的例子学生表学号姓名学院学院地址1张三计算机教学楼A主键学号❌ 问题学院地址依赖学院学院依赖学号存在传递依赖✅ 符合 3NF 的拆分学生表学号姓名学院1张三计算机学院表学院学院地址计算机教学楼A✅ 非主键字段只依赖主键四、BCNF巴斯-科德范式更严格的 3NF✅ 核心要求每一个决定因素都必须是候选键 解决“主键之外的字段也能决定别的字段”的问题❌ 不符合 BCNF 的例子课程安排表教师课程教材王老师数据库教材A王老师数据结构教材B假设规则一个教师只教一门课教师 → 课程一门课只能用一本教材课程 → 教材候选键(教师, 教材)❌ 问题教师 → 课程但教师不是候选键的一部分决定因素✅ 符合 BCNF 的拆分教师课程表教师课程王老师数据库课程教材表课程教材数据库教材A✅ 所有决定因素都是候选键五、4NF第四范式消除多值依赖✅ 核心要求一个表里不能有多个“独立多值事实”❌ 不符合 4NF 的例子学生兴趣表学号爱好技能1篮球Python1游泳Java假设爱好和技能互不影响但它们放在同一张表❌ 问题产生组合爆炸数据冗余✅ 符合 4NF 的拆分学生爱好表学号爱好1篮球1游泳学生技能表学号技能1Python1Java✅ 每个表只描述一个多值事实六、一句话总结重点范式解决什么问题1NF字段不能再拆2NF比如有两个主键一些字段值依赖其中一个主键另一些字段值依赖另一个主键3NF比如有一个主键存在传递依赖的情况BCNF决定因素必须是候选键见后面备注4NF一个表有多类数据组合爆炸数据冗余候选键 与 主属性这两个概念是理解 2NF/3NF/BCNF 的基础用一句话先记住候选键 能唯一标识一行数据的最小字段组合主属性 出现在任何一个候选键里的字段下面用具体表讲清楚。一、候选键Candidate Key定义能唯一确定表中每一行且不含多余字段最小性的字段或字段组合。两个条件唯一性给定这些字段的值只能找到一行最小性去掉其中任何一个字段就不能唯一确定了例子学生表学号身份证号姓名年龄1001310xxx张三201002320xxx李四21问哪些能当候选键学号能唯一确定一行且单个字段没法再删 → ✅ 候选键身份证号也能唯一确定一行 → ✅ 候选键姓名可能重名 → ❌ 不是(学号, 姓名)能唯一确定但删掉姓名还剩学号也能唯一确定 → 不满足最小性 → ❌ 不是候选键所以这张表有两个候选键学号和身份证号。再看联合候选键的例子选课表学号课程号成绩1001C01901001C02851002C0188学号单独 → 不能唯一确定1001 出现两次❌课程号单独 → 不能唯一确定C01 出现两次❌(学号, 课程号)→ 能唯一确定且两个都不能删 → ✅ 候选键这就是联合候选键复合候选键。二、主键Primary Key从多个候选键里挑一个当主键用来日常标识行。上面的学生表学号和身份证号都是候选键我们通常选学号当主键身份证号就叫备用键Alternate Key。主键一定是候选键候选键不一定是主键没被选中的那些。三、主属性Prime Attribute定义只要出现在任何一个候选键里的字段都叫主属性否则叫非主属性。注意是任何一个候选键不是主键。例子学生表候选键是学号、身份证号字段是否主属性原因学号✅ 主属性在候选键里身份证号✅ 主属性也在候选键里姓名❌ 非主属性不在任何候选键里年龄❌ 非主属性不在任何候选键里选课表候选键是(学号, 课程号)字段是否主属性学号✅ 主属性课程号✅ 主属性成绩❌ 非主属性四、为什么这两个概念重要回到前面讲范式时的关键区别2NF非主属性不能只依赖联合主键的一部分3NF非主属性不能传递依赖候选键BCNF连主属性也不能被非候选键决定3NF 和 BCNF 的分界线就在主属性上范式管不管主属性1NF不管2NF只管非主属性3NF只管非主属性BCNF主属性也管之前学生选导师的例子学生课程老师张三数据库李老师候选键是(学生, 课程)和(学生, 老师)所以学生、课程、老师全都是主属性。依赖老师 → 课程里课程是主属性却被非候选键的老师决定 → 3NF 不管它只管非主属性但 BCNF 要管 → 所以违反 BCNF。五、一张图总结关系所有字段 ├── 主属性出现在某个候选键里 │ ├── 主键字段选中的那个候选键 │ └── 备用键字段其他候选键 └── 非主属性不在任何候选键里口诀候选键能唯一标识 不能少字段主键候选键里挑一个主属性沾了候选键的边就算非主属性跟候选键没关系
返回列表