数据库原理学习笔记(二)数据库范式
范式可以理解成在设计数据表时的规范级别,常见的范式有
- 第一范式(1NF)
- 第二范式(2NF)
- 第三范式(3NF)
- BC范式(BCNF)
第一范式
要满足第一范式,要求数据表的每个属性无法再分,也就是需要满足原子性。可以把“不可再分”理解成无法用一个单独的值表示,比如说“系”这个属性,平时常说的“计算机系”,“化学系”实际上指的是系名,而系的管理者被称为系主任,所以对于“系”这个属性,只能通过将它拆分成若干属性的组合(系名,系主任,…)来表示。
所以如果数据表中某个属性指的是类似上面的“系”这样的属性,就不满足第一范式,解决办法就是将这个可以再分的属性继续分解
CREATE TABLE student ( id INT NOT NULL AUTO_INCREMENT, /* 学号 */name VARCHAR(20) NOT NULL, /* 姓名 */faculty /* 系,应该用什么类型表示?它包括系名,系主任等若干子属性 */...
);
可以看到,如果某个属性可以继续分解,那么是无法在创建数据表时表示它的,所以一般可以成功创建的数据表(前提是语义正确)都是符合第一范式的要求的
CREATE TABLE student ( student_id INT, student_name VARCHAR(20), faculty_name VARCHAR(20), faculty_boss VARCHAR(20), PRIMARY KEY (student_id)
);
第二范式
判断一个数据表是否满足第二范式,可以观察是否存在非主属性对于码的部分函数依赖,方法是
- 找出数据表中所有的码
- 根据第一步找出的码,找出所有主属性
- 在数据表中的所有属性中去除主属性,得到非主属性
- 查看是否存在某个非主属性对于码的部分函数依赖
如果存在部分函数依赖,则这个数据表就不符合第二范式,解决方法就是模式分解,将违反第二范式的属性单独提出创建一个新表或者分解表使得该表的码只包含一个属性
对于部分函数依赖,码至少要包含两个属性,所以上面的student表是满足第二范式的,下面考虑另一个表student_course,它描述了学生的选课信息,包含
- 学生信息
- 课程名,课程成绩
- 学生所在系信息
CREATE TABLE student_course ( student_id INT NOT NULL, student_name VARCHAR(20), course_name VARCHAR(20), course_score INT, faculty_name VARCHAR(20), faculty_boss VARCHAR(20), PRIMARY KEY (student_id, course_name)
);
由于课程成绩必须通过确定是哪个学生的哪门课来获取,所以这个表的主码(主键)是(student_id, course_name),现在来一步步分析这个表是否符合第二范式
分析student_course表
第一步,找出数据表中的所有的码。由上面的分析可得这个表只有唯一的码(student_id, course_name)
第二步,找出所有的主属性。码中的每个属性都是主属性,所以主属性包括student_id和course_name
第三步,找出所有的非主属性。除去主属性的都是非主属性,所以非主属性包括student_name, course_score, faculty_name, faculty_boss
第四步,判断非主属性是否对于码存在部分函数依赖
每个属性之间的依赖关系
- student_id可以推导出student_name,所以student_name完全依赖于student_id
- student_id可以推导出faculty_name和faculty_boss,所以二者完全依赖于student_id
- (student_id, course_name)可以推导出course_score,所以course_score完全依赖于(student_id, course_name)
由上述三个关系可以分析出部分依赖关系
- 由于faculty_name完全函数依赖于student_id,所以faculty_name部分函数依赖于(student_id, course_name)
- 由于faculty_boss完全函数依赖于student_id,所以faculty_name部分函数依赖于(student_id, course_name)
- …
所以这个表不满足第二范式,可以通过模式分解解决这一问题,比如将课程相关的信息提出去单独作为一个表,这样student_course表的码就只剩一个属性student_id了,自然不存在部分函数依赖
CREATE TABLE student ( student_id INT NOT NULL, student_name VARCHAR(20), faculty_name VARCHAR(20), faculty_boss VARCHAR(20) ,PRIMARY KEY (student_id)
);CREATE TABLE course ( student_id INT NOT NULL, course_name VARCHAR(20), course_score INT, PRIMARY KEY(student_id, course_name)
);
第三范式
判断一个数据表是否满足第三范式,可以观察是否存在非主属性对于码的传递函数依赖,解决方法也和第二范式相同,将导致不符合第三范式的那个属性提出,单独创建一个表
可以对上面的student和course表进行分析,判断这两个表是否满足第三范式
分析course表
第一步,找出所有的码。course的码只有(student_id, course_name)
第二步,找出所有的主属性。主属性有student_id和course_name
第三步,找出所有的非主属性。非主属性有course_score
第四步,判断是否存在非主属性对于码的传递函数依赖。因为传递函数依赖至少需要有两个非主属性,所以course表不存在对于码的传递函数依赖
所以course表满足第三范式
分析student表
第一步,找出所有的码。student的码只有(student_id)
第二步,找出所有的主属性。主属性为student_id
第三步,找出所有的非主属性。非主属性有student_name,faculty_name和faculty_boss
第四步,判断是否存在非主属性对于码的传递函数依赖。从客观事实的角度出发,如果知道系名,就可以知道系主任是谁,所以faculty_boss完全函数依赖于faculty_name。又因为faculty_name完全函数依赖于码student_id,所以faculty_boss传递函数依赖于码student_id
所以student表不满足第三范式。
可以通过将系相关的信息提出去单独创建一张表,比如
CREATE TABLE student ( student_id INT NOT NULL, student_name VARCHAR(20), faculty_name VARCHAR(20), PRIMARY KEY (student_id)
);CREATE TABLE faculty ( faculty_name VARCHAR(20) NOT NULL, faculty_boss VARCHAR(20) NOT NULL, PRIMARY KEY (faculty_name)
);
BC范式
BC范式可以通过判断是否存在主属性对于码的部分函数依赖。出现这种情况的原因通常是由于数据表中存在着多个码。比如说(A,C)和(B,C)都是这个数据表的码,同时B完全函数依赖于A,那么主属性B就部分函数依赖于码(A,C),可以通过继续分解成两个表分别是
- 表1,包含属性A,B
- 表2,包含属性A,C
解决
参考资料
解释一下关系数据库的第一第二第三范式? - 刘慰的回答 - 知乎 https://www.zhihu.com/question/24696366/answer/29189700
数据库原理学习笔记(二)数据库范式相关推荐
- 数据库原理学习笔记(一)关系完整性以及数据库完整性
关系完整性是对关系的某种约束,当关系随着时间变化(增删改等操作改变数据库关系表)时应该满足一定的约束条件,通常这些约束条件都依赖于客观事实 关系完整性包含三个方面,分别是 实体完整性 参照完整性 用户 ...
- 数据库MySQL学习笔记高级篇(周阳)
数据库MySQL学习笔记高级篇 1. mysql的架构介绍 mysql简介 高级Mysql mysqlLinux版的安装 mysql配置文件 mysql逻辑架构介绍 mysql存储引擎 2. 索引优化 ...
- B站《一天学会 MySQL 数据库》学习笔记
B站<一天学会 MySQL 数据库>学习笔记 老司机带我飞 职场十字诀:思考.计划.行动.总结.反思 关注他 4 人赞同了该文章 登录和退出MySQL服务器 # 登录MySQL $ my ...
- oracle protocol=beq 不可用,学习笔记:Oracle数据库坏块 深入研究obj$坏块导致exp/expdp不能执行原因...
天萃荷净 深入研究Oracle坏块obj$导致exp/expdp不能执行导出的原因 上篇(案例:Oracle出现obj$坏块exp/expdp导出不能导出的解决办法ORA-01578 ORA-0111 ...
- 家族关系查询系统程序设计算法思路_【学习笔记】数据库基础 - 查询优化
目录 什么是数据库查询优化? 影响查询优化的因素 优化策略概述 查询优化的总体思路 语义优化 -- 内容等价性 语法优化(逻辑层优化)---语法等价性 执行优化(物理层优化) 查询优化在DBMS中的位 ...
- 数据挖掘学习笔记——GEO数据库:芯片数据分析
数据挖掘 数据挖掘学习笔记--GEO数据库:芯片数据分析 文章目录 数据挖掘 一.芯片基础知识 1.1.背景 二.GEO数据库概述 2.1.基础简介 2.2.检索页面展示 三.GSE项目的三种下载方式 ...
- SQL数据库教程-学习笔记2
SQL数据库教程-学习笔记2 文章目录 SQL数据库教程-学习笔记2 三.DML语言的学习 1.插入语句:insert into 2.修改语句:update 3.删除语句:delete 4.练习题 四 ...
- 数据库原理(十 二)- 逻辑结构设计
数据库原理(十 二)- 逻辑结构设计 前言 E-R图向关系模型的转换 数据模型的优化 设计用户子模式 前言 概念结构是独立于任何一种数据模型的信息结构,逻辑结构设计的任务就是概念结构设计阶段设计好的基 ...
- 数据库的学习笔记(一)
简述: 本篇是数据库的学习笔记,仅供自己学习使用. 本文初发于 "曾晨de小站" zengchen233.cn,同步转载于此. 数据库和表的基本操作(一) 如何在指定数据库中创建表 ...
最新文章
- 温度 数值模拟 matlab,西安交通大学 - 温度场数值模拟(matlab)
- 如何配置LCD背光和LED,调试方法
- eclipse maven 项目发布到tomcat 报错 Failed to scan JAR [file:/C:/xxxxx.jar] from WEB-INF/lib
- JS对以对象组成的数组去重
- php如何获取当前时间
- python 字典性质描述_卧槽!Python还有这些特性(2):奇怪的字典
- NYOJ-寻找最大数(贪心)
- Windows mobile 下读取手机SIM卡信息
- python可以做什么-Python简直就是万能的,你用Python都做过哪些事?
- python模拟浏览器访问百度_selenium与python自动化测试模拟登录百度
- 提升专业素养之软件工程概述
- Ubuntu:back up whole system
- Anaconda3安装及opencv配置
- windows server2016忘记密码,windows重置密码,windows破解密码,win10忘记密码,win10破解密码,windows server2016破解密码
- CRM是什么?CRM客户管理系统主要的功能,作用,特点分别有哪些?
- 微信小程序的appid
- 当你们在谈论React和Vue的时候,我在用Mithril
- mapbox基本使用
- java设计帐号密码_怎样用java设置帐号和密码
- HBuilder 下运行uniapp(微信小程序)时,微信开发者工具进入游客模式