本文是数据库系统概念一书的学习笔记,笔记中使用的实例数据库是书中的[数据库系统概念sample DDL-MySQL.sql ](www.db-book.com/db6/lab-dir…)
第一章 基本概念
第二章 关系模型
2.1 关系数据库的结构
-
关系数据库=表的集合
-
表=元组的集合
-
表可以由关系来理解
关系为一个抽象的概念提供了某种具象化描述,规定满足某些条件的集合为···关系
而表也是用一系列属性来表示某一个概念
-
元组=行
-
属性=列
-
域(domain)=属性规定允许的取值集合
域是原子的,即域中的元素不可再分
-
2.2 数据库模式:
定义:数据库的逻辑设计
| 数据库概念 | 程序设计概念 |
|---|---|
关系 | 变量 |
关系模式 | 类型定义 |
关系实例 | 变量的值 |
在程序设计语言中:
- 一个变量可能有类型 地址 地址对应物理空间的值
- 类型定义了这个变量有哪些部分,值域,可以做的操作
- 变量的值在系统运行中是可变化的
在数据库中,一个表可能有表示的内容 存储地址 以及表示的内容
- 一个表(关系)可能有包含的内容(DDL) 对他可以做的操作(DML) 值(元组集合)
- 而关系模式——表的逻辑设计,定义了该关系有哪些属性 属性的域 可以做什么操作——
- 关系实例表某一瞬间的一个元组集合
2.3 键(key)
-
超键
能唯一区分一个元组的属性集合
-
候选键
能唯一区分一个元组的最小属性集合
-
主键
某一个候选键
选择要求:主键必须选择极少变化的值
-
外键
A关系的某个属性是B关系的主键,该属性是A的外键
则A参照B,意味着A的信息需要参照B才能得以表达
A是参照关系,B是被参照关系
2.4 关系查询语言
定义:用户用来从数据库中请求获取信息的语言
过程化语言:用户指导系统对数据库执行一系列操作以计算出所需结果
非过程化语言:只需要描述信息,不需给出过程
2. 5 关系运算
定义:施加于单个或一对关系上,得到的结果是单个关系
- 选择
- 投影
- 自然连接
- 笛卡尔乘积
- 并
第三章 SQL基本DML和DDL
3.1 database操作
show databases;
use database; //修改当前使用的数据库
create database name;
drop database name;
3.2 数据定义(DDL)
SQL的DDL可以定义:
- 关系的模式
- 每个属性的取值类型
- 完整性约束
- 关系维护的索引集合
- 关系的安全性和权限信息
- 关系在磁盘上的物理结构
3.2.1 基本类型
- int==integer
- numeric(p,d):定点数,p d为小数点前后的位数,
- smallint:小整数类型
- float(n)
- read,double precision:
- char(n):长度为n的字符串
- varchar(n):可变长度字符串,n为最大长度
3.2.2 模式定义
-
定义表:
create table 表名( 属性名 域(类型) <not null>, ... 属性名 域(类型) <not null>, <完整性约束>,...<完整性约束>); create table 表名 like 表名; create table 表名 as (查询子句) with data -
对表的模式进行操作
show tables; //查看有哪些表 drop table 表名; //删除整个关系 alter table 表名 add 属性名 域; //添加属性 alter table 表名 drop 属性名; //删除属性
3.2.3 完整性约束
1. 定义模式时使用的约束
- 属性名 not null:不可为空
- unique(属性列表):该属性的值不可重复
- 属性名 check +谓词:该属性每个值满足谓词
- default 值:默认值
参照完整性约束
- primary key:主键
- foreign key 属性名 references 表名:设定该属性为外键,被参照关系是表名,被参照属性是该表名主键
- 属性名 references 表名 :在定义属性时声明外键
这两种外键声明方式的不同在于对破坏完整性约束的操作的处理方式不同
- 使用foreign key时在破坏完整性的操作时可以定义级联的恢复完整性操作,例如
creat table(
···
foreign key name references 表名
on delete cascade //级联删除操作,另一个表删除了某项,则该表对应项也删除
on update cascade, //级联更新操作,另一个表更新了某项,则该表对应项也更新成对应值
···
)
- 在定义属性名时声明外键则直接拒绝执行导致完整性破坏的操作(roll back)
2.断言
表达了一个我们希望数据库总能满足的一个条件
create assertion <assertion name> check <谓词>
3.3 SQL查询语句(DML)
3.3.1 查询过程概述(关键字从上到下依次进行)
-
from 关系1,关系2,...关系n:对参数做简单的笛卡尔乘积,参数间有相同属性名,在得到的关系中则用
关系名.来区分 -
from A join B using (属性名):对参数中某属性值相同的做元组笛卡尔乘积,相同属性不重复显示
-
from A natural join B:对参数中所有相同属性值相同元组做笛卡尔乘积,相同属性不重复显示
-
where 谓词:对前述三个得到的每个元组作为谓词的输入
-
group by 属性名:将前述得到的元组用指定属性名分组
-
having +谓词:将每个分组作为谓词输入
-
select <属性名1,属性名2...属性名n>,<聚集函数1,聚集函数2...聚集函数n>:将获得的元组的指定属性输出
3.3.2 连接子句
(1)from
-
作用:得到笛卡尔乘积
-
使用形式:from + 连接
-
输入:连接子句
-
输出:若连接子句为空,由输入的关系做笛卡尔乘积得到的关系,若n个关系中有相同属性名,则在得到的关系用
关系名.来区分可以使用以下的迭代过程理解from产生的结果
```sql mysql> select * -> from teaches; +-------+-----------+--------+----------+------+ | ID | course_id | sec_id | semester | year | +-------+-----------+--------+----------+------+ | 76766 | BIO-101 | 1 | Summer | 2009 | | 76766 | BIO-301 | 1 | Summer | 2010 | | 10101 | CS-101 | 1 | Fall | 2009 | | 45565 | CS-101 | 1 | Spring | 2010 | | 83821 | CS-190 | 1 | Spring | 2009 | | 83821 | CS-190 | 2 | Spring | 2009 | | 10101 | CS-315 | 1 | Spring | 2010 | | 45565 | CS-319 | 1 | Spring | 2010 | | 83821 | CS-319 | 2 | Spring | 2010 | | 10101 | CS-347 | 1 | Fall | 2009 | | 98345 | EE-181 | 1 | Spring | 2009 | | 12121 | FIN-201 | 1 | Spring | 2010 | | 32343 | HIS-351 | 1 | Spring | 2010 | | 15151 | MU-199 | 1 | Spring | 2010 | | 22222 | PHY-101 | 1 | Fall | 2009 | +-------+-----------+--------+----------+------+ 15 rows in set (0.00 sec) mysql> select * -> from course; +-----------+----------------------------+------------+---------+ | course_id | title | dept_name | credits | +-----------+----------------------------+------------+---------+ | BIO-101 | Intro. to Biology | Biology | 4 | | BIO-301 | Genetics | Biology | 4 | | BIO-399 | Computational Biology | Biology | 3 | | CS-101 | Intro. to Computer Science | Comp. Sci. | 4 | | CS-190 | Game Design | Comp. Sci. | 4 | | CS-315 | Robotics | Comp. Sci. | 3 | | CS-319 | Image Processing | Comp. Sci. | 3 | | CS-347 | Database System Concepts | Comp. Sci. | 3 | | EE-181 | Intro. to Digital Systems | Elec. Eng. | 3 | | FIN-201 | Investment Banking | Finance | 3 | | HIS-351 | World History | History | 3 | | MU-199 | Music Video Production | Music | 3 | | PHY-101 | Physical Principles | Physics | 4 | +-----------+----------------------------+------------+---------+ 13 rows in set (0.00 sec) mysql> select * -> from teaches,course; +-------+-----------+--------+----------+------+-----------+----------------------------+------------+---------+ | ID | course_id | sec_id | semester | year | course_id | title | dept_name | credits | +-------+-----------+--------+----------+------+-----------+----------------------------+------------+---------+ | 76766 | BIO-101 | 1 | Summer | 2009 | PHY-101 | Physical Principles | Physics | 4 | | 76766 | BIO-101 | 1 | Summer | 2009 | MU-199 | Music Video Production | Music | 3 | | 76766 | BIO-101 | 1 | Summer | 2009 | HIS-351 | World History | History | 3 | | 76766 | BIO-101 | 1 | Summer | 2009 | FIN-201 | Investment Banking | Finance | 3 | | 76766 | BIO-101 | 1 | Summer | 2009 | EE-181 | Intro. to Digital Systems | Elec. Eng. | 3 | | 76766 | BIO-101 | 1 | Summer | 2009 | CS-347 | Database System Concepts | Comp. Sci. | 3 | ··· | 22222 | PHY-101 | 1 | Fall | 2009 | CS-190 | Game Design | Comp. Sci. | 4 | | 22222 | PHY-101 | 1 | Fall | 2009 | CS-101 | Intro. to Computer Science | Comp. Sci. | 4 | | 22222 | PHY-101 | 1 | Fall | 2009 | BIO-399 | Computational Biology | Biology | 3 | | 22222 | PHY-101 | 1 | Fall | 2009 | BIO-301 | Genetics | Biology | 4 | | 22222 | PHY-101 | 1 | Fall | 2009 | BIO-101 | Intro. to Biology | Biology | 4 | +-------+-----------+--------+----------+------+-----------+----------------------------+------------+---------+ 195 rows in set (0.00 sec) ```
(2)join...using
-
使用指定属性对关系实例进行连接
-
使用形式:from A join B using (属性名) 必须要加括号
-
输入:2个关系和使用的属性名
如果使用的属性名不是都拥有的属性,则出错
-
输出:对参数中某属性值相同的做元组笛卡尔乘积,相同属性不重复显示
mysql> select * //特殊情况
-> from teaches join course using (ID);
ERROR 1054 (42S22): Unknown column 'ID' in 'from clause'
(3)natural join
- 自然连接:使用所有同名属性对关系进行连接
- 使用形式:from A natural join B
- 输入:两个有顺序的关系
- 输出:对参数中所有相同属性值相同元组做笛卡尔乘积,相同属性不重复显示
mysql> select * //自然连接
-> from teaches natural join course;
+-----------+-------+--------+----------+------+----------------------------+------------+---------+
| course_id | ID | sec_id | semester | year | title
| dept_name | credits |
+-----------+-------+--------+----------+------+----------------------------+------------+---------+
| BIO-101 | 76766 | 1 | Summer | 2009 | Intro. to Biology
| Biology | 4 |
| BIO-301 | 76766 | 1 | Summer | 2010 | Genetics
| Biology | 4 |
| CS-101 | 10101 | 1 | Fall | 2009 | Intro. to Computer Science | Comp. Sci. | 4 |
mysql> select * //普通连接
-> from teaches join course using (course_id);
+-----------+-------+--------+----------+------+----------------------------+------------+---------+
| course_id | ID | sec_id | semester | year | title
| dept_name | credits |
+-----------+-------+--------+----------+------+----------------------------+------------+---------+
| BIO-101 | 76766 | 1 | Summer | 2009 | Intro. to Biology
| Biology | 4 |
| BIO-301 | 76766 | 1 | Summer | 2010 | Genetics
(4) outer join
- 当两个关系有元组从未被连接时,将他们显示在结果中,缺省的属性填null
- 形式:A left/right/full outer +任何情况下使用的join B
- left: 保留左边关系中的未参与连接元组
- right:保留右边关系中的未参与连接元组
- full: 两边的关系中的未参与连接元组都保留
流程:在A中关系中拿出一个元组与B进行遍历连接时,如果全部为false,保留这个元组
Ps.inner join的定义与outer join相反,不保留未连接元组没有写outer join的时候,默认是inner join
(5)join...on
- 用谓词进行连接
- 使用形式:A 任何形式的join B on 谓词
- 对A中的每一个元组,在B中进行谓词检查,成功的连接起来
Ps.on的作用和where类似,on是在连接时筛选元组,是连接流程的一部分
where则在连接完成后筛选元组,是单独的一个子句
但当使用到外连接时,前者会保留未匹配元组,而where则会删除,因为缺省的是null
3.3.3 where子句
-
对关系实例进行筛查
-
使用形式:where 谓词
-
输入:谓词
SQL中的谓词有
>,<,<=,>=,=并且支持逻辑连词
and,or,not可以使用
属性between A and B来代替属性>A&&属性<B -
输出:上面连接产生的新的关系实例经谓词作用后的关系实例
-
执行过程:
where的执行是在连接后执行,步骤大致如下
(1)取出第一条元组
(2)判断谓词是否成立,成立则保留,否则抛弃
(3)取下一条元组,返回步骤(2)
mysql> select *
-> from teaches,course
-> where ID=10101;
+-------+-----------+--------+----------+------+-----------+----------------------------+------------+---------+
| ID | course_id | sec_id | semester | year | course_id | title | dept_name | credits |
+-------+-----------+--------+----------+------+-----------+----------------------------+------------+---------+
| 10101 | CS-347 | 1 | Fall | 2009 | BIO-101 | Intro. to Biology | Biology | 4 |
| 10101 | CS-315 | 1 | Spring | 2010 | BIO-101 | Intro. to Biology | Biology | 4 |
| 10101 | CS-101 | 1 | Fall | 2009 | BIO-101 | Intro. to Biology | Biology | 4 |
3.3.4 聚集函数
作用:对关系实例中的group进行统计操作,产生的效果是将具有多个元组的group聚集成一个元组
输出形式:|group属性|统计结果|
关键字:
- avg()
- min()
- max()
- sum()
- count()
3.3.5 组操作子句
(1)group by关键字
-
对关系实例进行分组
-
使用形式:group by 属性
-
输入:属性
-
输出:按聚集函数进行输出
如果没有聚集函数,默认输出每组的第一个元组
(2)having关键字
-
对分组筛查
-
使用形式:having 谓词
-
输入:谓词和聚集函数
-
输出:显示具有满足谓词的元组的组
mysql> select course_id,count(*) as count -> from teaches -> group by course_id -> having count(*)<2; +-----------+-------+ | course_id | count | +-----------+-------+ | BIO-101 | 1 | | BIO-301 | 1 | | CS-315 | 1 | | CS-347 | 1 | | EE-181 | 1 | | FIN-201 | 1 | | HIS-351 | 1 | | MU-199 | 1 | | PHY-101 | 1 | +-----------+-------+ 9 rows in set (0.00 sec) mysql> select * -> from teaches -> group by course_id -> having ID<76766; +-------+-----------+--------+----------+------+ | ID | course_id | sec_id | semester | year | +-------+-----------+--------+----------+------+ | 10101 | CS-101 | 1 | Fall | 2009 | | 10101 | CS-315 | 1 | Spring | 2010 | | 45565 | CS-319 | 1 | Spring | 2010 | mysql> select * //没有聚集函数,默认输出每组第一个 -> from teaches -> group by semester; +-------+-----------+--------+----------+------+ | ID | course_id | sec_id | semester | year | +-------+-----------+--------+----------+------+ | 76766 | BIO-101 | 1 | Summer | 2009 | | 10101 | CS-101 | 1 | Fall | 2009 | | 45565 | CS-101 | 1 | Spring | 2010 | +-------+-----------+--------+----------+------+ 3 rows in set (0.00 sec)
3.3.6 select子句
-
从处理好的关系实例中提取出一些属性
-
使用形式:select <属性名1,属性名2...属性名n>,<聚集函数1,聚集函数2...聚集函数n>
-
输入:属性名和聚集函数
Ps.如果有聚集函数,属性名必须是group by中的属性
因为聚集函数是对group进行统计操作,最终结果是|group属性|统计结果|,无法显示非组属性之外的属性名
-
输出:显示具有满足谓词的元组的组
-
执行过程:
(1)打印属性名,即select后的字符串
(2)取处理好的关系的第一个元组,找出属性值打印并换行
(3)取下一条元组返回(2)
3.3.7 order by子句
- 按指定属性升序或降序输出结果
- 形式:order by 属性 (desc/asc)
- asc升序,desc降序,默认是升序
如果没有group by对关系实例进行分组,则整个关系视为一组
3.3.8附加的基本运算
1、更名运算:as
2、字符串运算
SQL中大小写敏感
允许使用多种函数
使用(not )like模式匹配:
- %:匹配任意子串
- _:匹配任意一个字符
- escape ’字符‘:自定义转义字符
3、所有属性*
4、集合运算
- union:并
- intersect:交
- except:差
Ps.集合运算默认不保留重复值,可以再关键词后加all保留关键词
3.4 嵌套子查询
3.4.1 分类
- 标量子查询:查询得到的关系只有一个元组,这个元组只有单个属性,程序将该关系视作标量来使用
- 多值子查询:查询得到的关系有多个元组
SQL中可以在任何可能出现关系和标量的地方用子查询替代
3.4.2 where子查询嵌套
-
前提:在where执行的过程中是取出每一条元组进行筛选,所以在where子句中的子查询只能看到该元组
在依赖于外部的子查询中,也只能看到该元组,示例:
select S.ID,S.name from student as S where exist (select T.course_id from takes as T where year=2009,semester=fall,S.ID=T.ID);该例中的where语句取到一条元组,在子查询中S就只代表这一条元组而非student表,子查询则取出每一条takes的元组,用id与该student中的元组进行比较,如果存在该课程就返回true
则该sql语句的作用是查询在2009年秋季学期上了课的学生
由于where中涉及判断,因此需要一些关键字对元组和元组集做逻辑判断,可以类比集合与元素的判断
-
(not) in关键字:判断该元组是否在子查询返回的元组中
-
比较关键字:子查询可能返回一个元组集,与一个元组作比较,SQL提供了以下几个取值策略
-
(not) some:代表某个元组,如where salary>some(子查询),则该元组的salary只要大于一个子查询的salary就返回true
=some<=>于in
-
(not) all:代表所有元组,如where salary>all(子查询),则该元组的salary必须大于所有子查询的salary才返回true
<>all<=>not in
-
-
(not) exist:子查询结果是否为空,一般是依赖于外部子查询,调用子查询中的元组是否于子查询的表有某种关系
-
(not) unique:用于测试子查询的结果中是否存在重复元组
3.4.3 from子查询
可以使用任何返回值是关系的子查询
3.4.4 select子查询
可以使用任何标量子查询
因为select实际上在元组中找属性名对应的标量,调用标量子查询直接提供该标量,打印
3.5 空值null
null代表该属性没有值,在定义关系时未在属性后标注not null则可以是null
3.5.1 null的逻辑运算
unknown是一个新的bool值,其相关逻辑运算:
- unknown and true=unknown
- unknown and false=false
- unknown or true =true
- unknown or false =unknown
- not unknown=unknown
总的来说,true>unknown>false
如果比较运算如> < >= = <=中任何一个输入是null/unknown,则表达式的结果是unknown
null=null返回unknown而不是ture
要判断一个值是否是null要使用is/not null/unkonwn
3.5.2 null的算术运算
有null值的元组属性的任何运算都为null
3.6 元组更新(DML2)
3.6.1 插入操作
//给属性项插入对应属性值
insert into 表名 <属性项> //为空则默认使用表的属性顺序来对应
values(<属性值>) //value值也可以换成子查询来批量插入,没有bulk loader快
/子查询;
如果在插入时只提供了部分属性的值,且其余的值可以是null,则为空
3.6.2 删除操作
delete from 表名
where P//可以使用嵌套,where为空则全部删除
3.6.3 更新操作
//给部分属性批量更新值
update 表明
set 属性=表达式
where 谓词 //确定要更新的元组
update 表名
set 属性= case
when ··· then ···
when ··· then ···
···
when ··· then ···
else ···
end
3.7 视图
3.7.1 定义
不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为视图,一个面向用户的个人化关系集合,相当于给一个查询逻辑起一个别名
虚关系:首先是一个关系,也就是一张表,
其次虚代表这个表在数据库中并没有物理实体,而用查询语句定义,在需要用到的时候才执行查询语句物化成一张表
一个数据库可能有不同的用户操作,不同用户有不同的权限,视图就代表读的权限不同
比如电脑中管理员账户能看到所有数据,普通账户只能看到自己的数据,就可以提前规定查询语句,用户查看的时候再执行它
3.7.2 定义视图
creat view viewName as
sql查询语句
3.7.3 使用视图更新关系
可更新性:
3.8 权限
3.8.1 用户和角色
用户代表操作此数据库的账户实体
角色是一类具有相同特性的用户集
即授权是某角色授予的,而非该用户
可以批量管理角色下用户的权限,这种分类给数据库管理带来很大的好处
sql中的任何权限操作都可以由用户/角色对用户/角色进行权限授予或收回
- 可以授予用户某个角色
- 可以授予角色某个角色
即存在角色链,一个角色的权限分为两部分,直接给这个角色授予的权限和该角色拥有的角色的权限
一个用户的权限分为两部分,直接给这个用户授予的权限和该用户所具有角色的权限
create role 角色;
grant 角色 to 角色;
grant 角色 to 用户;
3.8.2 权限分类
1、数据权限
-
all priviledges
-
select
-
insert
-
delete
-
update(属性)
2、模式授权
只有模式的拥有者才能对模式进行任意的修改
reference授权:允许用户创建关系时声明外码
外码意味着该表具有参照完整性约束,在对该表进行操作时会级联到别的表上
3.8.3 授权
grant <权限列表>
on <关系/视图名>
to <用户列表/角色列表>
(with grant option) //允许将该授权的权限授权给别人
(granted by current role) //使用当前角色授权
with grant option代表允许将这个授权的权限授权给别人,这样的操作的结果是存在复杂的权限图
判断一个用户或角色是否拥有一个权限的方法是看图中该权限是否有一条从根到该节点的路径
使用授权语句的前提是:授权方必须有该权限,并且该权限允许被授予给其他人(with grant option)
且授权可以使用当前角色而非当前用户来授权,这样在权限收回时,不会因为该用户的权限被收回,而导致其授权被级联收回
3.8.4 在给定权限下创建视图
视图是由查询语句构成的虚实体,内部就是sql查询语句
自然用户创建的视图时使用的SQL语句不能超出该用户的权限
3.8.5 权限的收回
revoke 权限名
from <用户列表/角色列表>
(restrict) //不级联收回
由于存在权限图,在收回一个用户或角色的权限时,要级联的收回其授予给别的用户的权限
用户权限被收回,则revoke时级联收回该用户授予的所有权限
角色权限被收回,则revoke时先收回所有该角色用户的权限,再级联收回这些用户使用该角色授予的所有权限
这样做的好处是,权限被赋予了角色的属性,如果某用户注销了账户,其角色的授权不会被收回
第三章 形式化关系查询语言
第四章 E-R模型
一、基本要素
是通过允许定义数据库全局罗及结构的企业模式实现的
三个基本要素:
- 属性
- 实体集
- 联系集
实体集的概念属性所组成的关系表示
联系集的概念由实体集所组成的关系表示
二、属性
2.1 定义
是一种描述性性质,有一个可取值范围,称为值集(域)
2.2 分类
- 简单(simple)和复合(composite)属性:
- 单值和多值属性:多值属性用
|属性|来表示 - 派生属性:由已有属性派生出来的属性,比如为属性求和,求差等
三、实体集
3.1 实体
是现实中可区别于其他所有对象的一个事务或对象
通过一组属性来表示
3.2 实体集
是相同类型即具有相同性质的一个实体集合
四、联系集
3.1 联系
多个实体间的关联,比如(X,Y)表示X和Y的联系
3.2 联系集
实体集间相同类型联系的集合,是联系组成得到的关系
参与
角色:实体在联系中的作用
描述性属性:除了实体中的属性其他的属性
3.3 约束
3.3.1 映射基数
表示实体集中一个实体通过一个联系能关联的实体个数,暂且只研究二元联系集上
- 一对一
- 一对多
- 多对一
- 多对多
3.3.2 参与约束
- 全部的(total):形容实体集中的每个实体都联系集的至少一个联系中
- 部分的(Partial)
3.3.3 联系集的码
联系集的超键是实体集的主键和描述性属性的并集
由于联系集的主键与映射基数有关,超过二元的映射基数还未讨论
下面认为超键是主键,主键为属性名加下划线来表示:属性
3.4 联系集的构建
对于两个实体集直接拼接属性构成的联系集,需要删除冗余属性
一般删除的是是关系中的超键,因为超键是可以被联系集替代的
超键代表一个参照实体中的实体对应一个被参照的实体集中的实体
我们在构建联系时不知道基数,不能认为只对应一个实体
联系集的表示范围更大
3.5E-R图
第五章关系数据库设计
-
数据冗余
-
更新异常
-
插入异常
-
删除异常
函数依赖
X->Y x中每个元素,y中有唯一值与之对应
-
平凡的函数依赖X->Y Y包含于X
-
不平凡的函数依赖X->Y Y不包含于X
-
完全函数依赖 X不能再小
-
部分函数依赖 x可以再小
候选码的计算方法
-
只出现在左边的一定是候选码
-
只出现在右边的一定不是候选码
-
左右都出现/都不出现的不一定是候选码
求确定候选码的闭包,如果能推出全部属性,当前确定的就是候选码 否则把每个可能的值放进当前确定的候选码中求闭包,能求,则一定是候选码
范式
1NF:所有属性字段都是原子的
3NF:不包含非主属性对码的传递函数依赖,确保数据表中的每一列数据都于主键直接相关,不能间接相关
BCNF:修正的第三范式,消除每一个属性对候选键的传递依赖,即候选键不能推出候选键,这样肯定有属性荣誉,因为中间的非主键属性可以推出主键
公理及推论
- 自反律
- 传递律
- 增补律
- X->Y X->Z 则 X->YZ
- X->Y WY->Z 则 XW->Z
- X->Y Z包含于Y 则X->Z
求最小函数依赖集(正则覆盖)
- 右边多个元素的函数依赖拆开
- 对所有依赖,去掉该依赖,若剩下的范式还是能推出右边的属性,这个函数依赖就是冗余的
- 对左边有多个属性的依赖
- 遮住该依赖中左边的某个属性,剩下的属性能推出该属性这个属性是冗余的,删除这个属性
模式分解准则
- 无损连接:分解后再次连接和分解之前一样
- 保持函数依赖:函数依赖关系不变
求保持函数依赖的3NF的分解
- 求出最小函数依赖集Fmin
- 把不在Fmin中的属性单独找出来,这些属性与其他属性没有依赖关系
- 把每个函数依赖左边相同的分为一类
- 求候选码
- 如果候选码没出现在分类中,把任意一个候选码作为一类