中级SQL
连接表达式
连接条件
join ...using只需在指定属性上的取值匹配
on条件可以指定任意的连接条件 ,连接结果中相等的属性出现2次
等价于
外连接
通过在结果中创建包含空值元组的方式,保留那些在连接中丢失的元组
左外连接(left outer join)只保留出现在左外连接运算之前(左边)关系中的元组
右外连接(right outer join)只保留出现在右外连接运算之后(右边)关系中的元组
全外连接(full outer join)保留出现在2个关系中的元组
内连接(inner join)不保留未匹配元组的运算,inner 可以省略
外连接只为那些对相应的内连接结果没有贡献的元组补上空值并加入结果,上面表达式每个元组都满足连接条件true,因此外连接不会产生出补上空值的元组,外连接实际上产生了两个关系的笛卡儿积
连接类型有 inner join,left outer join,right outer join,full outer join
连接条件有natural,on(结果关系中相等属性都保留),using(结果关系中相等属性只保留一个)
视图
作为虚关系对用户可见的关系,虚关系并不预先计算并存储,而是使用虚关系的时候才通过执行查询被计算出来
视图关系是在需要的时候才被创建
创建视图create view 视图名 as 查询表达式
视图的属性名可以显示指定
当我们定义一个视图时,数据库系统存储视图的定义本身,而不存储定义该视图的查询表达式的执行结果
一个视图可能被用到定义另一个视图的表达式中
物化视图
特定数据库允许存储视图关系,如果用户定义的实际关系改变,视图也跟着修改
保持物化视图一直在最新状态的过程称为物化视图维护,通常简称视图维护
视图更新
视图是一个有用的工具,但如果我们用它来表达更新、插入和删除,他们可能带来严重的问题
一般来说,如果定义视图的查询对上述条件都满足,我们称SQL视图是可更新的,这样数据库
事务
SQL规定当一条SQL语句被执行,就隐式的开始了一个事务
下列SQL语句会结束一个事务
commit work:提交当前事务,也就是将该事物所做的更新在数据库中持久保存。在事物被提交后,一个新的事物自动开始
rollback work:回滚当前事务,也就是撤销该事务中所有SQL语句对数据库的更新,就恢复到执行该事务第一语句之前的状态。
关键词work可选
一个事务或者在完成所有步骤后提交其行为,或者在不能成功完成其所有动作的情况下回滚其所有动作,通过这种方式数据库提供了对事务具有原子性的抽象,原子性即不可分割性。
要么所有事务的所有影响被反映到数据库中,要么任何影响都没有(在回滚之后)
完整性约束
保证授权用户对数据库所做修改不会破坏数据的一致性,完整性约束防止是对数据的意外破坏
完整性约束可在创建关系create table命令的一部分被声明,也可以通过alter table table-name add constraint命令施加到关系上(首先保证关系满足指定的约束)
not null约束:非空约束,声明为主码默认为非空,不必显示声明
unique约束:在关系中没有2个元组能在所有列出的属性上取值相同,然而候选码可以为空
check子句:check(P)子句指定一个谓词,关系中的每一个元组都必须满足谓词P,check子句保证属性值满足指定的条件
参照完整性约束(或子集依赖):
默认情况下,SQL中外码参照的是被参照表中的主码属性
references可以显示指定被参照关系的属性列表,然而这个指定的属性列表必须声明为被参照关系的候选码
当违反参照完整性约束时,通常是拒绝执行导致完整性破坏的操作(即进行更新操作的事务被回滚)
on delete cascade ,若删除department中的元组导致了此参照完整性约束被违反,则删除并不被系统拒绝,而是对course关系作级联删除
如果存在涉及多个关系的外码依赖链,则在链一端所做的删除或更新可能传至整个链
事务中对完整性约束的违反,SQL允许将initially deffrred子句加入到约束声明中,这样完整性约束不是在事务的中间步骤上检查,而是在事务结束的时候检查。默认情况下它会被立即检查
复杂check条件检测开销很大,我们可以使用断言,表达数据库总能满足某一个条件
SQL允许指定默认值
当一个元组被插入到student中,如果没有给出tot_cred属性的值,那么该元组在此属性上就被置为0
SQL中的日期和时间类型
一些获取当前日期和时间的函数
current_date返回当前日期
current_time返回当前时间
localtime返回当前的本地时间
时间戳(日期加上时间)由current_timestamp(带有时区)
localtimestamp(本地日期和时间,不带时区)
SQL允许在上面列出的所有类型上进行比较运算,也允许在各种数字类型上进行算术运算和比较运算
还支持interval数据类型,允许在日期、时间、和时间间隔上进行运算
x,y都是date类型,那x-y就是时间间隔类型,其值为日期x到日期y间隔的天数
独特类型
可以用create type子句来定义新类型
不能为一种类型的变量赋予另一种类型的值
新创建的类型就可以用作关系属性的类型
SQL提供了drop type 和 alter type子句来删除或修改以前创建过的类型
创建索引
在把用户定义类型加入到SQL之前,有一个相似但稍有不同的概念,域,它可以在基本类型上施加完整性约束
DDollars域可以用作属性类型,正如上面的定义类型一样
域和类型的差别:
1.在域上,可以声明约束,也可以为域类型变量定义默认或默认值
2.域不是强类型,一种域类型的值可以被赋给另一种域类型的变量,只要他们基本类型相同
把check子句用到域上,被声明为来自该域的任何变量都必须满足这个谓词
constraint salary_value_test子句可选,用来将该约束命名为salary_value_test
在数据库实现中实现对类型和域的支持,不同数据库支持程度不同
创建与现有的表模式相同的表
把查询的结果存储成一个新表
一条用于创建表,另一条用于把查询结果插入到表中
create table...as与create view语句非常相似
区别在于当表被创建时表的内容被加载,但视图总是反应当前查询的结果
授权
权限包括select、insert、update、delete
all privileges所有权限可以用作所有权限的简写形式
一个创建了新关系的用户将自动被授予该关系上的所有权限
grant用来授予权限
update可以在关系的所有属性上授予,也可以只在某些属性上授予
insert也可以指定属性列表,系统将其他属性要么赋予默认值要么赋值为null
用户名public指系统的所有当前用户和将来用户
默认情况下,被授予权限的用户和角色无权把此权限授予其他用户/角色
SQL允许用授予权限的接受者可以进一步把权限授予其他人
不允许对一个关系的指定元组授权
使用revoke语句来收回权限
角色
在数据库中建立一个角色集,可以给角色授予权限,就和给每一个用户授权的方式完全一样
创建角色
授权给角色
角色可以授权给用户,也可以授权给其他角色
一个用户或一个角色的权限包括:
所有直接授予用户/角色的权限
所有授予给用户/角色所拥有角色的权限
视图的授权
在这个例子中,视图的创建者必须在instructor关系上具有select权限,否则系统会拒绝这样的视图创建请求
模式的授权
允许用户在创建关系时声明外码
允许权限的接受者将该权限授予给其他用户
restrict防止权限的级联收回
替换成cascade表示需要级联收回,默认需要级联收回
授予权限时将授权人设置为一个会话所关联的当前角色,并且当角色不为空时,可在授权语句后加子句
收回角色/权限时任然能保持当前角色