数据库复习笔记. pdf版本可以在这里下载: 下载链接
感谢我院三位教授数据库的老师. 感谢赵小林老师高抬贵手给了100分呜呜呜呜
文章结构:
主要根据英文班的ppt顺序写的,一级标题每个序号对应一个ppt, 之后是该章ppt的名字, 之后是该章涉及的主要的知识点. 二级标题对应这章的一个详细知识点.
文章目录
- 1 intro: 数据库的作用/DBMS的定义/两种data model/数据独立性data independence/concurrency control并发控制(使用加锁协议)/crash recovery(存储备份)/数据库的分层架构以及其应用
- 2 E/R: 实体,实体集,属性/ER图的实体,属性,关系(多对多,多对一,一对一),关系集,关系的属性,弱实体集,键,子类/关系的角色roles/子类,ER子类与OO子类的区别/键keys/弱实体集定义,两个约定/数据库设计的三个法则,数据冗余,使用实体而非属性的两种情况/关系可合并的两种情况,RE图转关系模型:实体的变换,属性的变换,关系的变换,弱实体集的变换,带有子类的ER图的三种转换法
- 3 fd: 函数依赖functional dependence的定义,右部分解/键与超键/依赖的推导,闭包closure的推导,利用closure判断依赖是否存在,隐含依赖的推导,规范化normalization, nontrival fd非平凡函数依赖/依赖的投影projected FD,求依赖投影的简单指数算法exponential algorithm,两个技巧/3种异常, 判断无损分解, 分解的评判标准与chase检测/BCNF的定义,BC的分解/minimal basis最小函数依赖集的求法,prime主属性3NF的定义,3NF的合成(3NF synthesis),BC和3NF的比较/完全函数依赖(full function dependence)/2NF,1NF的定义与判断
- 3_2 fd的公理系统: 基本符号:关系模式,函数依赖的闭包,属性集的闭包,最小函数依赖集/Armstrong的3条规则和3个推理/闭包的计算,求闭包算法的循环次数/FD等价与FD覆盖
- 4 MVD多值依赖: MVD的定义,平凡多值依赖与非平凡多值依赖,MVD的6个性质,MVD与FD的关系/4NF的定义,4NF与BCNF的对比,4NF的分解/MVD或FD是否存在的判断(使用表格,或利用传递性)
- 5 Relational Algebra (ra 关系代数) : relational algebra的定义,操作数operand与算子operation/核心关系代数:selection,projection,product and join,rename,执行结果/表达式的构建,表达式的三种写法,算符优先级/包bag定义,与集合的区别,包与集合上操作的不同之处
- 6 数据库-连接库: SQL注入/基于库libraries的SQL接口/三层架构/php游标cursors
- 7 SQL intro: select-from-where/使用as重命名/模糊查询的两种模式/空值null的两种含义/三值逻辑/多重关系查询:定义,方法/self-join查询同一关系中的两个不同对象/子查询描述,返回值/in(与普通query的区别),exists,any,all,union,intersect,except用法,语句的值,用在哪里/基于包执行的操作,基于集合执行的操作/消除重复项duplicate elimination--distinct/join操作: 笛卡尔积,自然连接,theta连接
- 8 ra-sql: 拓展关系代数:包去重,排序/悬挂元组dangling,内连接,外连接:左外连接,右外连接,全连接/聚集aggregation:sum,max,min,avg,count,以及与distinct的结合,聚集中的空值/分组,使用分组对select进行限制,分组中的聚集函数,使用分组的两个必须条件/having的使用以及规则,后面跟随的条件/数据库插入(普通插入,批量插入,利用子查询插入),删除(全部删除,部分删除),更新(全部更新,条件更新),缺省
- 9 约束constraint: 约束的定义,种类/外键的定义,外键表达方式,维护外键约束的3种方式(default,cascade,Null(缺省,级联,置空))以及选择策略/三种检测(attribute-based, Tuple-based, assertion断言)的方式,时机/触发器trigger描述,使用时机,创造规则:event-condition-action
1 intro: 数据库的作用/DBMS的定义/两种data model/数据独立性data independence/concurrency control并发控制(使用加锁协议)/crash recovery(存储备份)/数据库的分层架构以及其应用
数据库的作用
- store huge amount of data over a long time
- allow apps to query and update data
- protect from unauthorized access
- protect form system crash
- protect from incorrect input
- support concurrent access
- allow administrator to change data
- different database operation
DBMS定义
a software to store and manage data, so applications don’t have to worry about them
- DDL
- DML
- storage management
- transaction management(交易/事物管理)
- security, efficiency, scalability(可扩展性)
两种data model
- E/R
- relational model(表, 元祖…)
数据独立性data indenpendence
DBMS的分层架构包括一些views, 一个概念层conceptual schema, 一个物理层physical schema. 各层之间改变某一层的数据仅对其上层造成影响
并发控制
- 解决: 加锁locking protocol
crash recorvery
- 解决: 使用日志log, 所有对数据的写操作记录在日志中,存在稳定的存储系统里(stable storage)
数据库的分层架构
- 二层: ODBC, JDBC
- 三层: 基于Web的应用程序
2 E/R: 实体,实体集,属性/ER图的实体,属性,关系(多对多,多对一,一对一),关系集,关系的属性,弱实体集,键,子类/关系的角色roles/子类,ER子类与OO子类的区别/键keys/弱实体集定义,两个约定/数据库设计的三个法则,数据冗余,使用实体而非属性的两种情况/关系可合并的两种情况,RE图转关系模型:实体的变换,属性的变换,关系的变换,弱实体集的变换,带有子类的ER图的三种转换法
实体,实体集,属性
- 实体entities: “thing” or object
- 实体集 entity set: 实体的集合
- 属性attribute: property(属性) of an entity set
E/R图的实体,属性,关系(多对多,多对一,一对一),关系集reletionship set
- 实体: 矩形
- 属性: 椭圆
- 关系: 菱形, 直线连接形成关系的实体
- 多对多: 不带箭头(一个酒吧卖很多种酒, 一种酒杯很多酒吧卖)
- 多对一: 指向一(一个人只有一款最喜欢的酒, 一款酒可以被很多人最喜欢)
- 一对一: 双向箭头(一个人只有一个老婆,反之也是)
- 关系集: 一张表, 里面有关系中各属性的值, 一行为一个元组, 可以有多行
- 键: 在相应属性下方画横线
- 关系的属性: 由形成关系的双方共同确定
- 弱实体集: 箭头指向弱实体集所依赖的实体
- 实体: 双框矩形
- 关系: 双框菱形
- 键: 在代表键的属性下画横线, 包括自己的键和依赖实体集的键
- 子类: 用带isa三角形的箭头从子类指向父类
- 实体: 矩形
- 属性: 椭圆,只标明子类特有属性
- 键: 只有基类实体有键, 并且该键作用于整个继承机制的所有类
关系的角色role
在ER图的边旁标识, 对关系中多次出现的实体进行定义
子类,ER子类与OO子类的区别
- 子类 = 特殊情况 = 更少的实体, 更多的属性
- ER子类与OO子类的区别
- OO: 子类继承自父类,其对象实体只属于一个类(objects are in one class only)
- ER: 子类的对象在子类和父类中都存在(E/R entity has representatives in all subclasses which they belong)
键
- 键: 键是关系集中的一组属性, 若两个元组的键值相同, 则其他非键属性必定相同
A key is a set of attributes for one entity set such that no two entities in this set agree on all the attributes of the key.
弱实体集weak entity定义, 两个约定
- 弱实体集: 为了唯一标识一个实体集中的实体, 需要依赖其本身的键以及一个或多个多对一关系中的另一个实体集的键.
- 约定:
- 弱实体集与依赖的实体集之间存在一个或多个多对一关系
- 弱实体集的键包括其本身的键和所依赖的实体集的键
数据库设计的三个法则, 数据冗余,使用实体而非属性的两种情况
- 数据库设计的三个法则
- 避免冗余(avoid redundancy)
- 尽量避免弱实体集的使用(limit the use of weak entity sets)
- 能用属性就不用实体(don’t use an entity set when an attribute will do)
- 数据冗余: 使用不同的方法描述同一件事物(saying the same thing in two different ways)
- 使用实体的两种情况
- 包含的属性不仅仅是名字,或含有至少一个非主属性
- 在多对多或多对一关系中属于"多"
关系可合并的两种情况,RE图转关系模型:实体的变换,属性的变换,关系的变换,弱实体集的变换,带有子类的ER图的三种转换法
- 关系可合并两种情况
- 同一实体集中的关系可合并
- 多对一关系中的"多"可合并
-
Drinkers(name, addr) Favorite(drinker, beer) 合并为: Drinker1(name, addr, favbeer)
-
- ER图转关系模型
- 实体集 -> 关系
- 关系 -> 关系(仅包含构成关系的各实体集的键)
- 弱实体集 -> 关系:
- 用实体表示关系而非关系表示关系
- 形成弱实体集的关系, 其依赖的实体集的关系
- 弱实体集形成的关系属性包含弱实体集的全部属性和其依赖的实体集的键
- 带有子类的ER图转换的3种方法:
- OO: 每个子类都是一个关系, 包含父类以及子类自己的全部属性
- use Null: 只有一个关系, 包含子类和父类的所有属性, 其中父类对象不具有的子类属性用null代替
- ER: 一个子类一个对象, 包含父类的键值和子类自己的全部属性
3 fd: 函数依赖functional dependence的定义,右部分解/键与超键/依赖的推导,闭包closure的推导,利用closure判断依赖是否存在,隐含依赖的推导,规范化normalization, nontrival fd非平凡函数依赖/依赖的投影projected FD,求依赖投影的简单指数算法exponential algorithm,两个技巧/3种异常, 判断无损分解, 分解的评判标准与chase检测/BCNF的定义,BC的分解/minimal basis最小函数依赖集的求法,prime主属性3NF的定义,3NF的合成(3NF synthesis),BC和3NF的比较/完全函数依赖(full function dependence)/2NF,1NF的定义与判断
函数依赖functional dependence的定义,右部分解
- 函数依赖: 在关系R中, 如果当属性集X中所有属性值相同时, 属性集Y中的所有属性值也相同, 称关系R中存在函数依赖 X − > Y X->Y X−>Y,简写作FD
X ->Y is an assertion about a relation R that whenever two tuples of R agree on all the attributes of X, then they must also agree on all attributes in set Y.
- Say “X ->Y holds in R.”
- Convention: …, X, Y, Z represent sets of attributes; A, B, C,… represent single attributes.
- Convention: no set formers in sets of attributes, just ABC, rather than {A,B,C }.
- 函数依赖的右部分解: 右部可分左部不可分, 通常右部表示为单一属性集
键与超键
- s u p e r k e y superkey superkey: 由 s u p e r k e y superkey superkey中属性可推出关系的全部属性
- k e y key key: 最小 s u p e r k e y superkey superkey集
依赖的推导,闭包closure的推导,利用closure判断依赖是否存在,隐含依赖的推导, nontrival fd非平凡函数依赖
- 依赖的推导: (1)根据传递性( X − > Y , Y − > Z ; = > X − > Z X->Y,Y->Z;=>X->Z X−>Y,Y−>Z;=>X−>Z) (2)或找X值相同时值相同的属性,看是否可以用已知的FD推导出来, 是则存在依赖, 不是则不存在
- closure的计算: 可以使用闭包判断属性集之间是否存在依赖关系
- 求属性集
{
A
1
,
A
2
,
.
.
.
,
A
n
}
\{A_1, A_2, ..., A_n\}
{A1,A2,...,An}的闭包, 已知
F
D
FD
FD集
S
S
S:
- 假设U终将成为 { A 1 , A 2 , . . . , A n } \{A_1, A_2, ..., A_n\} {A1,A2,...,An}的闭包,初始化 U = { A 1 , A 2 , . . . , A n } U=\{A_1, A_2, ..., A_n\} U={A1,A2,...,An},分解S中每个FD, 使其右部属性单一化
- 重复搜索这样的函数依赖 B 1 B 2 B 3 . . . B i − > C B_1B_2B_3...B_i->C B1B2B3...Bi−>C, 使左部 { B 1 B 2 B 3 . . . B i } \{B_1B_2B_3...B_i\} {B1B2B3...Bi}都在U中但是右部不在, 则将右部加到U中
- 重复上述过程知道没有属性可以加到U中, 则此时的U就是 { A 1 , A 2 , . . . , A n } \{A_1, A_2, ..., A_n\} {A1,A2,...,An}的闭包
- 求属性集
{
A
1
,
A
2
,
.
.
.
,
A
n
}
\{A_1, A_2, ..., A_n\}
{A1,A2,...,An}的闭包, 已知
F
D
FD
FD集
S
S
S:
- 利用closure判断依赖是否存在: 判断某依赖A->B是否存在关系X中, 只要求出X中A的闭包, 看B是否出现在闭包中
- 隐含依赖的推导: 看属性集中是否存在可由已知FD推导出的其他FD
- Nontrival FD非平凡函数依赖: 左部不包含右部
- normalization函数依赖规范化:
依赖的投影projected FD,求依赖投影的简单指数算法exponential algorithm,两个技巧
- p r o j e c t e d _ F D projected\_FD projected_FD: 给定一个关系和满足的依赖集, 求对部分属性投影后依然成立的依赖集
- 求依赖投影 E x p o n e n t i a l _ A l g o r i t h m Exponential\_Algorithm Exponential_Algorithm
- 输入: 关 系 R , 关 系 R 的 投 影 R i = π L ( R ) , 在 R 中 成 立 的 F D 集 合 S 关系R, 关系R的投影R_i = \pi_L(R), 在R中成立的FD集合S 关系R,关系R的投影Ri=πL(R),在R中成立的FD集合S
- 输出: 在 R i 中 成 立 的 F D 集 合 S i 在R_i中成立的FD集合S_i 在Ri中成立的FD集合Si
- 设 T 为 最 终 输 出 的 F D 集 , 初 始 化 为 空 设T为最终输出的FD集, 初始化为空 设T为最终输出的FD集,初始化为空
- 对 于 R i 属 性 集 和 的 每 一 个 子 集 X i , 根 据 R 中 的 F D 计 算 X i + 对于R_i属性集和的每一个子集X_i, 根据R中的FD计算{X_i}^+ 对于Ri属性集和的每一个子集Xi,根据R中的FD计算Xi+ ( 此 时 , 计 算 结 果 可 能 包 含 不 属 于 R i 的 属 性 ) (此时,计算结果可能包含不属于R_i的属性) (此时,计算结果可能包含不属于Ri的属性)
- 找 出 其 中 右 部 A 在 X i + 中 且 属 于 R i 的 所 有 非 平 凡 函 数 依 赖 X − > A , 添 加 到 T 中 找出其中右部A在{X_i}^+中且属于R_i的所有非平凡函数依赖X->A, 添加到T中 找出其中右部A在Xi+中且属于Ri的所有非平凡函数依赖X−>A,添加到T中
- 最 小 化 T : 不 断 重 复 下 列 两 个 步 骤 知 道 T 不 变 最小化T:不断重复下列两个步骤知道T不变 最小化T:不断重复下列两个步骤知道T不变
- 如 果 T 中 某 个 依 赖 F 能 从 T 中 其 他 F D 推 导 出 来 , 则 删 除 F 如果T中某个依赖F能从T中其他FD推导出来, 则删除F 如果T中某个依赖F能从T中其他FD推导出来,则删除F
- 如 果 T 中 有 Y − > B , Y 中 至 少 有 两 个 属 性 , 删 除 Y 中 一 个 属 性 Z , 如果T中有Y->B,Y中至少有两个属性,删除Y中一个属性Z, 如果T中有Y−>B,Y中至少有两个属性,删除Y中一个属性Z, 并 发 现 由 T 中 其 他 F D 可 以 推 出 Z − > B , 则 用 Z − > B 代 替 Y − > B 并发现由T中其他FD可以推出Z->B,则用Z->B代替Y->B 并发现由T中其他FD可以推出Z−>B,则用Z−>B代替Y−>B
-
- 计算闭包: 先计算单属性, 再计算双属性, 三属性, 四属性…
- 最小化:
- 如果投影后某函数依赖可以由其他依赖推导出,则删除
- 如果某个依赖删除右部某个属性后左部依然成立, 则删除右部那个属性
- 两个技巧:
- 空集和key的闭包不需要计算
- 如果某属性X的闭包包含全部属性, 则不需要再计算X与其他属性的组合的闭包
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-avA6nCBM-1582017347878)(2020-01-10-20-23-45.png)]
3种异常, 判断无损分解, 分解的评判标准与chase检测
- 异常:
- 冗余redundance
- 更新异常: 对象的一个值被更改, 但并非所有该对象的值都被更改
- 删除异常: 删除元组时所有该对象的记录都丢失,导致对象明明存在但是在数据库中无影无踪
- 无损分解的判断: 如 果 R 1 ⋂ R 2 是 R 1 或 R 2 的 s u r p e r k e y , 则 R 上 的 分 解 ( R 1 , R 2 ) 是 无 损 分 解 如果R_1\bigcap R_2是R_1或R_2的surperkey, 则R上的分解(R_1, R_2)是无损分解 如果R1⋂R2是R1或R2的surperkey,则R上的分解(R1,R2)是无损分解
- 分解的评判标准
- 消除异常
- 无损连接: 分解后再连接是否和原来的关系一致
- chase检测
- 依赖保持: FD的投影在分解的关系中成立,但是自然连接后不能满足原来的FD
BCNF的定义,BC的分解
- BCNF: 凡是关系R中的非平凡函数依赖,其右部都是R的surperkey
- BC的分解
- 找到当前关系中的键
- 在关系所给FD中随便选一个违反BC(右部不是键的非平凡依赖)的FD, 如果找不到, 该关系不需要分解,返回原FD,算法结束;否则到3
- 对于违反BC的每一个FD, 根据上层关系的FD求右部属性 R i R_i Ri的闭包 R i + {R_i}^+ Ri+, 将关系的属性分解为 S 1 = R i + ; S 2 = R − R i + + R i S_1 = {R_i}^+;S_2 = R - {R_i}^+ + R_i S1=Ri+;S2=R−Ri++Ri, 将上层FD分别投影到 S i S_i Si中, 对于每一个 S i S_i Si以及投影到他上面的函数依赖, 执行1
minimal basis的求法,prime,3NF的定义,3NF的合成(3NF synthesis)
- minimal basis最小函数依赖集求法
- 右部属性单一化: 分拆右部
- 左部属性最小化: 逐一去掉FD,看剩下的FD是否能够得到刚去掉的FD, 能则刚去掉的FD是多余的,复杂度 O ( n 2 ) O(n^2) O(n2)
- 无多余函数依赖: 若 X − > A X->A X−>A,且 X = B 1 B 2 . . . B n X=B_1B_2...B_n X=B1B2...Bn,逐一检查 B i B_i Bi, 若 A ∈ ( X − B i ) F + A \in{(X - B_i)_F}^+ A∈(X−Bi)F+, 则以 X − B i X-B_i X−Bi取代 X X X
- prime: key的成员
- 3NF: 左部是superkey或者右部是主属性
- 3NF的合成
- 求关系函数依赖FD的最小基本集G
- 求关系的键
- 对于G中每一个FD: X − > A X->A X−>A, 将左右部放在一起形成一个关系模式 X A XA XA
- 查看所有生成的关系模式中是否包含键, 如果包含,则不需要操作, 直接返回 X A XA XA集作为结果;否则,添加一个键作为一个关系模式,与 X A XA XA们一起作为结果返回
- BC和3NF的比较
- BC: 无损连接lossless join
- 3NF: 无损连接lossless join + 依赖保持dependency preservation
完全函数依赖(full function dependence)
FD: X − > Y X->Y X−>Y的左部最小
2NF,1NF的定义与判断
- 2NF: 每一个非主属性只由主属性决定
- 1NF: 每个属性都保持原子性(每一列都是不可分割的数据项)
3_2 fd的公理系统: 基本符号:关系模式,函数依赖的闭包,属性集的闭包,最小函数依赖集/Armstrong的3条规则和3个推理/闭包的计算,求闭包算法的循环次数/FD等价与FD覆盖
基本符号: 关系模式,函数依赖的闭包,属性集的闭包
- 关系模式: R ( U , F ) { U : 关 系 R 上 的 属 性 总 体 F : 关 系 R 上 的 函 数 依 赖 R(U, F)\begin{cases} U: &关系R上的属性总体\\ F: &关系R上的函数依赖 \end{cases} R(U,F){U:F:关系R上的属性总体关系R上的函数依赖
- 函数依赖的闭包: F + : R ( U , F ) 中 所 蕴 含 的 函 数 依 赖 全 体 F^+: R(U, F)中所蕴含的函数依赖全体 F+:R(U,F)中所蕴含的函数依赖全体
- 属性集的闭包: X F + : 所 有 能 由 R ( U , F ) 中 的 函 数 依 赖 导 出 的 右 部 的 集 合 {X_F}^+ : 所有能由R(U,F)中的函数依赖导出的右部的集合 XF+:所有能由R(U,F)中的函数依赖导出的右部的集合
- 最小函数依赖集:
F
m
:
通
过
右
部
单
一
化
,
左
部
最
小
化
,
消
除
多
余
函
数
依
赖
得
到
的
函
数
依
赖
集
F_m: 通过右部单一化,左部最小化,消除多余函数依赖得到的函数依赖集
Fm:通过右部单一化,左部最小化,消除多余函数依赖得到的函数依赖集
- 最小函数依赖集不一定唯一
Armstrong的3条规则和3个推理
- Armstrong的3条规则: 自反, 增广, 传递
- Armstrong的3个推理: 合并,伪传递, 分解
闭包的计算,求闭包算法的循环次数
- 闭包的计算: 求 属 性 集 X ( X ∈ U ) 关 于 U 上 的 函 数 依 赖 集 F 的 闭 包 X F + 求属性集X(X \in U)关于U上的函数依赖集F的闭包{X_F}^+ 求属性集X(X∈U)关于U上的函数依赖集F的闭包XF+
输入: X, F
输出: X F + {X_F}^+ XF+
- 令 X ( i ) = X , 此 时 i = 0 X^{(i)} = X, 此时 i = 0 X(i)=X,此时i=0
- 求 B : B 是 以 X i 中 任 意 一 属 性 为 左 部 的 F 中 某 函 数 依 赖 的 右 部 元 素 的 集 合 B: B是以X^i中任意一属性为左部的F中某函数依赖的右部元素的集合 B:B是以Xi中任意一属性为左部的F中某函数依赖的右部元素的集合
- 令 X ( i + 1 ) = X ( i ) ⋃ B X^{(i+1)} = X^{(i)} \bigcup B X(i+1)=X(i)⋃B
- 判断 X ( i ) = = X ( i + 1 ) 或 X ( i + 1 ) = = U ? { y e s − − − − − 算 法 结 束 , X F + = X ( i ) n o − − − − − i = i + 1 , 回 到 2 {X^{(i)} == X^{(i+1) }或X^{(i+1)} == U ? \begin{cases} yes &-----算法结束,{X_F}^+ = X^(i) \\ no &-----i = i+1,回到2 \end{cases}} X(i)==X(i+1)或X(i+1)==U?{yesno−−−−−算法结束,XF+=X(i)−−−−−i=i+1,回到2
- 闭包算法最大循环次数: ∣ U ∣ − ∣ X ∣ |U| - |X| ∣U∣−∣X∣
FD等价与覆盖
- FD等价:
F
+
=
G
+
F^+ = G^+
F+=G+(F覆盖G,反之也可以)
- 充要条件: F ∈ G + 且 G ∈ F + F \in G^+ 且 G \in F^+ F∈G+且G∈F+
- 判定: 逐 一 对 F 中 的 F D : X − > Y , 考 察 Y 是 否 在 X G + + 中 逐一对F中的FD:X->Y,考察Y是否在{X_{G^+}}^+中 逐一对F中的FD:X−>Y,考察Y是否在XG++中
4 MVD多值依赖: MVD的定义,平凡多值依赖与非平凡多值依赖,MVD的6个性质,MVD与FD的关系/4NF的定义,4NF与BCNF的对比,4NF的分解/MVD或FD是否存在的判断(使用表格,或利用传递性)
MVD的定义,平凡多值依赖与非平凡多值依赖,MVD的6个性质,MVD与FD的关系
- MVD: 在关系R中X中的属性完全相同时,交换Y中的属性值,其结果依然属于关系R
- 非平凡多值依赖 n o n t r i v a l M V D nontrival MVD nontrivalMVD: X − > − > Y , 其 中 , Y 不 是 X 的 子 集 而 且 X + Y ≠ U X->->Y,其中,Y不是X的子集而且X+Y \ne U X−>−>Y,其中,Y不是X的子集而且X+Y=U
- 平凡多值依赖trival MVD: 不是非平凡MVD
- MVD的6个性质:
- X − > − > Y = > X − > − > ( U − Y − X ) X->->Y => X->->(U-Y-X) X−>−>Y=>X−>−>(U−Y−X)
- X − > − > Y , Y − > − > Z = > X − > − > Z X->->Y, Y->->Z => X->->Z X−>−>Y,Y−>−>Z=>X−>−>Z
- X − > Y = > X − > − > Y X->Y => X->->Y X−>Y=>X−>−>Y
- X − > − > Y , X − > − > Z = > X − > − > ( Y ∪ Z ) X->->Y, X->->Z => X->->(Y \cup Z) X−>−>Y,X−>−>Z=>X−>−>(Y∪Z)
- X − > − > Y , X − > − > Z = > X − > − > ( Y ∩ Z ) X->->Y, X->->Z => X->->(Y \cap Z) X−>−>Y,X−>−>Z=>X−>−>(Y∩Z)
- X − > − > Y , X − > − > Z = > X − > − > ( Y − Z ) 或 ( Z − Y ) X->->Y, X->->Z => X->->(Y - Z)或(Z-Y) X−>−>Y,X−>−>Z=>X−>−>(Y−Z)或(Z−Y)
- MVD与FD的关系
- FD左部不可拆,右部可拆
- MVD左部不可拆,右部不可拆
- FD是特殊的MVD
4NF的定义,4NF与BCNF的对比,4NF的分解
- 4NF: 对于R中每一个非平凡MVD,其左部都是 s u p e r k e y superkey superkey
- 4NF与BC: 满足4NF一定满足BC,反之不成立
- 4NF的分解
- 在MVD中找一个4NF违例 X − > − > Y X->->Y X−>−>Y,找不到则分解结束,返回当前属性集合
- 分解为两个子集 S 1 = X Y , S 2 = X + ( U − Y ) S_1 = XY, S_2 = X+(U-Y) S1=XY,S2=X+(U−Y)
- 分别投影到 S 1 , S 2 S_1,S_2 S1,S2中, 执行1
MVD或FD是否存在的判断(使用表格,或利用传递性),规律小结
- MVD或FD是否存在的判断:
- 问题描述: 给定一个关系R,给出MVDs和/或FDs,求某个MVD或FD是否在关系中
- 解决方法: 将关系用表格的形式表示出来, 查看表格中的元组是否满足函数依赖或多值依赖
- 生成表元素:
- 生成FD数据元素: 两行元组左部属性相同,右部也相同
- 生成MVD数据元素: 两行元组左部属性相同,右部相同,其他属性相同,还有一行左部与其相同,右部交换,其他属性相同
- 已知MDV.FD:
- 证FD(需要证明相同左部,右部相同): 先使用MVD,在已知FD左部相同时交换求证FD右部属性;再使用已知FD,证右部相同
- 证MVD(需要派生出相同左部,右部交换的元组): 连用两次不同MVD,交换使两行元组只有目标MVD右部不同
5 Relational Algebra (ra 关系代数) : relational algebra的定义,操作数operand与算子operation/核心关系代数:selection,projection,product and join,rename,执行结果/表达式的构建,表达式的三种写法,算符优先级/包bag定义,与集合的区别,包与集合上操作的不同之处
relational algebra关系代数的定义,操作数operand与算子operation
- ra: 操作数+算子(由操作数和算子组成的数学系统)
- operand: 操作对象,(属性啥的)
- operation: 算子
核心关系代数:selection,projection, product and join, rename,执行结果
-
s
e
l
e
c
t
i
o
n
selection
selection:
在
属
性
集
R
2
中
选
择
满
足
条
件
C
的
属
性
组
成
集
合
R
1
在属性集R_2中选择满足条件C的属性组成集合R_1
在属性集R2中选择满足条件C的属性组成集合R1
- R 1 : = σ C ( R 2 ) R_1 := \sigma_C(R_2) R1:=σC(R2)
- 结果模式与操作数模式相同(属性个数不变)
-
p
r
o
j
e
c
t
i
o
n
projection
projection:
在
属
性
集
R
2
中
按
顺
序
选
择
L
中
的
属
性
组
成
新
的
集
合
R
1
在属性集R_2中按顺序选择L中的属性组成新的集合R_1
在属性集R2中按顺序选择L中的属性组成新的集合R1
- $R_1 := \pi_L(R_2) $
- 结果由新的属性列构成
- 扩展投影: L可能是一个关于属性的表达式, 可能导致结果中属性重复出现
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OaSXcCVz-1582017470464)(2020-01-11-15-47-30.png)]
- 扩展投影: L可能是一个关于属性的表达式, 可能导致结果中属性重复出现
-
p
r
o
d
u
c
t
product
product笛卡尔积:
按
R
1
(
m
行
)
,
R
2
(
n
行
)
的
顺
序
将
两
个
关
系
的
每
一
行
连
接
起
来
(
m
×
n
行
)
,
同
名
列
前
用
点
标
注
来
源
按R_1(m行),R_2(n行)的顺序将两个关系的每一行连接起来(m \times n行), 同名列前用点标注来源
按R1(m行),R2(n行)的顺序将两个关系的每一行连接起来(m×n行),同名列前用点标注来源
- R 3 : = R 1 × R 2 R_3 := R_1 \times R_2 R3:=R1×R2
- 结果属性集是两个关系的属性合集
-
j
o
i
n
join
join:
-
T
h
e
t
a
−
j
o
i
n
Theta-join
Theta−join:
先
求
笛
卡
尔
积
,
再
找
满
足
条
件
的
元
组
先求笛卡尔积,再找满足条件的元组
先求笛卡尔积,再找满足条件的元组
- 有下标C,C是条件
- 结果与笛卡尔积一样
-
N
a
t
u
r
e
−
j
o
i
n
Nature-join
Nature−join:
根
据
同
名
同
值
属
性
合
并
两
表
根据同名同值属性合并两表
根据同名同值属性合并两表
- 没有下标C
- 结果是两个关系的级联
-
T
h
e
t
a
−
j
o
i
n
Theta-join
Theta−join:
先
求
笛
卡
尔
积
,
再
找
满
足
条
件
的
元
组
先求笛卡尔积,再找满足条件的元组
先求笛卡尔积,再找满足条件的元组
- r e n a m e rename rename : 重命名 R 1 : = ρ R 1 ( A 1 , A 2 , . . . A n ) ( R 2 ) R_1 := \rho_{R_1(A_1,A_2,...A_n)}(R_2) R1:=ρR1(A1,A2,...An)(R2)
表达式的构建,表达式的三种写法,算符优先级
- 表达式的构建:结合算符优先级
- 三种写法:
- 赋值语句序列: 新 的 对 象 : = 对 原 有 对 象 的 操 作 新的对象:=对原有对象的操作 新的对象:=对原有对象的操作
- 具有多个算符的表达式: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-B5XuF5Fu-1582017470471)(2020-01-11-16-09-57.png)]
- 表达树:叶:操作数; 内部节点: 应用于一个或多个子节点的运算符
- 三种写法:
- 算符优先级:
选
择
投
影
重
命
名
>
笛
卡
尔
j
o
i
n
>
交
>
并
,
减
选择投影重命名>笛卡尔join>交>并,减
选择投影重命名>笛卡尔join>交>并,减
选择投影重命名,笛卡尔join跟后面,接着是求集合交,最低求并与求减
包bag定义,与集合set的区别,包与集合操作的不同之处
- bag: 元素可以重复出现
- 与set的区别:
- 元素是否重复出现
- bag上操作不去重
- sql基于bag
- 一些操作(譬如投影)在bag上更高效
- 与set的同: 求并集的交换律成立
6 数据库-连接库: SQL注入/基于库libraries的SQL接口/三层架构/php游标cursors
基于libraries的SQL接口
- C + C L I C+CLI C+CLI
- J A V A + J D B C JAVA+JDBC JAVA+JDBC
- P H P + P E A R 或 D B PHP+PEAR或DB PHP+PEAR或DB
数据库环境的三层结构:
- Web server: 直接和用户交互
- application server: 执行逻辑指令
- database server: 按要求完成交互
基于libraries的SQL接口
- CLI: C的SQL连接库
- JDBC: Java database connectivity,类似于C的CLI,但是主语言是java
php游标cursors
相当于指针
7 SQL intro: select-from-where/使用as重命名/模糊查询的两种模式/空值null的两种含义/三值逻辑/多重关系查询:定义,方法/self-join查询同一关系中的两个不同对象/子查询描述,返回值/in(与普通query的区别),exists,any,all,union,intersect,except用法,语句的值,用在哪里/基于包执行的操作,基于集合执行的操作/消除重复项duplicate elimination–distinct/join操作: 笛卡尔积,自然连接,theta连接
模糊查询的两种模式
- 使用 l i k e 或 者 n o t l i k e like或者notlike like或者notlike
- % : 字 符 串 \%:字符串 %:字符串
- _ : 字 符 \_: 字符 _:字符
空值null的两种含义
- missing value: 存在但是不知道
- inapplicable: 不存在
三值逻辑
- True:1
- False: 0
- unkown: 1 2 \frac{1}{2} 21
- 操作:
- a n d : 取 最 小 and:取最小 and:取最小
- o r : 取 最 大 or: 取最大 or:取最大
- n o t ( x ) : 1 − x not(x): 1-x not(x):1−x
多重关系查询Multirelation query定义,方法
- 定义: 从至少一个关系中查询
- 方法: f r o m from from子句后跟多个关系名称, w h e r e where where子句后的查询属性名前标识关系名
self-join查询同一关系中不同的两个对象
在from子句后,差多少对象就写多少遍关系名, 每一个都需要重命名
子查询subquery描述,返回值
- 描述: 将括号括起来的完整select-from-where子句作为条件插入from或者where之后
- 返回值: 子查询必须返回一个有确定值的单属性元组
- 如果返回元组值为空或者有多个值,则会run-time error
in,exists,any,all,union,intersect,except用法,语句的值,用在哪里
- in:
- < 属 性 > i n < 子 查 询 > { 属 性 在 子 查 询 返 回 值 中 : t r u e 属 性 不 在 子 查 询 返 回 值 中 : f a l s e <属性> in <子查询>\begin{cases} 属性在子查询返回值中: &true\\ 属性不在子查询返回值中:&false \end{cases} <属性>in<子查询>{属性在子查询返回值中:属性不在子查询返回值中:truefalse
- 用在: w h e r e where where子句之后
- 相应的: n o t i n not\quad in notin
- 与普通query的区别: in 可能只输出一次, 普通Query可能有重复输出
- exists:
- e x i s t < 子 查 询 > { 子 查 询 结 果 非 空 : t r u e 否 则 : f a l s e exist <子查询>\begin{cases} 子查询结果非空: &true\\ 否则:&false \end{cases} exist<子查询>{子查询结果非空:否则:truefalse
- 子查询用括号括起来
- any:
- x < 操 作 符 > a n y < 子 查 询 > { 子 查 询 结 果 中 有 一 个 元 组 值 与 x 满 足 操 作 符 关 系 : t r u e 否 则 : f a l s e x <操作符> any <子查询>\begin{cases} 子查询结果中有一个元组值与x满足操作符关系:&true\\ 否则:false \end{cases} x<操作符>any<子查询>{子查询结果中有一个元组值与x满足操作符关系:否则:falsetrue
- 子查询结果中必须包含至少一个元组,操作符可以是任何比较操作符
- all:
- x < 操 作 符 > a l l < 子 查 询 > { 子 查 询 结 果 中 所 有 元 组 值 与 x 满 足 操 作 符 关 系 : t r u e 否 则 : f a l s e x <操作符> all <子查询>\begin{cases} 子查询结果中所有元组值与x满足操作符关系:&true\\ 否则:false \end{cases} x<操作符>all<子查询>{子查询结果中所有元组值与x满足操作符关系:否则:falsetrue
- union,intersect,except:
- 交,并,差
- 是子查询与之查询之间的操作
基于包执行的操作,基于集合执行的操作
- 基于包执行的操作: select-from-where
- 基于set执行的操作: 交并差
消除重复项duplicate elimination–distinct
$select\quad distinct 属性名 … $可以消除重复元组
join操作: 笛卡尔积,自然连接,theta连接
- product笛卡尔积: R c r o s s j o i n S R \quad cross \quad join \quad S RcrossjoinS
- nature join自然连接: R n a t u r e j o i n S R \quad nature \quad join \quad S RnaturejoinS
- theta join: R j o i n S o n < 条 件 > R \quad join \quad S \quad on <条件> RjoinSon<条件>
8 ra-sql: 拓展关系代数:包去重,排序/悬挂元组dangling,内连接,外连接:左外连接,右外连接,全连接/聚集aggregation:sum,max,min,avg,count,以及与distinct的结合,聚集中的空值/分组,使用分组对select进行限制,分组中的聚集函数,使用分组的两个必须条件/having的使用以及规则,后面跟随的条件/数据库插入(普通插入,批量插入,利用子查询插入),删除(全部删除,部分删除),更新(全部更新,条件更新),缺省
拓展RA:包去重,排序,分组聚集
- 包去重: R 1 : = δ ( R 2 ) R_1:=\delta(R_2) R1:=δ(R2)
- 排序:
R
1
:
=
τ
L
(
R
2
)
R_1:=\tau_L(R_2)
R1:=τL(R2) ------------------------------------------唯一一个结果既不是set也不是bag的关系代数
- L是属性的排列,按L中属性的顺序依次比较 R 2 R_2 R2元组的值来排序
悬挂元组dangling tuple,内连接,外连接中悬挂元组的表示,外连接:left outer join, right outer join, full outer join
- 内连接: 根据两表中相同的列中的同值元组合并两表, 包括自然连接
- 悬挂元组: theta连接中属于左边的关系,但是右边关系中没有元组和它连接
- 外连接中悬挂元组的表示: 用Null
- 外连接: 属于自然连接, 根据同列名同值元组合并两表
- left outer join:根据左表匹配右表,右表中没有匹配项,则结果表的右表相应位置null
- right outer join:根据右表匹配左表,左表中没有匹配项则结果表的左表相应位置null
- full: 外连接的默认选项, 结合左右两种情况
aggregation:sum,max,min,avg,count,在聚集函数中使用distinct,聚集函数中元组null的情况
- 例:
select student, sum(score) as score_sum
from Student
where score>=60
- 在聚集函数中使用distinct:
select count(distinct price)
from sells
where beer = 'Bud';
- 聚集函数中元组null的情况: 忽略,不计数,若只有null,则认为是0
分组,使用分组对select进行限制,分组中的聚集函数,使用分组的两个必须条件
- 分组group by: group by作用于select from where语句的执行结果,并在select语句之后的聚集函数中体现
select beer, avg(price)
from sell
group by beer
结果: 返回已经售出的每款酒(按名字分组)的平均售价
- 使用分组的两个必须条件(满足其中之一):当sql语句中使用分组时,其select之后的属性列表必须:
- 有聚集函数修饰 或
- 属于gruop by修饰的属性
having的使用以及规则,后面跟随的条件
- having与group by结合使用,后面跟随 对每一组分组的约束条件
- 例:在已售表中找特定厂家生产的酒或者至少三家酒吧都售卖的酒
select beer, avg(price)
from Sell
group by(beer)
having count(bar) >= 3 or
beer in (select name
from Beer
where manf = "Bud")
- having后面跟随的条件: 子查询,否则必须是聚集函数或必须属于group by所依据的属性
数据库插入(普通插入,批量插入,利用子查询插入),删除(全部删除,部分删除),更新(全部更新,条件更新),缺省
- 插入: insert into <表名> values (值),多行值用逗号分开括号
- 利用子查询插入: 注意子查询的返回值与插入对象匹配,在insert into XXX后直接跟子查询语句
insert into Drinkmates
(select d2.name
from Drinker d1, Drinker d2
where d1.name="Saly" and d2.name <> "Sally" and d1.bar = d2.bar)
- 删除: delete from <表名> where <条件>
- 全部删除: 不写where,表置空,where选择有特定值的列:特定列删除
- 部分删除: 譬如如果有一款酒的厂家制造了其他酒,就把这家厂子的所有酒删掉:where后面跟exists,其对象是一个子查询,查找同厂酒并返回酒的名字,注意:在执行完where之后exists后面的子句时,已经有一个静态结果表了,在删除时是静态的从结果表中找名字,直接在目标表删除那些名字的元组
delete Beer b
where exists(
select name
from Beer
where manf = b.manf and name <> b.name
);
- 更新: update <表名> set <列的值> where <条件,用来判断哪个元组需要更新>
9 约束constraint: 约束的定义,种类/外键的定义,外键表达方式,维护外键约束的3种方式(default,cascade,Null(缺省,级联,置空))以及选择策略/三种检测(attribute-based, Tuple-based, assertion断言)的方式,时机/触发器trigger描述,使用时机,创造规则:event-condition-action
约束的定义,种类
- constraint: DBMS强制执行的数据之间的关系
- 种类: { k e y f o r e i g n k e y v a l u e − b a s e d c o n s t r a i n t t u p l e − b a s e d c o n s t r a i n t \begin{cases} key\\ foreign\quad key\\ value-based\quad constraint\\ tuple-based\quad constraint \end{cases} ⎩⎪⎪⎪⎨⎪⎪⎪⎧keyforeignkeyvalue−basedconstrainttuple−basedconstraint
foreign key外键的定义,外键表达方式,维护外键约束的3种方式(default,cascade,null(缺省,级联,置空))以及选择策略
- foreign key表达方式: 表R的a属性后面加primary key,表S的b属性后面加references R(a); 或表S最后加一行foreignk key(b) references R(a).注意a必须是pk或者unique
- 维护外键约束的3种方式
- default: 拒绝改动
- cascade: 一方修改,另一方也跟着修改
- null: 删除操作:将元组的值置null,再修改另一方相应元组为null
- 选择策略:
- 定义外键时, 对于删除和插入用置空或级联
- 定义外键之后,对于更新和删除用null或级联cascade
foreign key beer references Beer(name)
on DELETE set null
on update cascade
三种检测(attribute-based,tuple-based,assertion)的方式,时机
- attribute-based check: 定义时写在相应属性后面, check <条件(可以是子查询,使用其他表必须用子查询)>
- 时机: 更新或插入
beer char(20) check (
beer in (select name from Beer)
)
price real check (price <= 5.00)
- tuple-based check: 在定义表的属性时单独做一行, check <条件(可以使用子查询,使用其他表必须用子查询)>
- 时机: 更新或插入
create table Sell(
bar char(20),
beer char(20),
price real,
check (bar = 'Bud' or price <= 5.00>)
);
- Assertion: create assertion 名字 condition (<条件>);
- 时机: 任何关系的每一次修改
触发器trigger描述,创建,使用时机,创造规则,event-condition-action规则
- trigger描述: attribute-或者tuple-based check的使用时机是固定的, 触发器可以让用户自己决定何时check. 语法:
create trigger 触发器名字
- 时机: 在用户需要的时候
- event-condition-action: 当event出现时,对具有某条件condition的表或属性,执行某action
例子: 有两张表,Beer记录有的酒,Sell记录卖出去的酒,Sell中的Beer存在与Beer之间的外键约束,现在卖出了一款新酒,要向Sell中直接插入记录
代码:
create trigger Beertrig
after insert on Seel -- event
referencing new row as newtuple
for each row
when (newtuple.beer not in (select name from Beer)) -- condition
insert into Beer(name) values (newtuple.beer); -- action
另一个例子
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJgbLRHy-1582017539712)(2020-01-12-14-10-11.png)]
<未完,接下篇>