1.      数据挖掘是从数据库中发现知识,或者主要是从大量的磁盘数据中发现知识。它与机器学习和统计分析不一样。

2.      数据库管理系统(Database-Management System, DBMS)由一个互相关联的数据的集合和一组用于访问这些数据的程序组成。这个数据集合通常称为数据库(database)。DBMS的主要目标是要提供一种可以方便、高效地存取数据库信息的途径。

3.      数据库结构的基础是数据模型。数据模型是一个描述数据、数据联系、数据语义以及一致性约束的概念工具的集合。数据模型提供了一种描述物理层、逻辑层和视图层数据库设计的方式。

数据模型可被划分为四类:

1) 关系模型(relationship model)。关系模型用表的集合来表示数据和数据间的联系。

2) 实体-联系模型(entity-relationship model)。将现实世界的一件“事情”或一件“事物”视为一个实体,以实体作为基本对象。实体-联系模型就是将基本对象以及这些对象间的联系构成。所有实体集合称为实体集,同一类型的所有联系的集合称为联系集。该模型广泛用于数据库设计。

3) 基于对象的数据模型(object-based data model)。面向对象的数据模型可以看成是E-R模型增加了封装、方法(函数)和对象标识等概念后的扩展。对象-关系数据模型结合了面向对象的数据模型和关系数据模型的特征。

4) 半结构化的数据模型(semistructured data model)。该模型允许相同的数据项含有不同的属性集的数据定义。而之前提到的数据模型:所有某种特定的数据项必须有相同的属性集。比如XML(extensible markup language)可扩展标记语言。

5) 网状数据模型(network data model)。该模型已经很少用了,先于关系模型。

6) 层次数据模型(hierarchical data model)。该模型已经很少用了,先于关系模型。

4.      数据库语言分为:

1)    数据定义语言(data –definition language,DDL),通过它可以定义表、完整性约束、断言,等等。用户和数据库管理系统都能用它。

2)    数据操纵语言(data-manipulation language,DML)。分为两种:

a.      过程化DML。要求用户指定需要什么数据并且给出如何获得这些数据的途径。

b.      声明式DML。要求用户指定需要什么数据就行,不必指明如何获得这些数据信息。SQL查询语句是非过程化的,也即声明式的。

5.      数据库系统的大致功能部件可以分为:存储管理器和查询管理器。

存储管理器部件包括:

a. 权限及完整性管理器(authorization and integrity manager)

b. 事务管理器(transaction manager)

c. 文件管理器(file manager)

d. 缓存区管理器(buffer manager)

e. 数据文件(data files)

f.  数据字典(data dictionary)

g. 索引(index)

查询管理器部件包括:

a.      DDL解释器(DDL interpreter)

b.      DML编译器(DML compiler)

c.       查询执行引擎(query evaluation engine)

6.      超码(superkey)是一个或多个属性的集合,这些属性的集合可以使我们在一个关系中唯一标识一个元组。如果K为超码,则K的任意超集也为超码。如果K为超码并且K的任意真子集都不为超码,则K称为候选码,也就是最小的超码。超码也可以理解成在候选码上扩展其他属性。为了区分不同的候选码,从中选择一个作为主码。关系中的任意两个不同的元组都不允许同时在码(不论是主码、候选码或者超码)属性上具有相同的值。码是整个关系的一种性质,而不是单个元组的性质。

7.      外码(foreign key)定义:如果一个关系模式(r1)可能在它的属性中包含另一个关系模式(r2)的主码,这个属性在r1上称为外码,准确的说是关系r1参照关系r2的外码。其中,r1称为参照关系,r2称为被参照关系。在定义一个关系的外码时,该关系就存在外码约束了。外码约束比参照完整性约束条件更为苛刻。

8.      参照完整性约束(referential integrityconstraint)的参照属性在另一个关系模式r2中未必是主码,而外码约束必须是主码。所以,外码约束包含于参照完整性约束中。参照完整性约束又称为子集依赖(subset dependency)。参照完整性约束要求:在参照关系中任意元组在特定的属性上的取值必然等于被参照关系中某个元组在特定的属性上的取值。

9.      大学数据库模式:

classroom ( building,room_number, capacity )

department( dept_name,building, budget )

course( course_id,title,dept_name, credits )

instructor( ID,name, dept_name, salary )

section( course_id,sec_id, semester, year, building, room_number,time_slot_id )

teaches( ID, course_id,sec_id, semester, year )

student( ID, name,dept_name, tot_cred )

takes( ID, course_id,sec_id, semester, year, grade )

advisor( s_ID,i_ID )

time_slot( time_slot_id,day, start_time, end_time )

prereq( course_id, prereq_id )

10.  外键不可能在本关系中作主键或作为主键的一部分。(此话有误)

11.  外码中的属性允许为空(null),只要它们没有被声明为not null。有个规定:如果某外码列为空null,则该元组自动被认为是满足外码约束。

12.  参照完整性约束有以下几种:

1) 外码约束。在SQL create table 中外码参照默认情况下是被参照表中的主码属性。

如:foreign key (dept_name) referencesdepartment  其中dept_name属性在department 表中作为主码。

外码约束可以作为属性定义的一部分,同时声明该属性为外码,如:

dept_name varchar(20) referencesdepartment

create table advisor

(s_ID varchar(5),

i_IDvarchar(5),

primary key (s_ID),

foreign key (s_ID) references student(ID) ondelete cascade,

foreign key (i_ID) references instructor(ID)on delete set null

);

2) SQL支持显示指定被参照关系属性列表的references 子句。但是,这个指定的属性列表必须声明为被参照关系的候选码,或者是使用了primary key 约束,或者是使用了unique约束。(references子句出现的属性只能是主码、候选码和unique属性)

3) 更为普遍地参照完整性约束。在更普遍的参照完整性约束形式中,被参照的属性不必是候选码,这样的形式还不能在SQL中直接声明。但是,SQL标准提供了另外的结构用于实现这样的约束,比如:

a.      复杂check 条件和断言

b.      触发器

13.  当违反参照完整性约束时,通常的处理是拒绝执行导致完整性破坏的操作(即进行更新操作的事务被回滚)。但是,在foreign key 中可以指明:如果被参照的关系上的元组删除或者更新动作违反了约束,那么系统根据foreign key子句定义的要求来恢复完整性约束,而不是拒绝这样的动作。比如在创建课程表时:

create table course

( …

foreign key(dept_name) references department on delete cascade on update cascade,

);

其中,有了on delete cascade 子句,如果删除department中的元组导致了此参照完整性约束被违反,则删除并不被系统拒绝,而是对course关系作“级联”删除,即删除参照了被参照关系中删除元组的元组。有了on update cascade子句,同理,course关系会作“级联”更新。

SQL 还允许foreign key 子句指明除cascade以外的其他动作,比如:

a.      用set null 代替cascade,表示:如果完整性约束被违反,将参照域置(这里是dept_name)为空。

b.      用 set default 代替 cascade,表示:如果完整性约束被违反,将参照域置(这里是dept_name)为域的默认值。

如果存在多个关系的外码依赖链,则在链一端所做的删除或更新可能传至整个链,在此过程中,通过级联操作未能解决违反约束问题,则系统终止该事务。于是,该事务所做的所有改变及联级动作将被撤销。

14.  更为普遍的参照完整性约束形式:复杂check条件与断言

但是要注意的是,接下来所讲述的结构目前还没有被大多数数据库系统支持。

在SQL标准定义中,check子句中的谓词可以是包含子查询的任意谓词。于是,可以在关系section上声明如下所示的参照完整性约束:

check (time_slot_id  in (select  time_slot_id from  time_slot))

这个约束条件不仅在section关系中插入或更新元组时需要检测,而且在time_slot关系改变时需要被检测(比如在time_slot关系中删除元组或更新元组,导致完整性约束被破坏,因此,在time_slot关系中删除或更新元组时,在section关系需要显示说明应对方案)。

一个断言(assertion)就是一个谓词,它表达了我们希望数据库始终满足的一个条件。域约束和参照完整性约束就是断言的特殊形式。

SQL中的断言为如下形式:

create assertion <assertion_name>check <predicate>;

举例:对于student关系中的每个元组,它的属性tot_cred上的取值必须等于该生所成功修完课程学分的总和。

用断言描述如下:

createassertion credits_earned_constraint check

(not exists

(select ID

from student

where tot_cred <> (select sum(credit)

from takes natural join course

where student.ID = takes.ID and grade is notnull and grade <> ‘F’

)

)

);

上述采用了“not exists X such that not P(X)”结构来实现约束,因为SQL不提供“for all X, P(X)”结构(其中P是一个谓词),不过,没关系,这两个结构等价。

一些系统开发者省去了对一般性断言的支持,或者只提供易于检测的特殊形式的断言。如果数据库系统为支持上述复杂的断言或check子句,如果数据库支持触发器的话,可以通过触发器来实现等价的功能。

练习题:每位老师不能在同一个学期的同一时间段在两个不同的教师授课,用断言如何表达?

15.  基本模式定义

创建表(create table 命令)的通用形式:

create table<table_name>

(    A1 D1,

A2 D2,

A3 D3,

…,

An Dn,

<完整性约束1>,

…,

<完整性约束n>

);

举例:

create table teaches

(    ID varchar(5),

course_id varchar(8),

sec_id varchar(8),

semester varchar(6),

year numeric(4,0),

primary key (ID, course_id, sec_id,semester, year),

foreign key (course_id, sec_id, semester,year) references section,

foreign key (ID) references instructor

);

删除表命令:

droptable <table_name>;

修改表命令(向表中添加属性或删除属性):

a.      向表中添加新属性:

alter table <table_name> add A D;

其中,<table_name>为表名,向该表添加一个属性A,属性A的域为D;关系中的所有元组在新属性上的取值将被置为空null。

向表中添加新约束:

altertable <table_name> add <constraint> ;

当执行添加新约束时,系统首先保证关系满足指定的约束。如果满足,那么约束被施加到关系上;如果不满足,则拒绝执行上命令。

b.      向表中删除属性:

alter table <table_name> dropA;

很多数据库系统并不支持删除属性,尽管如此,它们允许去掉整个表。

16.  SQL查询可以有多种:

1)  单关系查询

2)  多关系查询

3)  嵌套子查询

a.  子查询嵌套在where子句中

1.      集合成员资格

用连接词in 和not in,来判断测试元组是不是集合中的成员。

例如:

select count(distinct ID)

from takes

where(course_id, sec_id, semester, year) in

(selectcourse_id, sec_id, semester, year

from teaches

where teaches.ID = 10101) ;

2.      集合的比较

< some、>some、<= some、 >=some、<>some,其中=some等价于in,然而<>some并不等价于not in。

< all、<=all、>=all、=all、<>all,其中<>all等价于not in,但=all并不等价于in。

3.      空关系测试

SQL提供exists结构用于测试子查询的结果关系中是否存在元组,用not exists结构测试子查询结果集中是否不存在元组。若子查询结果关系中存在元组,则exists结构返回true;否则返回false,而not exists结构返回false,否则返回true。我们可以使用not exists 结构模拟集合包含(即超集)操作:我们可将“关系A包含关系B”写成“not exists(B except A)”。

举例1:

select course_id

from section as S

wheresemester = ‘Fall’ and year = 2009 and exists(select * from section as T wheresemester = ‘Spring’ and year = 2010 and T.course_id = S.course_id ) ;

举例2:找出选修了Biology系开设的所有课程的学生。

selectS.ID, S.name

fromstudent S

where notexists( ( select course_id

from course

where dept_name = ‘Biology’ )

except

( select course_id

from takes as T

where T.ID = S.ID ) ) ;

4.      重复元组存在性测试

SQL提供一个返回布尔值的unique结构(此结构尚未被广泛实现),用于测试在一个子查询结果中是否存在重复元组。例如:找出所有在2009年最多开设一次的课程,如下所示:

selectT.course_id

fromcourse as T

whereunique (select R.course_id

from course as R

where R.course_id = T.course_id

and R.year= 2009) ;

不使用not unique 结构的一种等价表达形式:

selectT.course_id

fromcourse as T

where 1>= ( select count (R.course_id)

from course as R

where R.course _id = T.course_id

and R.year = 2009 ) ;

b.  子查询嵌套在from子句中

SQL允许在from子句中使用子查询表达式。在此采用的主要观点是:任何select-from-where 表达式返回的结果都是关系,因而可以被插入到另一个select-from-where中任何关系可以出现的位置。

举例:找出系平均工资超过42000美元的那些系中教师的平均工资:

select dept_name, avg_salary

from ( select dept _name, avg(salary) as avg_salary

from instructor

group bydept_name )

where avg_salary > 42000 ;

或对上述from子句产生的结果关系进行起个名字,并对属性进行重命名:

select dept_name , avg_salary

from ( select dept_name, avg(salary)

from instructor

group by dept_name )

as dept_avg (dept_name, avg_salary)

where avg_salary >42000 ;

找出在所有系中工资总额最大的系:

select dept_name, max(tot_salary)

from (select dept_name, sum(salary)

from instructor

group bydept_name)

as dept_total(dept_name , tot_salary)

在2003SQL中允许from子句中的子查询用关键词lateral作为前缀,以便访问from子句中在它前面的表或子查询中的属性。比如:

select name , salary , avg_salary

from instructor S1, lateral(select avg(salary) asavg_salary

frominstructor as S2

whereS2.dept_name = S1.dept_name );

没有lateral子句的话,子查询就不能访问来自外层查询的相关变量S1。目前只有少数SQL实现支持lateral子句,比如 IBM DB2。

c.  子查询嵌套在select子句中

举例:列出所有系以及它们拥有的教师数。

select dept_name , (select count(*)

frominstructor as S2

where S2.dept_name = S1.dept_name) as num_instructors

from department as S1;

d.  with 子句

with子句提供定义临时关系的方法,这个定义只对包含with子句的查询有效。

比如:

with max_budget( value ) as (select max(budget) fromdepartment )

select budget

from department , max_budget

where department.budget = max_budget.value ;

with子句定义了临时关系max_budget,此关系在随后的查询中马上被使用了。

例如:假设我们要查询所有工资总额大于所有系平均工资总额的系,我们利用with子句写:

with dept_total(dept_name , value) as

(selectdept_name , sum(salary)

frominstructor

group bydept_name),

dept_total_avg (value) as

(select avg(value)

fromdept_total)

select dept_name

from dept_total ,dept_total_avg

where dept_total.value >=dept_total_avg.value;

4)  标量子查询

举例:列出所有系以及它们拥有的教师数。

select dept_name , (select count(*)

frominstructor as S2

where S2.dept_name = S1.dept_name) as num_instructors

from department as S1;

上面的例子说明:1. 子查询时可以使用外层的from子句中的关系的属性。2. 子查询保证只返回单个值。

标量子查询可以出现在select、where和having子句中。当在表达式中使用标量子查询时,它出现的位置是单个值出现的地方。(尽管标量子查询的结果类型仍是关系,SQL是从该关系中包含单个属性的单个元组中取出相应的值,并返回该值。)

5)  相关子查询

17.  通常查询结果默认保留重复元组:

select dept_name from instructor;

等价于

select all dept_name from instructor;

如果想强制删除重复的元组,可在select后加入关键字distinct:

select distinct dept_name from instructor;

18.  一个SQL查询可以包含三种形式的子句:select子句,from子句,where子句。

1)  select子句用于列出查询结果中所需要的属性。

2)  from子句是一个查询求值中需要访问的关系列表。

3)  where子句是一个作用在from子句中关系的属性上的谓词,以筛选from子句产生的结果关系。

想理解一个查询所代表的运算最容易的方式是以如下顺序来考察各子句:首先是from,然后是where,最后是select。

通过from子句定义了一个在该子句中所列出关系上的笛卡尔积。它可以用集合理论来形式化定义,也可以通过下面的迭代过程来理解,为from子句结果关系产生元组:

for each 元组t1 in 关系 r1

for each 元组 t2 in 关系 r2

for each 元组 t3 in 关系 r3

……

for each 元组 tn in 关系 rn

把元组t1,t2,t3,…,tn连接拼成单个元组t

把元组t加入结果关系rfset中

上述代码运行完之后,结果关系rfset具有from子句中所有关系的所有属性,同时结果关系rfset拥有元组数量为m1 *m2*m3*…*mn(其中,mi是关系ri中元组数量)。在该结果关系rfset模式中的属性名前有关系名作为前缀,这是为了避免不同关系具有相同的属性名。我们在select子句中也可以在多个表中出现相同的属性名前加上关系名作为前缀来避免混淆,而只出现在单个表中的属性,我们通常去掉关系名前缀,以简化形式。

但是,在实践中,SQL也许会将上述迭代过程表达式转换成更高效的等价形式。

19.  一般来说,一个SQL查询的含义可以理解如下:

1)  为from子句中列出的关系产生笛卡尔积。

2)  在步骤1)的结果上应用where子句中指定的谓词。

3)  对于步骤2)结果中的每一个元组,输出select子句中指定的属性的值(或表达式的结果)。

20.  SQL还支持其他一些附加的基本运算:

1)  更名运算

可以重命名结果关系中属性的方法,如下形式的as子句:

old_name asnew_name

上述的as子句不仅可以在select子句中出现,也可以在from子句中出现。

重命名一般有两个用途:

a.  将一个长的关系名称(或select子句属性)替换为较短的名称,这样方便使用。

b.  如果需要比较同一个关系中的元组的情况,则必须对关系重命名,例如:

select distinct T.name

from instructor as T, instructor as S

where T.salary > S.salary and S.dept_name = ‘Biology’;

其中,T 和S可以被认为是instructor关系的两份拷贝,准确的说是别名,表别名,相关名称,相关变量,等都行。

2)  字符串运算

a.      SQL字符串使用一对单引号表示,如果单引号作为字符串的一部分时,那就用两个单引号字符来表示。

百分号(%):匹配任意子串。

下划线(_):匹配任意一个字符。

b.      转义字符用法

在like 运算中使用escape关键字来定义转义字符,转义字符直接放在特殊字符前面。例如1:like ‘ab\%cd%’ escape ‘\’

上面将第一个特殊字符%作为字符串的组成部分,’\’作为转义字符,所以,含义是匹配所有以ab%cd开头的任意字符串。

例如2:like ‘ab\\cd%’ escape ‘\’     匹配所有以“ab\cd”开头的字符串。

c.       select 子句中的属性说明

星号(*)在select子句中代表“所有的属性”。

d.      排列元组的显示次序

使用order by 子句:select name from instructor where dept_name = ‘Physics’ order byname;

order by <attribute_name>子句默认使用升序。与默认等价的是order by <attribute_name> asc,我们可以用desc表示降序。比如:

select * from instructor order by salary desc, name asc ;含义是以属性salary作为第一级排序(降序),以属性name作为第二级排序(升序)。

e.      where 子句谓词

SQL提供between…and…,或not between比较运算。

21.  集合运算

union、intersect和except运算分别对应于数学集合论中的∪、∩和-运算。

1)  union 运算

( select course_id

from section

where semester = ‘Fall’and year = 2009

)

union

(select course_id

from section

where semester = ‘Spring’and year = 2010

);

union运算自动去掉重复元组。如果想保留,可以用union all 代替union。

2)  intersect 运算

( select course_id

from section

where semester = ‘Fall’ and year = 2009

)

intersect

(select course_id

from section

where semester = ‘Spring’and year = 2010

);

intersect运算在最终结果关系中自动去掉重复元组(默认的)。如果想保留,可以用intersect all 代替intersect。比如,在使用了intersect all 时,如果存在这样的情况:ECE-101在2009年秋季学期开设了4个课程段,在2010年春季学期开设了2个课程段,那么在结果关系中有2个ECE-101元组;若使用intersect时,结果关系只有1个ECE-101元组。

3)  差运算

( select course_id

from section

where semester = ‘Fall’and year = 2009

)

except

( select course_id

from section

where semester = ‘Spring’and year = 2010

);

except 运算从其第一个输入中输出所有不出现第二个输入中的元组,此运算在执行差操作之前自动去除输入中重复元组(默认的)。比如,ECE-101在2009年秋季学期开设了4个课程段,在2010年春季学期开设了2个课程段,那么except运算的结果关系中就只有1个ECE-101元组。如果想在结果关系中出现2个ECE-101元组,可以用except all 代替except。用except all能够保留下重复元组,前提是相减结果为正。若为负,在结果关系中没有任何关于这个元组了(这里是ECE-101)。

22.  空值

1)  空值与算术运算符,当空值参与算术表达式运算中,运算结果为空。

2)  空值与比较运算符,当空值参与比较表达式运算中, 运算结果为unknown(既不是谓词is null,也不是谓词is notnull),它是除了true和false之外的第三个逻辑词。特别地,not unknown 的结果为unknown。

3)  空值与集合运算符

当一个查询使用select distinct 子句时,重复元组将会被去除,重复的判断依据:在两个元组对应的属性值上,都是非空并且值相等,或者都是空。比如,{(‘A’,null),(‘A’,null)},这两个元组被认为是相同的,即使在某些属性上存在空值。

注意:上述对待空值的方式与谓词中对待空值的方式不同,在谓词中null = null会返回unknown,而不是true。(总结:在谓词中,两个空null被认为是两个不相同的东西,在筛选元组时,两个空被认为时相同的东西)

23.  聚集

1)  基本聚集

有avg()、sum()、count()、min()、max()五个基本聚集,avg和sum的输入必须是数字集,但其他运算符还可以在非数字数据类型的集合上,如字符串。

常用形式举例:avg(salary)、count(distinct ID)、count(*)

2)  分组聚集

a.  用group by 子句进行分组。groupby子句中给出的一个或多个属性是用来构造分组的。分组的依据:在group by 子句中的所有属性上的取值相同的元组将被分在一个组中。在没有用group by子句的查询中,默认整个关系被当做一个分组,比如,select avg(salary) from instructor 。

当查询语句出现聚集函数又有group by时,执行过程:先分组,后计算。

注意:当查询使用分组时,任何没有出现在group by子句中的属性如果出现在select子句中的话,它只能出现在聚集函数内部,否则这样的查询就是错误的。

b.  对各个分组进行筛选,使用having子句

having 子句中的谓词在形成分组后才能起作用。having子句与where子句的区别:having子句用于对分组限定条件,而where子句用于对元组限定条件。

举例:

select dept_name avg(salary) as avg_salary

from instructor

group by dept_name

having avg(salary) >42000 ;

c.  当查询语句出现分组聚集函数、where子句、group by子句或having子句时,通过下述操作序列来定义理解:

5.      最先根据from子句来产生一个关系。

6.      如果有出现了where子句,where子句的谓词将运用于from子句的结果关系上。

7.      如果出现了group by子句,满足where子句的元组通过group by子句形成分组。如果没有group by子句,则将满足where子句谓词的整个元组被当作为一个分组。

8.      如果出现了having子句,它将应用到每个分组上;不满足having子句谓词的分组将被抛弃。

9.      select子句利用剩下的元组产生出查询结果中的元组,也就是在每个分组上应用聚集函数来得到单个结果元组。

举例:

select course_id , semester ,year, sec_id, avg(tot_cred)

from takes natural join student

where year =2009

group by course_id , semester, year, sec_id

having count(ID) >= 2 ;

3)  对空值和布尔值的聚集

a.      空值对聚集的影响

聚集函数根据以下原则处理空值:除了count(*)外所有的聚集函数都忽略输入集合中的空值。

聚集函数根据以下原则处理空集:空集的count运算值为0,而其他所有聚集运算在输入值为空值的情况下返回一个空值。

b.      布尔值对聚集的影响

能处理布尔值(true、false、unknown)的聚集函数有some和every。(在SQL:1999中引入了布尔数据类型,同时提供处理布尔数据类型的聚集函数)。

24.  数据库的修改

1)  删除

delete from r where P;

其中P代表一个谓词,r代表一个关系。

2)  插入

insert into course values( ‘CS-437’,’Database System’,’Comp.Sci’,4);

在上述例子中,元组属性值的排列顺序和关系模式中属性排列的顺序一致。

下面在insert语句中指定属性:

insert into course (course_id , title , dept_name, credits) value (‘CS-437’,’Database System’,’Comp.Sci’,4) ;

下面以查询结果的基础上插入元组:

insert into instructor

select ID, name, dept_name, 18000

from student

where dept_name= ‘Music’ and tot_cred >144 ;

3)  更新

举例1:

update instructor

set salary = salary * 1.05;

where salary < (select avg(salary) from instructor) ;

举例2:

假设工资超过100000美元的教师涨3%的工资,其余教师的工资涨5%。

update instructor

set salary = salary * 1.03;

where salary > 100000;

update instructor

set salary = salary *1.05;

where salary <100000;

注意上面两条update语句的顺序十分重要。

SQL提供case结构,我们可以利用它在一条update语句中执行前面的两种更新,避免更新错误引发的问题:

update instructor

set salary = case

whensalary <= 100000  then salary * 1.05

elsesalary *1.03

end

case语句的一般格式如下:

case

when pred1 then result1 ;

when pred2 then result2 ;

when pred3 then result3 ;

when predn then resultn ;

else result0

end

case 语句可以用在任何应该出现值的地方。

考虑这样的更新:我们把每一student元组的tot_cred属性值设置为该生成功学完的课程学分的总和。

update student S

set tot_cred = ( select sum(credits)

from takes natural join course

where S.ID = takes.ID and takes.grade <> ‘F’ and takes.grade isnot null

);

如果一个学生没有成功学完任何课程,上述更新语句将其tot_cred属性值设置为空。如果想把这样的属性值设置为0的话,我们可以使用另一条update语句来把空值替换为0。更好的解决方案是把上述子查询中的“select sum(credits)”子句替换为如下使用case表达式的select子句:

select case

whensum(credits) is not null then sum(credit)

else 0

end

所以:

update student S

set tot_cred =(

select case

whensum(credits) is not null then sum(credit)

else 0

end

from takesnatural join course

where S.ID = takes.ID and takes.grade<> ‘F’ and takes.grade is not null

);

25.  连接表达式

SQL连接条件有以下几种:

1)  using条件连接,比如r1 join r2using (A1, A2),连接匹配:r1.A1 = r2.A1 且 r1.A2 = r2.A2。

2)  on条件连接,比如r1 join r2 onr1.A1 = r2.A1, r1.A2 = r2.A2; on条件连接比using条件连接更灵活。on条件谓词的写法与where子句谓词类似。

3)  natural自然连接,比如 r1 natural join r2,含义:在r1和r2两个关系模式中都出现的属性上取值相同的元组对连接起来合为单个元组。连接结果显示顺序:先列出共同属性的值,然后再列出第一个关系模式属性的值,最后第二个关系模式属性的值。

SQL连接类型大体上分为两种:

1)  内连接:对连接的两个关系中,不满足连接匹配条件的元组全部“丢弃”,只保留满足条件的元组。使用关键字inner,此关键字可选,也就是默认的连接是内连接(…inner join …)。比如,natural inner join,

2)  外链接:与内连接对应,将内连接“丢弃”的元组保留下来,根据保留的情况可以分为左外连接(left outer join),右外连接(right outer join)和全外连接(full outer join)。使用关键字outer。

注意:任意的连接形式可以和任意的连接条件进行组合。也就是,内连接和外链接都可以使用上述3种条件连接(using、on和natural)。

内连接包括:

1)  自然连接

a.  一般自然连接

select name, course_id

from instructor natural join teaches ;

等价于

select name, course_id

from instructor, teaches

where instructor.ID = teaches.ID ;

b.  构造形式的自然连接

select name, title

from (instructor natural join teaches ) join courseusing(course_id) ;

两个关系中共同属性中的一个(course_id)作为连接条件,其他的共同属性则不必相等。

外连接包括:

1)  左外连接

select *

from student natural left outer jointakes ;

其中,关键字natural指定了连接条件(也就是共同属性上值相等)。

select *

from student left outer join takes onstudent.ID = takes.ID ;

上面的查询语句运行结果与下面的查询语句运行结果是一样的。从这两句中可以体会on 和where在外连接中的表现是不同的:

select*

from student left outer jointakes on true

where student.ID = takes.ID ;

其中连接条件为true,也就是student与takes作笛卡尔乘积。然后在from子句结果关系中通过where子句筛选出满足student.ID = takes.ID的元组。

2)  右外连接

select *

from takes natural right outer joinstudent ;

3)  全外连接

select *

from (select *

from student

where dept_name= ‘Comp.Sci’)

natural fullouter join

(select *

from takes

where semester =‘Spring’ and year = 2009 ) ;

26.  视图

SQL允许通过查询来定义“虚关系”,它在概念上包含查询的结果。虚关系并不预先计算并存储,而是在使用虚关系的时候才通过执行查询被计算出来。

任何像这种不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为视图(view)。在任何给定的实际关系集合上能够支持大量视图。

1)  视图定义

create view v as<query expression> ;

其中<query expression>可以是任何合法的查询表达式,v表示视图名。

create view physics_full_2009 as

selectcourse.course_id, sec_id, building, room_number

from course,section

wherecourse.course_id = section.course_id

and course.dept_name = ‘Physics’

andsection.semester = ‘Fall’

andsection.year = 2009 ;

2)  SQL查询中使用视图

一旦定义了一个视图,我们就可以用视图名指代该视图生成的虚关系。

select course_id

from physics_full_2009

where building = ‘Watson’ ;

视图的属性可以按下述方式显示指定:

create view physics_full_2009 (coursed,secId,building,roomNumber) as

selectcourse.course_id, sec_id, building, room_number

from course,section

wherecourse.course_id = section.course_id

and course.dept_name = ‘Physics’

andsection.semester = ‘Fall’

andsection.year = 2009 ;

3)  物化视图

特定数据库系统允许存储视图关系,但是它们保证:如果用于定义视图的实际关系改变,视图也要跟着修改。这样的视图被称为物化视图(materialized view)。

为了保持物化视图一直在最新状态的过程称为物化视图维护(materialized view maintenance ),或者通常简称视图维护(viewmaintenance)。

视图维护方式:

a.  实际关系改变时,立即进行视图维护

b.  访问视图时,进行视图维护。

c.  进行周期性视图维护。

物化视图的特点:

a.  优点:查询时可以快速响应,避免读取大量底层关系。

b.  缺点:需要付出存储代价和更新开销。

4)  视图更新

对于查询而言,视图是一个有用的工具。但是,对视图的更新、插入和删除将带来更严重的问题。一般说来,如果定义视图的查询对下列条件都能满足,我们称SQL视图是可更新的(updatable)(即视图上可以进行插入、更新或删除):

a.      from子句中只有一个数据库关系。

b.      select子句中只包含关系的属性名,不包含任何表达式、聚集或distinct声明。

c.       任何没有出现在select子句中的属性可以取空值,即这些属性上没有not null 约束,也不构成主码的一部分。

d.      查询中不含有group by 或having子句。

在这些限制下,下面的视图允许执行update、insert和delete操作:

create viewhistory_instructors as

select *

frominstructor

where dept_name = ‘History’;

可以对history_instructors中进行更新、插入和删除。假设用户尝试向视图中插入元组( ‘25566’,’Brown’,’Biology’,100000),这个元组可以被插入,但是不满足视图所要求的选择条件,所以它不会出现在视图history_instructors中。为了解决这个问题,可以在视图定义末尾加上with check option子句。

27.  事务(transaction)由查询或更新语句(包括插入、删除和更新操作)的序列组成。SQL标准规定当一条SQL语句被执行,就隐式地开始了一个事务。而结束一个事务由下面任何一件事情发生:

1)  Commit work :提交当前事务,也就是将该事务所做的更新在数据库中持久保存。说明该事务成功完成所有步骤。在事务被提交后,一个新的事务自动开始。在某种意义上,事务提交就像对编辑文档的变化存盘,而回滚就像不保存变化退出编辑。

2)  Rollback work :回滚当前事务,即撤销该事务中所有SQL语句对数据库的更新。这样,数据库就恢复到执行该事务第一句之前的状态。

上面两句中的关键字work都是可选的。

一个事务或者在完成所有步骤后提交其行为,或者在不能成功完成其所有动作的情况下回滚其所有动作,通过这种方式数据库提供了对事务具有原子性(atomic)的抽象,原子性也就是不可分割性。

在很多SQL实现中,默认方式下每个SQL语句自成一个事务,且一执行完就提交。如果一个事务要执行多条SQL语句,就必须关闭单独SQL语句的自动提交,如何关闭也依赖于特定的SQL实现。

作为SQL:1999标准的一部分(但目前只有一些SQL实现支持),允许多条SQL语句包含在关键字begin atomic ……end 之间。所有在关键字之间的语句构成了一个单一事务。

28.  完整性约束

保证授权用户对数据库所做的修改不会破坏数据的一致性。

1)  单个关系上的约束

2)  参照完整性约束

3)  复杂check条件与断言

29.  创建索引

在关系属性上创建索引(index)是一种数据结构,它可以高效地找到关系中那些在索引属性上取值给定的元组,而不用扫描关系中的所有元组。

尽管SQL语言没有给出创建索引的正式语法定义,但很多数据库都支持使用如下所示的语法来创建索引:

createindex studentID_index on student(ID) ;

上述语句在student关系的属性ID上创建了一个名为studentID_index的索引。当要查询ID为22201的student元组时,SQL查询处理器就会使用上面定义的studentID_index索引来找到所需的元组,而不用读取整个关系。

30.  关系模式中的码的概念同样适用于实体集和联系集。不管联系集R中有没有其他的属性,联系集中所有的外码构成一个属性集合是该联系集的超码。

《数据库系统概论》学习总结相关推荐

  1. 《HBase权威指南》一导读

    前 言 HBase权威指南 你阅读本书的理由可能有很多.可能是因为听说了Hadoop,并了解到它能够在合理的时间范围内处理PB级的数据,在研读Hadoop的过程中发现了一个处理随机读写的系统,它叫做H ...

  2. 《JS权威指南学习总结--开始简介》

    本书共分成了四大部分: 1.JS语言核心 2.客户端JS 3.JS核心参考 4.客户端JS核心参考 其中 <JS权威指南学习总结--1.1语法核心> 是:第一部分JS语言核心 各章节重点 ...

  3. JavaScript 权威指南-学习笔记(一)

    本文所有教程及源码.软件仅为技术研究.不涉及计算机信息系统功能的删除.修改.增加.干扰,更不会影响计算机信息系统的正常运行.不得将代码用于非法用途,如侵立删! JavaScript 权威指南-学习笔记 ...

  4. Hadoop权威指南学习笔记三

    HDFS简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考.有什么不到之处还望指出,一起学习一起进步. 转载请注明:http://blog.csdn.net/my ...

  5. HBase权威指南 高清中文版 PDF(来自linuxidc)

    内容提要 <HBase权威指南>由乔治(Lars George)著,探讨了 如何通过使用与HBase高度集成的Hadoop将 HBase的可 伸缩性变得简单:把大型数据集分布到相对廉价的商 ...

  6. Hadoop权威指南学习笔记一

    Hadoop简单介绍 声明:本文是本人基于Hadoop权威指南学习的一些个人理解和笔记,仅供学习參考,有什么不到之处还望指出.一起学习一起进步. 转载请注明:http://blog.csdn.net/ ...

  7. 802.11基本概念介绍【802.11 无线网络权威指南学习总结1】

    802.11基本概念介绍[802.11 无线网络权威指南学习总结1] 1.802.11网络技术介绍 IEEE 802 规格的重心放在 OSI 模型最底下的两层,因为它们同时涵盖了实体(physical ...

  8. mysql权威指南 代码_mysql权威指南学习札记

    mysql权威指南学习笔记 1,mysql的标示符最多就64个字符 2,drop table table1,table2,table3;删除多个table的时候用,号分隔开,为了避免不必要的错误,我们 ...

  9. symfony权威指南学习之一:symfony 介绍

    symfony权威指南学习之一:symfony 介绍 一.symfony 简介        symfony 是一个完整的 web 应用开发框架,它为加速开发提供了几个关键功能. 首先,它把 web ...

  10. Http权威指南学习研究

    学习时间:                                   该学习:第六章  6.6小节   加油   185页 2017年5月15日15:13:00 今天任务: 看完前两章节: ...

最新文章

  1. 郎凤娥谈定西实施煤粉锅炉改造项目
  2. Linux教程 网络管理命令Netstat的使用
  3. 如何向本地MSDN帮助库中添加和修改一些帮助内容
  4. 苹果自带相册打马赛克_如果你用苹果手机!学会这3个技巧,就能让手机变得更加好用...
  5. Python入门基础篇(五)字符串的正则表达式re模块,全面解析!!!
  6. [bzoj4006][JLOI2015]管道连接_斯坦纳树_状压dp
  7. Mobile Terminal无法使用常用Unix命令
  8. 微信小程序wx.getUserProfile
  9. 一年四季,你最喜欢哪个季节出去旅游?
  10. OpenSSL 修复可导致 DoS攻击的高危漏洞
  11. 4月27 统计学——卡方检验和卡方分布
  12. 对数换底公式及推导证明
  13. #天府TV#《什么是成都》爆红背后,还有上千热泪盈眶留言!
  14. [ffmpeg][goav][issues] goav Dictionary crash double free
  15. CF 285D 285E
  16. 相机标定后得到相机视域,并根据相机视域求取摄像机位置和摄像机方位角
  17. Linux与数据结构 2019-2-1
  18. 动词变名词的变化规则_动词变职业名词的规则
  19. 什么是video codec? video codec在实际业务的应用。
  20. xAd:南京大学大二学生开发的视频内广告动态植入技术

热门文章

  1. 编程珠玑第二版 ---- 第一章个人习题集(Java)
  2. ESP8266-002 ESP8266EX简介
  3. 最新postfix 的master.cf配置参考
  4. Python爬虫爬取美女写真实例
  5. 热度TopN排名算法的设计
  6. 数据库MYSQL及MYSQL ODBC
  7. Flowable初始化失败 Table ‘xxxx‘ already exist
  8. VBA学习(一)启用VBA、变量、常量、静态变量、字符串拼接、循环语句与判断语句
  9. 如何做默认样式重置?RESETTING 和 NORMALIZING 之间有什么区别?
  10. 为什么会患糖尿病足?可能与这5种原因有关