第四章 中级SQL

4.1 连接表达式

4.1.1 连接条件

on是另一种形式的连接,其中可以指定任意的连接条件。on条件允许在参与连接的关系上设置通用的谓词,该谓词的写法与where子句谓词类似。

1 select*
2 from student join takes on student.ID = takes.ID;

on条件有两个优点,首先,被称为外连接的这类连接来说,on条件的表现与where条件是不同的。其次,如果在on子句中指定连接条件,并在where子句中出现其余的条件,这样的SQL查询通常更容易懂。

4.1.2 外连接

实际上有三种形式的外连接:

  • 左外连接left outer join)只保留出现在左外连接运算之前(左边)的关系中的元组。
  • 有外连接right outer join)只保留出现在右外连接运算之前(右边)的关系中的元组。
  • 全外连接full outer join)保留出现在两个关系中的元组。

不保留未匹配元组的连接运算被称为内连接运算。

右外连接左外连接是对称的。如来自右侧关系中的不匹配左侧关系任何元组的元组被补上空值,并加入到有外连接的结果中。

1 select *
2 from takes natural right outer join student;
3
4 select *
5 from takes natural left outer join student;

得到的结果是一样的,只不过结果中属性出现的顺序不同。

全外连接是左外连接和右外连接类型的的组合。

onwhere在外连接中的表现是不同的,其原因是外连接只为那些对那些对相应内连接结果没有贡献的元组补上空值并加入结果。

on条件是外连接声明的一部分,但where子句却不是。

4.1.3连接类型和条件

为了区分常规连接和外连接,SQL中把常规连接称作内连接。用inner join来代替outer join,说明使用的是常规连接,然而关键字inner是可选的。

类似地,natural join等价于natural inner join

4.2 视图

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

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

4.2.1 试图定义

create view命令定义视图。

create view v as <query expression>

4.2.2 SQL查询中使用视图

一旦定义了一个视图,我们就可以用视图名指代该视图生成的虚关系。一个视图可能被用到定义另一个视图的表达式中。

1 create view departments_total_salary(dept_name, total_salary) as
2     select dept_name, sum(salary)
3     from instructor
4     group by dept_name;

4.2.3 物化视图

特定的数据库系统允许存储视图关系,但是如果用于定义视图的实际视图的实际关系改变,视图也跟着修改,这样的视图被称为物化视图

保持物化视图一直在最新状态的过程称为物化视图维护,或者通常简称视图维护

4.2.4 视图更新

尽管对查询而言,视图是一个有用的工具,但如果我们用它们来表达更新,插入或删除,它们可能带来严重的问题。困难在于,用视图表达的数据库修改必须被翻译为对数据库逻辑模型中实际关系的修改。  

除了一些有限的情况之外,一般不允许对视图关系进行修改。

一般来说,如果定义视图的查询对下列条件都能满足,我们称SQL视图是可更新的:

  • from子句中只有一个数据库关系。
  • select子句中只包含关系的属性名,不包含任何表达式、聚集或distinct声明。
  • 任何没有出现在select子句中的属性可以取空值;即这些属性上没有not null约束,也不构成主码的一部分。
  • 查询中不包含group byhaving子句。

在默认情况下,SQL允许执行上述更新,但是可以通过在视图定义的末尾包含with check option子句的方式来定义视图。这样,如果向视图中插入一条不满足视图的where子句条件的元组,数据库系统将拒绝该插入操作。

4.3 事务

事务由查询和更新语句的序列组成。SQL标准规定当一条SQL语句被执行,就隐式地开始了一个事务。下列SQL语句之一会结束一个事务:

  • Commit work:提交当前事务,也就是将事务所做的更新在数据库中持久保存。在事务被提交后,一个新的事务自动开始。
  • Rollback work:回滚当前事务,即撤销该事务中所有SQL语句对数据库的更新。

关键词work在两条语句中都是可选的。

一旦某事务执行了commit work,它的影响就不能用rollback work来撤销了。

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

SQL1999标准允许多条SQL语句包含在关键字begin atomic…end之间。所有在关键字之间的语句构成了一个单一事务。

4.4 完整性约束

完整性约束通常被看成是数据库模式设计过程的一部分,它作为用于创建关系的create table命令的一部分被声明。然而,完整性约束也可以通过使用alter table table-name add constraint命令施加到已有关系上,其中constraint可以是关系上的任意约束。当执行上述命令时,系统首先保证关系满足指令约束。如果满足,那么约束被施加到关系上;如果不满足,则拒绝执行上述命令。

4.4.1 单个关系上的约束

允许的完整性约束包括:

  • not null
  • unique
  • check(<谓词>)

4.4.2 not null约束

   not null声明禁止在该属性上插入空值。

4.4.3 unqiue约束

unqiue声明指出属性Aj1, Aj2, ... Ajm形成了一个候选码;即在关系中没有两个元组能在所有列出的属性上取值相同。

4.4.4 check子句

当应用于关系声明时,check(P)子句指定一个谓词P,关系中的每个元组都必须满足谓词P。根据SQL标准,check子句中的谓词可以包括子查询在内的任意谓词。

4.4.5 参照完整性

外码声明:foreign key(dept_name) references department。

当参照完整性约束时,通常的处理是拒绝执行导致完整性破坏的操作。但是,在foreign key子句中可以指明:如果被参照关系上的删除或更新动作违反了约束,那么系统必须采取一步步骤通过修改参照关系中的元组来恢复完整性约束,而不是拒绝这样的动作。

1 create table course
2     {...
3     forgein key (dept_name) references department
4         on delete cascade
5         on update cascade,
6     ...};

由于有了与外码声明相关联的on delete cascade子句,如果删除department中的元组导致此参照完整性的约束被违反,则删除并不被系统拒绝,而是对course关系做“级联”删除,即删除参照了被删除系的元组。类似地,如果更新被参照字段时时违反了约束,,则更新操作并不被系统拒绝,而是将course中的参照元组的dept_name字段改为新值。SQL还允许forgein key子句指明除cascade以外的其他动作,如果约束被违反:可将参照域(这里是dept_name)置为null(用set null代替cascade),或者置为域的默认值(用set default)。

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

4.4.6 事务中对完整性约束的违反

事务可能包含几个步骤,在某一步之后完整性约束也许会暂时被违反,但是后面的某一步也许就会消除这个违反。

为了处理这样的情况,SQL标准允许将initially deferred子句加入到约束声明中;这样完整性约束不是在事务的中间步骤上检查,而是在事务结束时检查。一个约束可以被指定为可延迟的。对于声明为可延迟的约束,执行set constraints constraint_list deferred语句作为事物的一部分,会导致对指定约束的检查被延迟到该事务结束时执行。

4.4.7 复杂check条件与断言

SQL标准所定义,check子句中的谓词可以是包含子查询的任意谓词。如果一个数据库实现支持在check子句中出现子查询,我们就可以在关系section上声明如下参照完整性约束: check (time_slot_id in (select time_slot_id from time_slot))

一个断言就是一个谓词,它表达了我们希望数据库总能满足的一个条件。域约束和参照完整性约束都是断言的特殊形式。断言形式如下:

create assertion <assertion-name> check <predicate>;

1 create assertion credits_earned_constraint check
2     (not exists (select ID
3         from student
4         where tot_cred < > (select sum (credits)
5                                     from takes natural join course
6                                     where student.ID = takes.ID
7                                     and grade is not null and grade < > ‘F‘)))

4.5 SQL的数据类型与模式

4.5.1 SQL中的日期和时间类型

  • date:日历日期,包括年(四位)、月和日。
  • time:包括小时、分和秒。可以用time(p)表示秒的小数点后的数字位数。通常指定time with timezone,还可以把时区信息连同时间一起存储。
  • timestamp:date和time的组合。可以用变量timestamp(p)来表示秒的小数点后的数字位数(默认6位)。如果指定with timezone,则时区信息也会被存储。
1 date ‘2001 - 04 - 25‘
2 time ‘09:30:00‘
3 timestamp ‘2001 - 04 - 25 10:29:01.45‘

4.5.2 默认值

SQL允许为属性指定默认值。(tot_cred)

1 create table student
2     (ID varchar(5),
3     name varchar(20) not null,
4     dept_name varchar(20),
5     tot_cred numeric(3,0) default 0,
6     primary key(ID));

4.5.3 创建索引

create index studentID_index on student(ID);

4.5.4 大对象类型

SQL提供字符数据的大对象类型(clob)和二进制数据类型的大对象数据类型(blob)。

1 book_review clob (10KB)
2 image blob (10MB)
3 movie blob (2GB)

4.5.5 用户定义的类型

SQL支持两种形式的用户定义数据类型。第一种称为独特类型,另一种称为结构化数据类型

一个好的类型系统应该能够检测出这类赋值或比较,为了支持这种检测,SQL提供了独特类型的概念。可以用create type子句来定义新类型。如:create type Dollars as numeric(12, 2) final;

一种类型的数值可以被转换(也即cast)到另一个域,cast(department.budget to numeric(12, 2))

SQL提供drop typealter type子句来删除或修改以前创建过的类型。

4.5.6 create table的扩展

应用常常要求创建于现有的某个表的模式相同的表。SQL提供一个create table like的扩展来支持: create table tempp_instructor like instructor;

当书写一个复杂查询时,把查询的结果存储成一个新表通常是很有用的;这个表通常是临时的。SQL2003提供了一种更简单的技术来创建包含查询结果的表。

1 create table tl as
2     (select*
3      from instructor
4      where dept_name = ‘Music‘)
5 with data;

SQL2003标准定义,如果忽略with data子句,表会被创建,但不会载入数据。

4.5.7 模式、目录与环境

默认目录和模式是为每个连接建立的SQL环境的一部分。环境还包括用户标识。所有通常的SQL语句,包括DDL和DML语句,都在一个模式的环境中运行。

可以用create schemadrop schema语句来创建和删除模式。

4.6 授权

4.6.1 权限的授予与收回

SQL标准包括selectinsertupdatedelete权限。grand语句用来授权,基本形式:

1 grant<权限列表>
2 on <关系名或视图名>
3 to <用户/角色列表>
4
5 grant select on department to Amit, Satoshi;

revoke语句来收回权限。

1 revoke <权限列表>
2 on <关系名或视图名>
3 to <用户/角色列表>
4
5 revoke seleect on department from Amit, Satoshi;

4.6.2 角色

在数据库中建立一个角色集,可以给角色授予权限,就和给每个用户授权的方式完全一样。每个数据库用户被授予一组他有权扮演的角色(也可能是空的)。

1 create role instructor;
2
3 grant select on takes
4 to instructor;
5
6 grant dean to Amit;
7 create role dean;
8 grant instructor to dean;
9 grant dean to Satoshi;

4.6.3 视图的授权

在函数或过程上可以授权execute权限,以允许用户执行该函数或过程。在默认情况下,和视图类似,函数和过程具有其创建者拥有的所有权限。在效果上,该函数或过程的运行就像其被创建者调用那样。

尽管此行为在很多情况下是恰当的,但是它并不总是恰当。从SQL2003开始,如果函数定义有一个额外的sql security invoker子句,那么它就在调用该函数的用户的权限下执行,而不是在函数定义者的权限下执行。这就允许创建的函数库能够与调用者相同的权限下运行。

4.6.4 模式的授权

SQL提供了一种references权限,允许用户在创建关系时声明外码。SQL的reference权限可以与update权限类似的方式手遇到特定属性上。

grant references(dept_name) on department to Mariano;

4.6.5 权限的转移

如果我们在授权时允许接受者把得到的权限在传递给其他用户,我们可以在相应的grant命令后面附加with grant option子句。

grant select on department to Amit with grant option

4.6.6 权限的收回

从一个用户/角色那里收回权限可能导致其他用户/角色也失去该权限,这一行为称作级联收回。在大多数的数据库系统中,级联时默认行为。然而,revoke语句可以申请restrict来防止级联收回: revoke select on department from Amit, Satoshi restrict

可以用关键字cascade来替换restrict,以表示需要级联收回;然而cascade可以省略,是默认的。下面的revoke语句仅仅收回grant option,而不是真正收回select权限:revoke grant option for select on department from Amit;

如果要在授权时将授权人设置为一个会话所关联的当前角色,并且当前角色不为空的话,可以在授权语句后面加上:grant by current_role

假设将角色instructor授予Amit是用grant by current_role子句实现的,当前角色被设置为dean而不是授权人(用户Satoshi),那么,从Satoshi处收回角色/权限(包括角色dean)就不会导致收回角色dean作为授予的权限,即使Satoshi是执行该授权的用户;这样,即使Satoshi额权限被收回,Amit仍然能够保持instructor角色。

时间: 2024-10-31 01:07:31

第四章 中级SQL的相关文章

源码-PL/SQL从入门到精通-第四章-PL/SQL控制语句(基础中的基础)

控制语句对任何一门语言.任何一个程序员而言,都是基础中的基础. 学了PL/SQL,才体会到Java语法的简洁,简直不是一个时代的东西:当然,他们的定位本来就不一样,不能以己之长比之他人之短. --第4章开始 --代码4.1 最简单的IF语句使用示例 DECLARE v_count NUMBER(10) := 0; --定义计数器变量 v_empno NUMBER(4) := 7888; --定义员工编号 BEGIN SELECT COUNT(1) --首先查询指定的员工编号是否存在 INTO v

数据库系统原理(第四章:SQL与关系数据库基本操作 )

一.SQL概述 sql是结构化查询语言(Structured Query Language,SQL)是专门用来与数 据库通信的语言,它可以帮助用户操作关系数据库. SQL的特点: SQL不是某个特定数据库供应商专有的语言: SQL简单易学 :SQL强大.灵活,可以进行非常复杂和高级的数据库操作 SQL的组成: 数据查询 数据定义语言(Data Definition Language,DDL) 数据操纵(DML) 数据控制(DCL) *******************数据定义语言*******

Java Persistence with MyBatis 3(中文版) 第四章 使用注解配置SQL映射器

在上一章,我们看到了我们是怎样在映射器Mapper XML配置文件中配置映射语句的.MyBatis也支持使用注解来配置映射语句.当我们使用基于注解的映射器接口时,我们不再需要在XML配置文件中配置了.如果你愿意,你也可以同时使用基于XML和基于注解的映射语句. 本章将涵盖以下话题: l 在映射器Mapper接口上使用注解 l 映射语句 @Insert,@Update,@Delete,@SeelctStatements l 结果映射 一对一映射 一对多映射 l 动态SQL @SelectProvi

【Oracle】第四章异常处理

第四章异常处理 PL/SQL 块是构成 PL/SQL 程序的基本单元 将逻辑上相关的声明和语句组合在一起 PL/SQL 分为三个部分,声明部分.可执行部分和异常处理部分 [DECLARE declarations] BEGIN executable statements [EXCEPTION handlers] END; 以下示例演示了如何使用PL/SQL 语句: declare area integer; width integer; height integer; currentdate d

第四章:4.2MySQL 权限系统介绍

4.2.1 权限系统简介 MySQL 的权限系统在实现上比较简单,相关权限信息主要存储在几个被称为granttables 的系统表中,即: mysql.User,mysql.db,mysql.Host,mysql.table_priv 和mysql.column_priv.由于权限信息数据量比较小,而且访问又非常频繁,所以Mysql 在启动的时候,就会将所有的权限信息都Load 到内存中保存在几个特定的结构中.所以才有我们每次手工修改了权限相关的表之后,都需要执行"FLUSH PRIVILEGE

14第十四章触发器(转载)

14第十四章触发器 DML --> AFTER / FOR   UPDATE , INSERT , DELETE  -- 用来级联删除 --> INSTEAD OF  在 时间之前触发,相当于 bef INSERTED, DELETED 两张表要好好利用. 在创建 DML 触发器时,不能使用下列语句: CREATE / ALTER /DROP DATABASE LOAD DATABASE / LOAD LOG / RECONFIGURE RESTORE DATABASE  / RESTORE

OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章)

OpenGL ES着色器语言之变量和数据类型(二)(官方文档第四章) 4.5精度和精度修饰符 4.5.1范围和精度 用于存储和展示浮点数.整数变量的范围和精度依赖于数值的源(varying,uniform,纹理查找,等等),是不是顶点或者片元着色器,还有其他一些底层实现的细节.最低存储需要通过精度修饰符来声明.典型地,精度操作必须要保留变量包含的精度存储.仅有的例外是需要大量复杂计算的内建函数,如atan(),返回值的精度低于声明的精度. 强烈建议顶点语言提供一种匹配IEEE单精度浮点数或更高精

2015年下半年软考中高级学员精讲班 &nbsp; 第四章

2015年下半年软考中高级学员精讲班 主讲:王老师 中级学员和高级学员一起看中级教程 中级教程第四章 项目管理一般知识(P135-183) 中高级学员上午考试:3分选择题    下午考试:不考 高级学员本周重点是4.4节 上半年试题(19) ●矩阵型组织的缺点不包括(19). A. 管理成本增加                B. 员工缺乏事业上的连续性和保障 C. 多头领导                     D. 资源分配与项目优先的问题产生冲突 试题分析:矩阵型组织存在着管理成本增加.

第四章 Hibernate入门

第四章 Hibernate入门4.1 框架技术    4.1.1 框架的概念        框架是一个提供了可重用的公共结构的半成品.    4.1.2 主流框架        4.1.2.1 Struts框架        4.1.2.2 Struts2框架        4.1.2.3 Hibernate框架            一个优秀的持久化框架,负责简化对象数据保存到数据库中,或从数据库中读取数据并封装到对象的工作.        4.1.2.4 Spring框架4.2 Hibern