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

【转】数据库范式(1NF 2NF 3NF BCNF)

范式判断流程图

 

1. 四种范式之间关系 

        

2.第二范式、第三范式、BCNF区别:

2NF:非主键列和主键列之间,是完全依赖于主键,还是依赖于主键的一部分(只依赖某个主键);

3NF:非主键列之间,不存在依赖,只直接依赖主键。

BCNF:主键列之间,不存在依赖。

 

一般关系数据库都满足第一范式,先确定是几个主键属性。

第一范式:列不可再分

第二范式:非主键属性全部依赖于主键属性

第三范式:非主键属性之间无依赖关系

第四范式:主键属性之间无依赖关系

3. 第一范式:列不可分。每一列都是不可分割的基本数据项。

a.反例:

StudyNo

Name  

Sex  

Contact

20040901     

john        

Male     

Email:kkkk@ee.net,phone:222456

20040902     

mary        

famale   

email:kkk@fff.net phone:123455

contact字段可以再分,不符合第一范式。

b.  正解:

StudyNo

Name  

Sex  

Email

Phone

20040901     

john        

Male     

Email:kkkk@ee.net

222456

20040902     

mary        

famale   

email:kkk@fff.net

123455

4.第二范式:在第一范式基础上,对于多关键字表,非主属性不能部分依赖于主键(eg:只依赖某个主键);对于单关键字表,不存在部分依赖情况(只依赖一个主键,全部依赖),全符合。

better eg:

订单明细表:【OrderDetail】(OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName)。
因为我们知道在一个订单中可以订购多种产品,所以单单一个 OrderID 是不足以成为主键的,主键应该是(OrderID,ProductID)。显而易见 Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID。所以 OrderDetail 表不符合 2NF。不符合 2NF 的设计容易产生冗余数据。
可以把【OrderDetail】表拆分为【OrderDetail】(OrderID,ProductID,Discount,Quantity)和【Product】(ProductID,UnitPrice,ProductName)来消除原订单表中UnitPrice,ProductName多次重复的情况。

 a.反例:

StudyNo

Name  

Sex  

Email

Phone

ClassNo

ClassAddress

20040901     

john        

Male     

Email:kkkk@ee.net

222456

200401

#12A

20040902     

mary        

famale   

email:kkk@fff.net

123455

200402

#8A

主键是studyNo和classNo。classAddress部分依赖主键classNo,需要变为两个表。

b.  正解:

学生表

StudyNo

Name  

Sex  

Email

Phone

20040901     

john        

Male     

Email:kkkk@ee.net

222456

20040902     

mary        

famale   

email:kkk@fff.net

123455

教室表

ClassNo

ClassAddress

200401

#12A

200402

#8A

c. 消除数据冗余和增、删、改异常。

(1) 数据冗余:

    同一门课程由n个学生选修,"学分"就重复n-1次;同一个学生选修了m门课程,姓名和年龄就重复了m-1次。

(2) 更新异常:

    若调整了某门课程的学分,数据表中所有行的"学分"值都要更新,否则会出现同一门课程学分不同的情况。

(3) 插入异常:

    假设要开设一门新的课程,暂时还没有人选修。这样,由于还没有"学号"关键字,课程名称和学分也无法记录入数据库。

(4) 删除异常:

    假设一批学生已经完成课程的选修,这些选修记录就应该从数据库表中删除。但是,与此同时,课程名称和学分信息也被删除了。很显然,这也会导致插入异常。

5.第三范式:在第二范式基础上,非关键字段对任一主键不能传递函数依赖。非主键列必须直接依赖于主键,不能传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。总之,非主键列之间不能存在依赖关系。

better eg:

订单表【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID)。
其中 OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity 等非主键列都完全依赖于主键(OrderID),所以符合 2NF。不过问题是 CustomerName,CustomerAddr,CustomerCity 直接依赖的是 CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF。
通过拆分【Order】为【Order】(OrderID,OrderDate,CustomerID)和【Customer】(CustomerID,CustomerName,CustomerAddr,CustomerCity)从而达到 3NF。

 

a. 反例:

StudyNo

Name  

Sex  

Email

Phone

BounsLevel

Bouns

20040901     

john        

Male     

Email:kkkk@ee.net

222456

优秀

¥1200

20040902     

mary        

famale   

email:kkk@fff.net

123455

¥800

主键是StudyNo,只有一个主键StudyNo,而且符合第二范式。但是非主键列bounsLevel和bouns存在依赖关系。

b.正解:

学生表

StudyNo

Name  

Sex  

Email

Phone

BounsNo

20040901     

john        

Male     

Email:kkkk@ee.net

222456

1

20040902     

mary        

famale   

email:kkk@fff.net

123455

2

奖学金等级表

BounsNo

BounsLevel

Bouns

1

优秀

¥1200

2

¥800

c.消除数据冗余和增、删、改异常。

6.鲍依斯-科得范式(BCNF):在第三范式的基础上,数据库表中如果不存在任何字段对任一候选关键字段的传递函数依赖则符合第三范式。即不存在关键字段决定关键字段的情况。

a.反例:StoreHouseManager

StoreHouseID(仓库ID)

GoodsID(商品ID)

ManagerID(管理员ID)

GoodsNum(商品数量)

001

20130104

1

200

主键是

(仓库ID, 商品ID) →(管理员ID, 数量) 或

(管理员ID, 商品ID) → (仓库ID, 数量),

(仓库ID, 商品ID)和(管理员ID,商品ID)都是StorehouseManage的候选关键字,表中的唯一非关键字段为数量

满足第三范式。但是,存在关键字段决定关键字段情况。

(仓库ID) → (管理员ID)

(管理员ID) → (仓库ID)

b.正解:

仓库管理表

StoreHouseID(仓库ID)

GoodsID(商品ID)

GoodsNum(商品数量)

001

20130104

200

仓库表

StoreHouseID(仓库ID)

ManagerID(管理员ID)

001

1

c. 消除增、删、改异常。

(1) 删除异常:

当仓库被清空后,所有"存储物品ID"和"数量"信息被删除的同时,"仓库ID"和"管理员ID"信息也被删除了。

(2) 插入异常:

当仓库没有存储任何物品时,无法给仓库分配管理员。

(3) 更新异常:

如果仓库换了管理员,则表中所有行的管理员ID都要修改。 

应用的范式等级越高,则表越多。表多会带来很多问题:
1 查询时要连接多个表,增加了查询的复杂度
2 查询时需要连接多个表,降低了数据库查询性能
而现在的情况,磁盘空间成本基本可以忽略不计,所以数据冗余所造成的问题也并不是应用数据库范式的理由。
因此,并不是应用的范式越高越好,要看实际情况而定。第三范式已经很大程度上减少了数据冗余,并且减少了造成插入异常,更新异常,和删除异常了。所以大多数情况应用到第三范式已经足够,在一定情况下第二范式也是可以的。

转载于:https://www.cnblogs.com/shawWey/p/8960746.html

相关文章:

  • 父元素与子元素之间的margin-top问题(css hack)
  • 20180427积累
  • 关于sqoop --split-by 及 -m的理解
  • 20165301陈潭飞2017-2018-2 20165301 实验三《Java面向对象程序设计》实验报告
  • 往idea中导入已有的web项目
  • webpakc4.0移除了 CommonsChunkPlugin 组建
  • 判断Python输入是否为数字、字符(包括正则表达式)
  • 《C》指针
  • HTML第二课——css【2】
  • taobao_api项目进展
  • Java类库和常用类库介绍
  • 微信小程序开发:学习笔记[2]——WXML模板
  • linux常用命令:tr 命令
  • bzoj 4574: [Zjoi2016]线段树
  • 数据结构-绪论
  • 「前端」从UglifyJSPlugin强制开启css压缩探究webpack插件运行机制
  • 【Amaple教程】5. 插件
  • Django 博客开发教程 8 - 博客文章详情页
  • E-HPC支持多队列管理和自动伸缩
  • ES6系列(二)变量的解构赋值
  • hadoop集群管理系统搭建规划说明
  • IDEA 插件开发入门教程
  • Netty 4.1 源代码学习:线程模型
  • Selenium实战教程系列(二)---元素定位
  • spring boot 整合mybatis 无法输出sql的问题
  • 动态魔术使用DBMS_SQL
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 前端面试总结(at, md)
  • 入手阿里云新服务器的部署NODE
  • 微信小程序--------语音识别(前端自己也能玩)
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • #stm32驱动外设模块总结w5500模块
  • (2)(2.10) LTM telemetry
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (Redis使用系列) Springboot 在redis中使用BloomFilter布隆过滤器机制 六
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (强烈推荐)移动端音视频从零到上手(上)
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • .net操作Excel出错解决
  • .NET精简框架的“无法找到资源程序集”异常释疑
  • .Net语言中的StringBuilder:入门到精通
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [BT]小迪安全2023学习笔记(第15天:PHP开发-登录验证)
  • [C#]手把手教你打造Socket的TCP通讯连接(一)
  • [C++] 如何使用Visual Studio 2022 + QT6创建桌面应用
  • [CISCN2021 Quals]upload(PNG-IDAT块嵌入马)
  • [EFI]MSI GF63 Thin 9SCXR电脑 Hackintosh 黑苹果efi引导文件
  • [GN] 后端接口已经写好 初次布局前端需要的操作(例)
  • [i.MX]飞思卡尔IMX6处理器的GPIO-IOMUX_PAD说明
  • [IDF]聪明的小羊
  • [iphone-cocos2d]关于Loading的若干处理和讨论
  • [Java基础] Java中List.remove报错UnsupportedOperationException
  • [JS]JavaScript 注释 输入输出语句