超码(super key):是一个或多个属性的集合,这些属性的组合可以使我们在一个关系中唯一的标识一个元祖。
候选码( candidate key):超码中可能包含了无关紧要的属性,我们通常只对这样的一些超码感兴趣,它们的任意子集都不能成为超码。这样最小超码称为候选码(candidate key) 。
主码(primary key): 被数据库设计者所选中用来标识一个关系的候选码。
外码(foreign key):一个关系模式r1可能在他的属性中包含了另一个关系的r2的主码。这个码就称为**参照关系(referenced relation)**的外码(foreign key)。
一、DML
就是我们最经常用到的 SELECT、UPDATE、INSERT、DELETE。 主要用来对数据库的数据进行一些操作。
SELECT 列名称 FROM 表名称
UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值
INSERT INTO table_name (列1, 列2,...) VALUES (值1, 值2,....)
DELETE FROM 表名称 WHERE 列名称 = 值
二、DDL
其实就是我们在创建表的时候用到的一些 sql ,比如说:CREATE、ALTER、DROP等。DDL主要是用在定义或改变表的结构,数据类型,表之间的链接和约束等初始化工作上
CREATE TABLE 表名称
(
列名称1 数据类型,
列名称2 数据类型,
列名称3 数据类型,
....
)
ALTER TABLE table_name
ALTER COLUMN column_name datatype
DROP TABLE 表名称
DROP DATABASE 数据库名称
三、DCL
是用来设置或更改数据库用户或角色权限的语句,包括(grant,deny,revoke等)语句。这个比较少用到。
在公司呢一般情况下我们用到的是DDL、DML这两种。
String Operations
percent (%). The % character matches any substring.
underscore (_). The _ character matches any character.
常见语言
between
select name
from instructor
where salary between 90000 and 100000
(select course_id from section where sem = ‘Fall’ and year = 2009)
union
(select course_id from section where sem = ‘Spring’ and year = 2010)
(select course_id from section where sem = ‘Fall’ and year = 2009)
intersect
(select course_id from section where sem = ‘Spring’ and year = 2010)
Find courses that ran in Fall 2009 but not in Spring 2010
(select course_id from section where sem = ‘Fall’ and year = 2009)
except
(select course_id from section where sem = ‘Spring’ and year = 2010)
distinct
Left-join
Right-join
第一范式 : 一个域是原子的(atomic),如果该域的元素被认为是不可再分的单元。我们称一个关系R属于第一范式(First Normal Form,1NF),如果R的所有属性的域都是原子的。
函数依赖(Function Depend): 对于实例中的所有元素,如果t1和t2,若t1[a] = t2[a] ,则 t1[b] = t2[b]. a → b a \to b a→b(注: a = α a = \alpha a=α, b = β b = \beta b=β)。
平凡(trivial) 一般的,如果 β ⊆ α \beta \subseteq \alpha β⊆α则 形如 α → β \alpha \to \beta α→β的函数依赖是平凡的。
闭包(closure) 能够从 F F F集合推出所有的函数依赖集合 F + F^+ F+。
BCNF(Boyce-Codd Normal Form) 对于 F + F^+ F+中所有形如 α → β \alpha \to \beta α→β的函数依赖,其中( α ⊆ R \alpha \subseteq R α⊆R , β ⊆ R \beta \subseteq R β⊆R)至少一项成立:
第三范式(3rd NF)至少一项成立:
多值依赖
设R(U)是属性集U上的一个关系模式。X,Y,Z是U的子集,并且Z=U-X-Y。关系模式R(U)中多值依赖X→→Y成立,当且仅当对R(U)的任一关系r,给定的一对(x,z)值有一组Y的值,这组值仅仅决定于x值而与z值无关。
平凡的多值依赖与非平凡的多值依赖:
若X→→Y,而Z为空集,则称X→→Y为平凡的多值依赖;若Z不为空,则称其为非平凡的多值依赖。
**第四范式(4th NF)**至少一项成立
正则覆盖定义:F的正则覆盖Fc是一个依赖集,使得F与Fc相互逻辑蕴涵。此外,还包含如下性质:
Fc中任何函数依赖都不含无关属性。
Fc中函数依赖左半部分都是唯一的。即,Fc中不存在α1→β1,α2→β2,满足α1=α2
无关项(extraneous attribute) 定义:若果去除函数依赖中的属性不会改变函数依赖的闭包,就称该属性是无关的。
设关系模式R与函数依赖集F,R分解为R1,R2,此分解是无损的必须满足:α=R1∩R2是R1或R2的超码,可利用属性集闭包验证。
保持依赖的判断:
如果F上的每一个函数依赖都在其分解后的某一个关系上成立,则这个分解是保持依赖的(这是一个充分条件)。
如果上述判断失败,并不能断言分解不是保持依赖的,还要使用下面的通用方法来做进一步判断。
设关系模式R(U,F),其中U={A, B, C, D, E},F={A→BC,C→D,BC→E,E→A},则分解ρ={R1(ABCE),R2(CD)}满足 (43) 。
(43)
A.具有无损连接性、保持函数依赖
B.不具有无损连接性、保持函数依赖
C.具有无损连接性、不保持函数依赖
D.不具有无损连接性、不保持函数依赖
无损连接的判断,因为 R1∩R2={C},而C是R2的超码所有无损。
保持依赖的判断,A→BC,BC→E, E→A都在R1上成立(也就是说每一个函数依赖左右两边的属性都在R1中),C→D在R2上成立,因此给分解是保持依赖的。
给定关系模式R(U,F),U={A, B, C, D, E},F={B→A,D→A,A→E,AC→B},其候选关键字为
(40) ,则分解ρ={R1(ABCE),R2(CD)}满足 (41) 。
(40) A.ABD
B.ABE
C.ACD
D.CD
(41) A.具有无损连接性、保持函数依赖
B.不具有无损连接性、保持函数依赖
C.具有无损连接性、不保持函数依赖
D.不具有无损连接性、不保持函数依赖
再看第二问。
先做无损链接的判断。R1∩R2={C},计算C+。
result=C
因此C既不是R1也不是R2的超码,该分解不具有无损分解性。
再做保持依赖的判断。
B→A,A→E,AC→B在R1上成立,D→A在R1和R2上都不成立,因此需做进一步判断。
由于B→A,A→E,AC→B都是被保持的(因为它们的元素都在R1中),因此我们要判断的是D→A是不是也被保持。
对于D→A应用算法二:
result=D
对R1,result∩R1=ф(空集,找不到空集的符号,就用这个表示吧),t=ф,result=D
再对R2,result∩R2=D,D+ =ADE ,t=D+ ∩R2=D,result=D
一个循环后result未发生变化,因此最后result=D,并未包含A,所以D→A未被保持,该分解不是保持依赖的。
选D。
B+树索引是一种多级索引,但是其结构不同于多级索引顺序文件。典型的B+树结点结构如图11-7所示。它最多包含 n-1 个搜索码,以及 n 个指针。
每个叶节点最多可有(n-1)个值。我们所允许包含的值的最少为 ⌈ ( n − 1 ) / 2 ⌉ \lceil (n-1)/2 \rceil ⌈(n−1)/2⌉当n=4时,为大于等于2,小于等于3,当n=3时,大于等于1小于等于2.
每个非叶节点最少要有 ⌈ n / 2 ⌉ \lceil n/2 \rceil ⌈n/2⌉个指针(根节点除外),最多 n n n个节点,也被称为内部节点(internal node)
除非只有一个节点,否则根节点必有两个指针
ACID性质
Example
Q1. Consider the transaction T below:
read(x); read(y); y:= y-x; x := x-y; write(x); write(y);
The transaction completes successfully and commits. Some other information about this system is as follows:
_ T is the only active transaction in the system
_ The database has a constraint that both data item x and y should have value greater than 0.
Which of the following statement is false ?
A. Transaction ensures durability.
B. Transaction ensures isolation.
C. Transaction ensures consistency.
D. Transaction ensures atomicity.
A. Durability 一个事务完成后它对于数据库的改变必须是永久性的。
YES, The transaction completes successfully and commits.
B. Isolation 每个事务都不会对其他事务产生干扰。
YES, T is the only active transaction in the system.
C. Consistency 执行事务的时候(没有其他事务干扰时),保持事务的一致性。
NO, The database has a constraint that both data item x and y should have value greater than 0.
D. Atomicity 事务的所有操作要么全部正确反映出来,要么不反映。
YES, commits.
注:WAR 代表着 write and read 并且有顺序。
正如我们之前所注意到的,事务并非总能成功的执行完成,这种事务称为中止(aborted),一旦中止事务造成的变更被撤销,我们称为已回滚(rolled back)典型的方法是维护一个日志。成功完成执行的事务被称为已提交(committed) 。即使出现系统故障,这个状态也必须保持。
Two schedules S1 and S2 are said to be view-equivalent when the following conditions are satisfied:
If the transaction Ti in S1 reads an initial value for object X, so does the transaction Ti in S2.
If the transaction Ti in S1 reads the value written by transaction Ti in S1 for object X, so does the transaction Ti in S2.
If the transaction Ti in S1 is the final transaction to write the value for an object X, so is the transaction Ti in S2.
A schedule S is view serializable if it is view equivalent to a serial
schedule.
Every view serializable schedule that is not conflict serializable has
blind writes.
我们考虑一个调度S,其中含有分别属于I与J的两条连续指令Ii与Ij(i!=j)。
如果I与J引用不同的数据项,则交换I与J不会影响调度中任何指令的结果。然而,若I与J医用相同的数据项Q,则两者的顺序是重要的。由于我们只处理read和write指令,因此只有在I与J都是read时,两条指令的执行顺序才是无关紧要的。
当I与J是不同事务在相同数据项的操作,并且其中至少有一个时write指令时,我们说I与J是冲突(conflict) 的。
如果设I与J是调度S的两条连续指令。若I与J是属于不同事务的指令且不冲突,则可以交换I与J的顺序得到一个新的调度S‘。S与S’等价。
如果调度 S 可以通过一系列非冲突指令交换转换成 S‘,我们称 S 与 S’ 是**冲突等价(conflict equivalent)**的。
若一个调度 S 与一个串形调度等价,则称调度 S 是冲突可串形化(conflict serializable)。
不论什么原因,如果事务 Ti 失败了,我们必须撤销该事务的影响以确保其原子性。在允许并发执行的系统中,原子性要求依赖 Ti 的任何事物 Tj(即 Tj 读取了 Ti 写的数据)也中止。为确保这一点,我们需要对系统所允许的调度类型做一些限制。
在下面两节中,我们从事务故障恢复的角度讲述什么样的调度是可接受的,第15章将讲述如何保证只产生这种可接受的调度。
一个可恢复调度(recoverable schedule) 应该满足:对于每对事务 Ti和Tj,如果Tj读取了之前由Ti所写的数据项,则Ti先于Tj提交。
无级联调度
即使一个调度是可恢复的,要从事务Ti的故障中正确恢复,可能需要回滚若干事务。当其他事务读取了由事务Ti所写数据项时就会发生这种情形。这种因单个事务故障导致一系列事务回滚的现象称为级联回滚(cascading rollback) 。
无级联调度(cascading schedule) 应满足:对于每对事务Ti和Tj,如果Tj读取了先前由Ti所写的数据项,则Ti必须在Tj这一读操作前提交。容易验证每个无级联调度也都是可恢复的调度。
事务由磁盘向主存输入信息,然后再将信息输出回磁盘。
输入和输出操作以块为单位完成。位于磁盘上的块称为物理块(physical block),临时位于主存的块称为缓存块(buffer block),内存中用于临时存放块的区域称为磁盘缓存区(disk buffer)。
磁盘与主存间的块移动是由下面两个操作引发的:
- input(B)传送物理块B至主存
- output(B)传送缓存块B至磁盘,并替换磁盘上相应的物理块
在概念上,每个事务Ti有一块私有工作区,用于保存Ti所访问及更新的所有数据项的拷贝。该工作区在事务初始化时由系统创建;在事务提交或中止时由系统删除。事务Ti通过在其工作区和系统缓冲区之间传送数据,与数据库系统进行交互。我们使用下面两个操作来传送数据:
使用最为广泛的记录数据库修改的结构就是日志(log)。日志时日志记录(log record)的序列
日志记录有几种,更新日志记录(update log record) 描述一次数据库写操作,他有如下几个字段:
事务Ti开始
事务Ti提交
事务Ti中止
每次事务执行写操作时,必须在数据库修改前建立该次写操作的日志记录并把它加到日志中。一旦日志记录已存在,就可以根据需要修改输出到数据库中。并且,我们有能力撤销已经输出到数据库中的修改,这是利用日志记录的旧值字段来做的。
为了从系统故障和磁盘故障中恢复时能使用日志内容记录,日志必须存放在稳定储存器中。
为了能使我们能理解恢复过程中日志记录的作用,我们需要考虑事务在进行数据项修改中所采用的步骤:
如果一个事务执行了对磁盘缓存区或磁盘自身的更新,我们说这个事务修改了数据库;而对事务在主存自己私有的部分进行的更新不算数据库修改。如果一个事务知道它提交都没有修改数据库,我们说它采用了**延迟修改(deferred-modification)技术,如果数据库修改在事务仍然活跃时发生,我们就说它采用了立即修改(immediate-modification)**技术。
当一个事务的commit日志记录——这是该事务最后一个日志记录——输出到稳定储存器后,我们就说这个事务**提交(commit)**了;这时所有更早的日志记录都已经输出到稳定存储器中。于是,在日志中就有足够的信息来保证,计算发生系统崩溃,事务所做的更新也可以重做。如果系统崩溃发生在日志记录输出到稳定存储器之前,事务Ti将会回滚。这样,包含commit日志记录的块的输出是单个原子的动作,ta导致一个事务的提交。
大多数的恢复算法,都没有把每个事务的重做分别执行,而是对日志进行一次扫描,在扫描过程中每遇到一个redo的日志记录就这些redo动作。这种方法能确保保持更新的顺序,并且效率更高,因为仅需要整体读一遍日志,而不是对每个事务都读一遍日志。
undo操作不仅将数据项恢复成旧值,而且作为撤销过程的一个部分,还写日志来记下所执行的更新。这些日志的一个部分,还写日志记录来记下所执行的更新。这些日志记录是特殊的 redo-only 日志记录,因为他们不需要包含所更新的数据项的旧值。
与重做过程一样,执行更新的顺序非常重要
正对于事物Ti的 undo 操作完成后,它写一个的日志记录,表面撤销完成了。
具体例子看 P 409 P409 P409
当系统故障发生时,我们必须检查日志,决定哪些事务需要重做,哪些需要撤销。原则上,我们需要搜索整个日志来确定该信息。这样做有两个主要的困难:
为了降低这种开销,引入检查点。
下面描述一个简单的检查点,
检查点checkpoint
checkpoint是为了定期将db buffer的内容刷新到data file。当遇到内存不足、db buffer已满等情况时,需要将db buffer中的内容/部分内容(特别是脏数据)转储到data file中。在转储时,会记录checkpoint发生的”时刻“。在故障回复时候,只需要redo/undo最近的一次checkpoint之后的操作。
在系统崩溃后,系统检查日志以找到最后一条记录。
只需要对L中的事务,以及 记录写到日志中之后才开始执行的事务进行undo或redo操作。让我们把这个事务集合记为T。
log records are always written onto disk before their corresponding database records are written.
In case of deferred database modification, wr ites are reflected on the database only after commit log has been written. Hence, for consistent state in both cases, T1 must do the redo operation. On the other hand, no action needs to be taken for T2, because the write operation of T2 has not been reflected on the database. During the second recovery, since it is not guaranteed that the first write has gone through or not, T1 needs to write once more.
没有检查点,小规模先UNDO,然后REDO
大规模时需要从检查点开始REDO
for the recovery algorithm, undo operations are done first, and then redo operations.
一个严格的调度:由当一个事务读取了一个数据项时,其他任何事务都无法再从中读取数据,写入数据,除非这个事务结束。