软考-软件设计师:数据库技术基础-关系数据库的规范化:三范式,BCNF(BC范式) 作者:马育民 • 2025-05-01 07:50 • 阅读:10002 # 规范化 关系数据库设计的方法之一就是设计 **满足适当范式** 的模式,通常可以通过判断分解后的模式达到几范式来评价模式规范化的程度。 范式有: - **1NF** - **2NF** - **3NF** - **BCNF** - 4NF - 5NF [](https://www.malaoshi.top/upload/0/0/1GW12loAI4GU.png) # 范式一 属性值不可再 如下图: `地区`、`户型` 都 **可再分**,而且分开后更加便于 **查询** [](https://www.malaoshi.top/upload/0/0/1EF3t6EwB8JD.png) ### 如何满足范式 需要拆分字段 ### 好处 - 数据一致性:避免同一个字段中存储多个含义不同的信息 - 查询方便性:如果字段可再分,SQL 就无法有效查询和处理 - 更新安全性:减少更新异常,避免部分数据被遗漏或错误修改 ### 缺点 关系模式FIRST和函数依赖集F如下: ``` FIRST(Sno,Sname,Status,City,Pno,Qty) F={ Sno—→Sname,Sno→Status,Status→City,(Sno,Pno)→Qty} ``` 下图是供应商和提供零件的信息: - Sno是主键 - Sname是供应商名 - Status是状态 - City是城市 - Pno:零件编号 - Qty:零件数量??? 关系: - Sno能确定Sname、Status - Status能确定City - Sno和pno能确定Qty [](https://www.malaoshi.top/upload/0/0/1GW12msC2LGg.png) 从上图可以看出,每个属性都不可再分,满足范式一 但存在下面4个问题: - 冗余度大。例如,每个供应者的 Sno、Sname、Status、City要与其供应的零件的种类一样多。 - 引起修改操作的不一致性。例如,供应者S1从“天津”搬到“上海”,若稍不注意,就会使一些数据被修改,另一些数据没有被修改,导致数据修改的不一致性。 - 插入异常。关系模式FRIST的主码为 Sno、Pno,按照关系模式实体完整性规定,主码不能取空值或部分取空值。这样,当某个供应者的某些信息未提供时(如Pno),则不能进行插入操作,这就是所谓的插入异常。 - 删除异常。若供应商 S4的P2零件销售完了,并且以后不再销售P2零件,那么应删除该元组。这样,在基本关系FIRST找不到S4,而 S4又是客观存在的。 正因为上述4个原因,所以要对模式进行分解,并引入了范式二。 # 范式二 在范式一的基础上,消除 **非主属性** 对候选键的 **部分依赖** **理解:**一个表中只能保存一个实体的数据 上图中,关系模式FRIST的主码为 Sno、Pno,但非主属性Sname、Status依赖 Sno,不依赖Pno,这就违背范式二 ### 如何满足范式 需要拆分关系,将FIRST关系分解为: - FIRST1(Sno,Sname,Status,City),非主属性Sname,Status,City 依赖 Sno,符合范式二 - FIRST2(Sno,Pno,Qty),非主属性 `Qty` 依赖 `Sno,Pno`,符合范式二 # 范式三 在范式二的基础上,消除 **非主属性** 对候选键的 **传递依赖** FIRST1 不满足范式三,因为 `Sno → Status`,`Status → City`,存在着非主属性 `City` 传递依赖于码 `Sno` ### 如何满足范式 需要拆分关系,将FIRST1关系分解为: - FIRST11 (Sno, Sname, Status),非主属性 Sname, Status 直接依赖 Sno - FIRST12 (Status, City),非主属性 City 直接依赖 Status # BC范式 在范式三的基础上,消除 **主属性** 对候选键的 **部分依赖** 和 **传递依赖** ### 例子:违法部分依赖 例:关系模式STJ(S,T,J)中,S表示学生,T表示老师,J表示课程。每一老师只教一门课程。每门课程有若干老师,某一学生选定某门课,就对应一个固定老师。 [](https://www.malaoshi.top/upload/0/0/1GW12nhvRusn.png) |T |J |S | | ------------ | ------------ | ------------ | |张老师 |数学 |A同学 | |王老师 |数学 |B同学 | |赵老师 |数学 |C同学 | |钱老师 |语文 |A同学 | |孙老师 |语文 |B同学 | |李老师 |英语 |C同学 | |周老师 |英语 |B同学 | 候选码:ST、SJ 主属性:S、T、J 由于J只依赖T,不依赖 S,违反BC范式 ### 如何满足范式 需要拆分关系: - 关系1(S、J) - 关系2(T,J) # 总结 [](https://www.malaoshi.top/upload/0/0/1GW12ntnZnHR.png) # 题 某公司数据库中的元件关系模式为 `P(元件号,元件名称,供应商,供应商所在地,库存量)`, 函数依赖集F如下所示: `F={元件号 → 元件名称,(元件号,供应商)→ 库存量,供应商 → 供应商所在地}` 元件关系的主键为(),该关系存在冗余以及插入异常和删除异常等问题。为了解决这一问题需要将元件关系分解),分解后的关系模式可以达到) A、元件号,元件名称 B、元件号,供应商 C、元件号,供应商所在地 D、供应商,供应商所在地 A、元件1(元件号,元件名称,库存量)、元件2(供应商, 供应商所在地) B、元件1(元件号,元件名称)、元件2(供应商,供应商 所在地,库存量) C、元件1(元件号,元件名称)、元件2(元件号,供应商, 库存量)、元件3(供应商,供应商所在地) D、元件1(元件号,元件名称)、元件2(元件号,库存 量)、元件3(供应商,供应商所在地)、元件4(供应商所 在地,库存量) A、1NF B、2NF C、3NF D、4NF ### 第一问答案 B 1. `入度为0` 的属性:元件号,供应商 2. 元件号,供应商能够推导出其他所有属性,所以是候选码,也是主键 ### 第二问答案 C 从 `F={元件号 → 元件名称,(元件号,供应商)→ 库存量,供应商 → 供应商所在地}` 可知: - `元件名称` 部分依赖 `元件号`,违反范式二 - `供应商所在地` 部分依赖 `供应商`,违反范式二 拆分关系: - 关系1(元件号,供应商, 库存量),`库存量` 直接依赖 `(元件号,供应商)` - 关系2(元件号 , 元件名称),`元件名称` 直接依赖 `元件号` - 关系3(供应商 , 供应商所在地),`供应商所在地` 直接依赖 `供应商` ### 第三问答案 C **提示:**已经达到BC范式 原文出处:http://malaoshi.top/show_1GW12pM1wNvQ.html