文章目录
这是我们学校研究生复试数据库的试卷,仅供参考。
如果有些知识点忘记了,下面有个人整理的知识点,如果有错误,欢迎指正!!
一、绪论
1、数据库的四个基本概念
1.1、数据data
描述事物的符号记录
1.2、数据库DB
数据库是长期储存在计算机内、有组织的、可共享的大量数据的集合。
1.3、数据库管理系统DBMS
是位于用户和操作系统之间的一层数据管理软件。
1.4、数据库系统DBS
是由数据库、数据库管理系统、应用程序和数据库管理员组成的存储、管理、处理和维护数据的系统。
2、数据库的发展阶段
- 人工管理阶段
- 文件系统阶段
- 数据库管理系统
3、数据模型
数据模型是数据库系统的核心和基础
3.1、概念
对现实世界数据特征的抽象
3.2、作用
表示实体类型及实体类型间联系的模型
3.3、分类
3.3.1、概念模型
含义:按用户观点来对数据和信息建模,主要用于数据库设计。
概念模型的一种表示方法:实体-联系方法(ER图)。用E-R图来描述现实世界的概念模型
3.3.2、逻辑模型
含义:按计算机系统的观点对数据建模、主要用于数据库管理系统的实现。
包括:
-
层次模型
-
网状模型
-
关系模型------------------用二维表格结构来表示实体以及实体之间联系的数据模型
这里只需要掌握关系模型,其他的不重要
3.3.3、物理模型
含义:它描述数据在系统内部的表示方法和存取方法,或在磁盘上的存储方式和存取方法
3.4、数据模型的组成
数据结构 +数据操作 +数据完整性约束
4、数据库系统的结构
4.1、三级模式结构
- 外模式 :对应视图
- 模式 :对应基本表
- 内模式 :对应存储文件
4.2、二级映像
- 外模式/模式映像
- 模式/内模式映像
如要保证物理独立性,需要修改模式和内模式之间的映像
如要保证逻辑独立性,需要修改外模式和模式之间的映像
二、关系数据库
支持关系模型的数据库系统
1、关系模型的组成
关系数据结构+关系操作集合+关系完整性约束
1.1、关系数据结构
1、关系的含义
一个关系就是一个二维表。一行一元组,一列一属性
2、域
属性的取值范围
3、关系模式
对关系的描述称为关系模式,由关系名和其属性集合构成,格式:关系名(属性名1,属性名2,属性名3)
4、码
- 候选码:某一属性组的值能唯一标识一个元组 ,比如 学号+姓名组合
- 主码:若一个关系有多个候选码 ,选定一个为主码
- 主属性:包含在任何候选码中的属性称为主属性
- 非主属性:不包含在任何候选码中的属性称为非主属性
- 外码:另一个关系的主码
- 学生(学号,姓名,性别,专业号,年龄)
学生称为 参照关系
- 专业(专业号,专业名)
专业称为 被参照关系
- 学生(学号,姓名,性别,专业号,年龄)
- 全码
1.2、关系操作集合
1、基本的关系操作
- 查询
- 插入
- 删除
- 修改
使用关系语言来实现这些操作
其中查询操作分为:选择、投影、连接、除、并、差、交、笛卡尔积
2、关系语言的分类
- 关系代数
- 关系演算
- SQL语言
只要求掌握关系代数和SQL语言
1.3、关系完整性约束
-
实体完整性:规定主码中的属性即主属性不能取空值
-
参照完整性:外码要么为空
表示暂未分配
,要么对应另一表的主码 -
用户自定义完整性:用户自己定义规则
2、关系代数
2.1、概念
一种抽象的查询语言,它用对关系的运算来表达查询
2.2、特点
关系代数的运算对象和运算结果均为关系
2.3、分类
-
传统的集合运算
- 并
- 差
- 交
- 笛卡尔积
-
专门的关系运算
-
选择:在关系R中选择满足条件的诸元组
相当于SQL语言中的where子句
-
投影:选择指定属性列组成新的关系
相当于SQL语言中的select 指定列 from 某表
-
连接:从笛卡尔积中选取属性间满足一定连接条件的元组
笛卡尔积相当于无条件连接,而连接运算是有条件连接
-
非等值连接:非’=‘的连接运算,如 ‘>’、’<’
-
等值连接:满足属性间相等,即’='的连接运算
-
自然连接:除去重复属性的等值连接
-
外连接:对自然连接运算的拓展,可以处理由于连接运算而缺失的信息。
-
左外连接:左边没有空元素
-
右外连接:右边没有空元素
-
全外连接
-
-
-
除
- 被除数是你的总范围,除数是你要搜索的条件
- a除b就是从a里面找出满足b的元组
- 同时满足好几个条件时用除法
三、结构化查询语言SQL
1、概念
是关系数据库的标准语言
2、体系结构
2.1、基本表
本身独立存在的表
- 基本表与关系:一对一
- 基本表与存储文件:多对一
- 基本表与索引:一对多
2.2、视图(虚表)
从一个或多个基本表中导出的表
数据库中只存放视图的定义,不存放视图的数据
2.3、存储文件
3、数据类型
数据类型 | 含义 |
---|---|
char(n) | 长度为n的定长字符串 |
varchar(n) | 最大长度为n的变长字符串 |
int | 长整数 |
smallint | 短整数 |
bigint | 大整数 |
decimal(p,d) | 定点数,由p位数字组成,小数点后面有d位数字 |
float(n) | 可选精度的浮点数 |
4、数据定义 DDL
定义数据库中的基本对象:模式、表、视图和索引。
-
一个关系数据库管理系统的实例中可以建多个数据库。
-
一个数据库可以建多个模式
-
一个模式包含多个表、视图、索引
模式和视图不存在修改的操作 只能删除再重建
4.1、模式
4.1.1、【模式定义】
定义模式实际上定义了一个命名空间 , 在这个空间中可以进一步定义该模式包含的数据库对象,例如:基本表、视图、索引。
//某某用户得到创建模式的授权
create schema <模式名> authorization <用户名>;
案例
//为用户WANG定义一个学生-课程模式S-T
create schema "S-T" authorization WANG;
4.1.2、【模式删除】
drop schema <模式名> <cascade|restrict>;
案例
drop schema "learn" cascade;
cascade:想删除该模式及模式中所有数据库对象
restricct:如果模式中有数据库对象,比如表视图 就拒绝删除
4.2、表
4.2.1、【表定义】
create table 表名(字段名 类型 字段约束, 字段名 类型 字段约束, 字段名 类型 字段约束);
案例
create table user(
id int primary key,
name varchar(20),
age int ,
sex char(1))
-
列级完整性约束
- not null
- unique : 值唯一
- default : 默认值
-
表级完整性约束
- 主键约束,即实体完整性
- 外键约束,即参照完整性
4.2.2、【表删除】
drop table <表名> [restrict|cascade];
案例
//删除Student表
drop table Student cascade;
cascade:如果表有外键,视图,触发器的话,也会强制删除
restrict:相反
4.2.3、【表修改】
#增加新列
alter table <表名> add <新列名><数据类型>[完整性约束]
#删除表中的列
alter table <表名> drop 列名
#修改原有的列定义,包括修改列名,数据类型
alter table <表名> alter column <列名><数据类型>
案例
//向Student表增加"入学时间"列,其数据类型为日期型。
alter table Student add S_entrance DATE;
4.3、索引
数据量比较大的时候,查询时间长,建立索引可以加快查询速度。
创建索引是对存储文件的操作,即改变的是内模式
4.3.1、【索引建立】
create [unique][cluster] index <索引名> on <表名>(<列名>)
unique:每一个索引只对应唯一的数据记录
cluster:物理顺序与索引顺序相同。比如买书
案例
create unique index Stusno on Student(Sno);
4.3.2、【索引修改】
alter index <旧索引名> rename to <新索引名>;
案例
//将SC表的SC索引名改为SCSno。
alter index SC rename to SCSno;
4.3.3、【索引删除】
drop index <索引名>;
案例
//删除Student表的Stusname索引
drop index Stusname;
5、数据查询 DML
查询数据库中的各种数据对象
select [distinct] 指定字段 from 表 where 筛选条件 group by 列名1 having… order by 列名
//distinct 消除重复行
5.1、投影查询
使用select命令可以选择查询表中的任意列。
select name as '姓名',sex as '性别',cno as `班号` from student
5.2、选择查询----where+给定条件
where子句指定查询条件,只从源表显示满足该查询条件的记录
【1】条件运算
条件运算符: > < = != >= <=
【2】逻辑运算
逻辑运算符: and or not
作用:连接条件表达式
【3】字符匹配-----模糊查询
like ; not like
#案例1:查询员工名中第三个字符为n,第五个字符为1的员工名和工资
select last_name,salary from employees where last_name like '__n_1%';
#数据中如果存在特殊通配符则需要转义
#案例2:查询员工名中第二个字符为_的员工名(转义字符)
select last_name from employees where last_name like '_\_%';
【4】给定集合查询
- in
- not in
selcet * from score where 分数 in (85,86,88);
【5】空值查询
- is null
- is not null
【6】范围查询
between and 、 not between and
#案例:查询员工编号在100到120之间的员工信息
select * from employees where employee_id between 100 and 120 ;
5.3、排序查询 order by
-
asc代表升序,desc代表降序,默认不写是升序
-
order by子句一般是放在查询语句的最后面,表示对最终查询结果排序
#查询student表的所有男生记录,并以班号降序排列
select 学号,姓名,班号 from student
where 性别='男'
order by 班号 desc;
#以课程号升序、分数降序检索score表的所有记录
select * from score
order by 课程号,分数 desc;
5.4、聚合函数
特点
① sum , avg 用于处理数值型,max , min, count 可以处理 任何类型
② 当聚集函数遇到空值时,count(*)不跳过空值, 而其他的函数只处理非空值。
③ 可以和distinct搭配实现去重
④where子句中是不能用聚合函数的,只能在select子句和group by中的having子句用
案例
select sum(salary) from employees;
select sum(salary) 工资总数, round(avg(salary),2) 平均值 from employees
select max(salary) 最高, min(salary) 最低 from employees
、
#有多少人有工资,会排除为NULL
select count(salary) from employees;
#函数可以和distinct去重语句使用
select count(distinct commission_pct) from employees;
#统计有多少行,多少元组
select count(*) from employees;
5.5、分组查询 group by
根据列名进行分组
该属性列值相等的元组为一个组
①分组查询中的筛选条件分为两类
-
想要分组之前筛选用where,即表中选取行
-
想要分组之后筛选用having,即选取满足条件的分组
②分组后聚集函数将作用于每一个组
③可添加排序(放在group by后)
#查询score表中最低分大于70、最高分小于90的学生学号
select 学号 from score
where 分数 is not null
group by 学号
having min(分数)>70 and max(分数)<90
5.6、连接查询
select 列名1,列名2, from 表1, 表2
where 连接条件
#注:若不加where条件,则是查询结果是笛卡尔积
1、内连接
使用inner join关键字。不使用该关键字时默认均为内连接。内连接又包括等值连接、非等值连接和自连接。
【1】等值连接
表之间通过"等于"关系连接起来,产生一个连接临时表先笛卡尔积,后where子句筛选
,生成最终结果。
注意:等值连接并不是自然连接,如要自然连接,则通过投影,去除重复列
#查询所有学生的姓名、课程号和分数列
select student.姓名,score.课程号,score.分数
from student,score
where student.学号=score.学号;
//下面使用inner join 也可以
select student.姓名,score.课程号,score.分数
from student inner join score on student.学号=score.学号
where student.学号=score.学号;
#查询'09033'班所选课程的平均分
select y.课程号,avg(y.分数) as '平均分'
from student x , score y
where x.学号=y.学号 and x.班号='09033' and y.分数 is not null t4rdds
【2】非等值连接
表之间的连接关系不是"等于",而是其他关系。通过指定的非等值关系将两个表连接起来,产生一个连接临时表,然后对该临时表进行处理后生成最终结果。
#查询所有学生的学号、课程号和等级列
select 学号,课程号,等级
from score,grade
where 分数 between low and upp
order by 等级
【3】自连接
在数据查询中有时需要将同一表进行连接,这种连接称为自连接,进行自连接就如同两个分开的表一样,可以把一个表的某行与同一表中的另一行连接起来。
#查询选修'3-105'课程的成绩高于'109'号学生成绩的所有记录,并按成绩从高到低排序.
select x.课程号,x.学号,x.分数
from score x,score y
where x.课程号='3-105' and x.分数>y.分数 and y.学号='109' and y.课程号='3-105'
order by x.分数 desc;
2、外连接
【1】左外连接
其结果包括第一个命名表中的所有行,不包括右表中的不匹配行。
select course.课程名,teacher.姓名
from course left join teacher on (course.任课教师编号=teacher.教师编号);
【2】右外连接
其结果包括第二个命名表中的所有行,不包括左表中的不匹配行。
select course.课程名,teacher.姓名
from course right join teacher on (course.任课教师编号=teacher.教师编号)
【3】全外连接
左右两边都保留不匹配信息
select course.课程名,teacher.姓名
from course full join teacher on (course.任课教师编号=teacher.教师编号)
5.7、子查询
当一个查询是另一个查询的条件时,换言之,当从表中选取数据行的条件依赖于该表本身或其他表的联合信息时,需要使用子查询来实现。
#检索考试成绩为最高分的学生姓名。
select 姓名
from student
where 学号=(select 学号
from score
where 分数=(select max(分数)
from score
where 分数 is not null
)
)
一个子查询的返回值为多行时,需要使用any、all、in 和not in等选项,它们与查询条件一起返回一组值的子查询。
#检索选修学生人数多于5人的某课程的任课教师姓名 -----in
select 姓名
from teacher
where 教师编号 in
(select x.任课教师编号
from course x,score y
where x.课程号=y.课程号
group by x.任课教师编号
having count(x.任课教师编号)>5)
)
#检索选修教师编号为'3-105'课程且成绩至少高于选修教师编号为'3-245'课程的学生的课程号、学号和分数,并按分数从高到低次序排列。
select 课程号,学号,分数
from score
where 课程号='3-105' and 分数>any
(select 分数 from score
where 课程号='3-245')
order by 分数 desc;
#检索选修教师编号为'3-105'课程且成绩高于选修教师编号为'3-245'课程的学生的课程号、学号和分数
select 课程号,学号,分数
from score
where 课程号='3-105' and 分数>all
(select 分数 from score
where 课程号='3-245')
5.8、相关子查询
5.9、EXISTS子查询
暂未写
5.10、查询结果的并、交、差运算
6、数据更新 DQL
对数据增删改查
6.1、插入数据
insert into <表名> values(值1,值2,值3……)
insert into <表名> (属性列1,属性列2,属性列3) values(值1,值2,值3……)
6.2、修改数据
update <表名> set 列名=值 where 条件
6.3、删除数据
delete from <表名> where 条件
7、视图定义 DCL
从基本表导出的表,为了让用户看得简单。 当我们业务需求要查出多张表的数据,这时我们可能会关联多张表查询处理,如果这个查询sql复杂的话也影响了查询效率,这个时候我们就可以创建视图,查询时候只需要 select * from view 就可以了
注意:对视图的操作会作用于对基本表的操作
7.1、创建视图
create view <视图名> [<列名>,<列名>] as <子查询> [with check option];
#含义:将子查询的结果作为视图的结果
#[with check option]
表示对视图进行增删改操作时要保证数据更新、插入或删除的行满足视图定义中的子查询中的条件表达式。
案例
# 建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生
create view IS_Student
as
select Sno,Sname,Sage
from Student
where Sdept='IS'
with check option;
由于在定义IS_Student视图时加上了with check option子句,以后对该视图进行插入、修改和删除操作时,关系数据库管理系统会自动加上Sdept='IS'的条件。
7.2、删除视图
drop view <视图名> [cascade]
#视图删除后视图的定义将从数据字典中删除。如果该视图上还导出了其他视图,则使用cascade级联删除语句把该视图和由它导出的所有视图一起删除。
7.3、查询视图
# 在信息系学生的视图中找出年龄小于20岁的学生。
select Sno,Sage
from IS_Student
where Sage<20;
7.4、更新视图
视图是不存在的,所以我们对视图的操作,最终要反映到对基本表的操作
案例
# 1、将信息系学生视图IS_Student中学号为"201215122"的学生姓名改为"刘辰"。
update Student
set Sname='刘辰'
where Sno='201215122' and Sdept ='IS';
# 2、向信息系学生视图IS_Student 中插入一个新的学生记录,其中学号为 "201215129",姓名为"赵新",年龄为20岁。
insert
into Student(Sno,Sname,Sage,Sdept)
values('201215129','赵新',20,'IS');
四、数据库安全性
保护数据库防止恶意破坏和非法存取。 数据库安全最重要的一点就是确保只授权给有资格的用户访问数据库的权限,这主要通过数据库系统的存取控制机制实现。
1、自主存取控制
用户可以自定义和分配其他用户的操作权限。主要通过grant、revoke来进行控制,由两个元素构成:数据库对象和操作权限,我们定义用户的存取权限 成为授权。
1.1、授权 Grant
Grant <权限> on 表名[(列名)] to 用户 with grant option
# 授权命令是由数据库管理员使用的,若给用户分配权限时带with grant option子句,则普通用户获权后,可把自己的权限授予其他用户。
案例
//授予用户user1拥有对表student的查询权限
Grant select on student to usre1 with grant option
1.2、回收权限 revoke
revoke <权限> on <数据对象> from <数据库用户名> cascade
案例
//回收user1对student表的查询权限
revoke select on student from user1;
1.3、数据库角色
角色指的是一类人,比如说CEO、总监、普通职员,可以给一类人授权
1、角色的创建
create role <角色名>
# 创建角色CEO
create role CEO
2、角色的授权
grant <权限> on <对象类型> 对象名 to <角色1>,<角色2>
# 为角色CEO分配查询Student表的权限
grant select on Student to CEO
3、把角色授权给其他用户或者角色
grant <角色> to 角色或者用户名字 [with admin option];
#将角色CEO分配给李华
grant CEO to LiHua
-- 如果加上with admin option,意味着,这个用户还可以把这权限授予给其他角色或者用户
4、角色权限的收回
revoke <权限> on <对象名> from 角色名字
#回收CEO对表的查询权限
revoke select on Student from CEO;
2、视图机制
为不同的用户定义不同的视图,把不需要的数据隐藏起来,这样用户就不会进行误操作
#1、定义视图
create view CS_Student
as
select *
from student
where sdept='IS';
#2、将视图里的查询权限给王平
grant select
on CS_Student
to 王平;
#3、将视图里的所有权限都给王平
grant all privileges
on CS_Student
to 王平;
五、数据库的完整性
防止数据库中存在不正确的数据
1、实体完整性
主码唯一且非空
#两种添加主键的方法
create table course (id int not null,time varchar(255),primary key(id)));
create table course (id int not null primary key,time varchar(255));
2、参照完整性
外码要么没有,要么只有一个
create table course
(id int,
time varchar(255),
title varchar(255),
teacher_id int,
primary key(id), foreign key(id) references course_description(course_id);
);
# references 表名(属性) : 关联哪张表的某个属性
3、用户定义完整性
3.1、非空
create table student(
id char(9) primary key,
age int not null
);
3.2、列值唯一
create table student(
id char(9) primary key,
age int unique;
);
3.3、满足某一个条件表达式 check来写
create table student(
id char(9) primary key,
sex char(2) check (sex in ('男','女')),
age int not null
);
4、断言
create assertion <断言名> <check 子句> #其中check子句 与where子句的表达式类似
drop assertion 断言名字;
案例
# 限制每一门课程最多60名学生选修
create assertion ASSE_SC_CNUMI
check(60>=all(select count(*)
from SC
group by cno)
);
5、触发器
触发器又叫做事件-条件-动作规则。当对一个表增、删、改时候,对触发器里面的条件进行检查,如果成立,就执行触发器里面的动作,否则不执行里面的动作。
create trigger <触发器名> -- 每当触发事件发生时,该触发器被激活
{before|after} <触发事件> on <表名> -- 指明触发器激活的时间是在执行触发事件前或后
referencing new|old row as<变量> -- 指出引用的变量
for each{row|statement} -- 定义触发器的类型
[when <触发条件>] <触发动作体> -- 仅当触发条件为真时才执行触发动作体
drop trigger <触发器名> on <表名>
- for each row 行级触发器: 比如触发事件要执行多个update语句,每执行update一次,触发动作体便执行一次
- for each statement 语句级触发器: 同上,要等所有的update语句执行完,触发动作体才会执行一次。
案例
//当对表SC的Grade属性进行修改时,若分数增加了10%,则将此次操作记录到另一个表SC_U(Sno,Cno,Oldgrade,Newgrade)中,其中Oldgrade是修改前的分数,Newgrade是修改后的分数。
create trigger SC_T
after update of Grade on SC -- update of Grade on SC是触发事件
referencing
oldrow as OldTuple,
newrow as NewTuple
for each row -- 行级触发器,即每执行一次Grade的更新,下面的规则就执行一次
when (NewTuple.Grade>=1.1*OldTuple.Grade) -- 触发条件,只有该条件为真时才执行
insert into SC_U(Sno,Cno,OldGrade,NewGrade) -- 下面的insert操作
values(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade)
//将每次对表Student的插入操作所增加的学生个数记录到表Student-InsertLog中。
create trigger Student_Count
after insert on Student
referencing
new table as delta
for each statement -- 语句级触发器,即执行完insert语句后下面的触发动作体才执行一次
insert into StudentInsertLog(Number)
values(select count(*) from delta);
六、关系数据理论
1、关系模式
R<U,F>
R:关系名
U:属性集
F:函数依赖
关系中一个或一组属性的值可以决定其他属性的值 ,比如 学号→姓名就是一个依赖
如下图所示
2、函数依赖
下面举例,结合上面的描述,自行带入理解
-
非平凡的函数依赖
- (学号 , 课程号)→成绩
- 学号→姓名
-
平凡的函数依赖
- (学号 ,课程号)→学号
- 学号→学号
-
完全函数依赖
-
部分函数依赖
(学号,身份证号)→姓名 -
传递依赖
由员工号→岗位,岗位→工资,可得员工号→工资
3 、如何求最小依赖集?
本质上就是去除依赖集的冗余依赖,因为有其他的依赖也能推出该冗余依赖,所以删掉多余的依赖
步骤
1)拆右边为多个元素的 比如A- ->BC 拆为 A- ->B 和A- >C
2)除去右边元素,看左边的闭包能否继续推出右边,如果不能则保留。
3)左边最小化(通过遮住元素看其他余下的元素能不能推出该遮住的元素) 。 比如BCD, 遮住B看余下的CD能推出B吗,遮住C看余下的BD能推出C吗 , 以此重复。
习题
已知关系R<U,F> ,U{A,B,C,D,E,F,G},F={BCD→A,BC→E,A→F,F→G,C→D,A→G}
求F的最小依赖集。
1.右边没有要拆分的
2.除去A→G
3.BC→A
BC→E
A→F
F→G
C→D
4、码
4.1、候选码
概念
如下图:
属性组<学号,课程号>可以推出U的所有属性,学号→姓名、课程号→课程名、学号,课程号→成绩。而对于该属性组里的单个属性学号
和课程号
均不能推出所有属性。符合上述定义,所以<学号,课程号>是候选码。
总结:能推出所有属性的是候选码
4.2、超码
能表示出所有属性的集合 候选码是最小的超码
4.3、主码
从候选码中任意挑出一个作为主码,如上面的<学号,课程号>
4.4、主属性
包含在候选码中的属性都称为主属性,如上面的学号以及课程号均为主属性
4.5、非主属性
不包含在候选码中的属性,如上面的成绩、姓名、课程名
4.6、外码
一个属性不是当前关系的主码,但是是另一个关系的主码
4.7、全码
所有的属性都是主码,或者说属性U全是候选码
5、如何选出候选码?
- 只出现在左边的一定是候选码
- 只出现在右边的一定不是候选码
为什么呢?很简单,因为左边有元素可以推出它,那干嘛还要它
- 左右都出现的不一定
- 左右都不出现的一定是候选码
- 再求确定的候选码的闭包,如果可以推出全部,那么当前确定的就是候选码,否则,你要把每一个可能的值 放进当前确定的候选码里面进行求闭包
总结:能推出U集的就是候选码
习题
R<U,F> , U={A,B,C,D,E,G} , F={ (A,B)→C , (C,D)→E , E→A , A→G } , 求该关系模式的候选码。
//按上面的方法做
解:
B一定是候选码 D一定是候选码
G一定不是候选码
A不一定 C不一定 E不一定
BD→啥也推不出来,所以要把每一个可能的求闭包。
(BDA) 可推出C E A G 所以可以推出ABCDEG
(BDC) 可推出E A G 所以可以推出ABCDEG
(BDE) 可推出A G C 所以可以推出ABCDEG
那么它的候选码最终是{(BDA),(BDC),(BDE)};
这里还放了一条题目,看会不会做?
6、三大范式
关系数据库中的关系必须满足一定的规范化要求,对于不同的规范化程度可用范式来衡量。
6.1、第一范式(1NF)
第一范式存在的问题
第一范式变第二范式需要消除第一范式中的部分函数依赖。
6.2、第二范式(2NF)
如下图所示,满足第一范式但存在部分函数依赖。
(学号,课程号)是候选码, 姓名、学院、院长、课程名、成绩均为非主属性。
- 姓名、学院、院长只依赖于候选码中的学号,所以是部分函数依赖。
- 课程名只依赖于候选码中的课程号,所以也是部分函数依赖。
-成绩依赖于学号、课程号的属性组,所以是完全函数依赖。
因为第二范式要求每个非主属性都完全函数依赖于候选码,但这里这有成绩满足完全函数依赖,所以不符合。
消除第一范式的部分函数依赖
单个属性作为候选码时,是不会出现部分函数依赖的,如下图,满足第二范式
但是第二范式可能存在传递函数依赖,如上图 学号→学院,学院→院长,得学号→院长,可见院长传递函数依赖于学号
6.3、第三范式(3NF)
满足第二范式,但不包含非主属性对码的传递函数依赖,确保数据表中的每一列数据都和主键直接相关,而不能间接相关。
消除第二范式的传递函数依赖
6.4、BCNF![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/cc99b4a76bf6a78c709451e544e84f25.png)
6.5、小结
个人总结:
先找出候选码,如果候选码是多个属性组成的一个属性组的,那么是有可能存在部分函数依赖的:看有没有非主属性依赖于候选码的一部分。若是候选码是单个属性,那么肯定不存在部分函数依赖。
见视频
7、模式分解
准则:保持函数依赖
7.1、习题
已知 R(ABCDEGH) , F={A→D , E→D , D→B , BC→D , DC→A },求保持函数依赖的3NF的分解。
1) 求出最小函数依赖集
2)把不在F里面的属性都找出来,单独分一类,并去除
3) 把每一个依赖左边相同的分成一类,没有一样的,那么就把A→D改为{AD}如果一样{A→B,A→C} 那么就改为{ABC}
4) 如果候选码没出现在分离里面,把任意一个候选码作为一类
最小函数依赖集Fmin={A→D,E→D,D→B,BC→D,DC→A}
GH没在F里面,单独一类{GH}
候选码:CE
AE
{AD}{ED}{DB}{BCD}{DCA }{CE}{GH}
七、数据库设计
1、数据库设计步骤
- 需求分析: DFD图或者设计数据字典
- 概念结构设计 :ER图
- 逻辑结构设计 : ER图 -> 逻辑模型
- 物理结构设计 : 逻辑模型 -> 物理模型
- 数据库实施 : 写SQL代码
- 数据库运行和维维护 : 性能检测
2、ER图
2.1、实体
实体用矩形表示,矩形框内写明实体名。
实体有:普通实体,弱实体、父实体、子实体
弱实体:这种实体对于另一些实体具有很强的依赖关系。
2.2、属性
属性用椭圆表示,框内写明属性名。
有下划线的属性为主键,有虚线的属性为外键
2.3、联系
联系用菱形表示,菱形框内写明联系名,并用无向边分别与有关实体连接起来,同时在无向边旁标注上联系的类型(1:1、1:n、m:n)
1)判断两个实体之间的联系类型的方法
①一个实体A可以对应几个B ,则对应右边写几
②一个实体B可以对应几个A ,则对应左边写几
如下图,
一个学生对应一个班级,那么右边就写1
一个班级对应多个学生,那么左边就写n
2)判断三个实体之间的联系类型的方法
三个实体之间的联系讲解
3、 ER图转关系模式
1)实体向关系模式的转换
将ER图中的实体逐一转换成一个关系模式,实体名对应关系模式的名称,实体的属性转换成关系模式的属性,实体的标识符就是关系的码。
2)联系向关系模式的转换
(1)一对一联系的转换。一对一联系有两种方式向关系模式进行转换。一种方式是将联系转换成一个独立的关系模式,关系模式的名称取联系的名称,关系模式的属性包括该联系所关联的两个实体的码及联系的属性,关系的码取自任一方实体的码;另一种方式是将联系归并到关联的两个实体的任一方,给待归并的一方实体属性集中增加另一方实体的码和该联系的属性即可,归并后的实体码保持不变。
(2)一对多联系的转换。一对多联系有两种方式向关系模式进行转换。一种方式是将联系转换成一个独立的关系模式,关系模式的名称取联系的名称,关系模式的属性取该联系所关联的两个实体的码及联系的属性,关系的码是多方实体的码:另一种方式是将联系归并到关联的两个实体的多方,给待归并的多方实体属性集中增加一方实体的码和该联系的属性即可,归并后的多方实体码保持不变。
(3)多对多联系的转换。多对多联系只能转换成一个独立的关系模式,关系模式的名称取联系的名称,关系模式的属性取该联系所关联的两个多方实体的码及联系的属性,关系的码是多方实体的码构成的属性组。
(4)三个实体的联系转换。只能转换成一个独立的关系模式,关系模式的名称取联系的名称,关系模式的属性取该联系所关联的多方实体的码及联系的属性,关系的码是多方实体的码构成的属性组。
八、数据库恢复技术
1、事务
事务是用户定义的一个数据库操作序列
事务通常是以BEGIN TRANSACTION开始,以COMMIT或ROLLBACK结束。
COMMIT:提交,即提交事务的所有操作。将事务中所有对数据库的更新写回到磁盘上的物理数据库中
ROLLBACK:回滚,即事务运行中一旦发生故障,系统将事务对数据库所有已完成的 操作全部撤销,回滚到事务开始的状态。
这里的操作指对数据库的更新操作
2、事务的四大特性-----ACID
3、恢复的实现技术
建立冗余数据最常用的技术是数据转储和登记日志文件。
九、并发控制
事务是并发控制的基本单位,保证事务ACID特性是事务处理的重要任务。事务的ACID可能遭到破坏的原因是多个事务对数据库的并发操作造成的。为了保证事务的隔离性和一致性,数据库管理系统需要并发控制。
1、并发带来的数据不一致
产生三类数据不一致性的主要原因是并发操作破坏了事务的隔离性。
1.1、丢失修改
修改未生效,比如我把票价修改为99,但是同时有人去修改为299元,结果看到的还是299元
1.2、脏读
比如我正在读数据库的A、B字段,但是读的时候有其他用户正在更新这两个字段,而且是先更新A再更新B。如果那个用户更新到一半我就读了,这时候只更新了A未更新B,这时候我去读的就是脏数据。
1.3、不可重复读
我在一个事务中,连续两次读到的数据不一样,“幻读”。
比如事务一开始读到余额是10元,此时正好发工资100到这张卡上,第二次读就变成了了110元
2、并发控制的主要技术:封锁
2.1、基本的两类锁
- 排他锁
- 共享锁
2.2、封锁方法引起 活锁和死锁
a)活锁:T2一直没拿到锁
解决方法:采用先来先服务策略
b)死锁:T1在等待T2,而T2又在等待T1的局面。
解决方法主要分为预防死锁和…
诊断死锁的方法:超时法和事务等待图法