DBMS-SQL:连接表达式视图事务完整性约束数据类型与模式授权

Posted 荒废的养鸡场

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DBMS-SQL:连接表达式视图事务完整性约束数据类型与模式授权相关的知识,希望对你有一定的参考价值。

连接表达式

Join…using:允许用户指定需要哪些列相等,只需在指定属性上取值匹配。

e.g.

r1 join r2 using (A1, A2)
/*与r1和r2自然连接类似,但只要在t1.A1=t2.A1并且t1.A2=t2.A2成立的前提下,r1的元组t1和r2的元组t2就能匹配。即使r1和r2都具有名为A3的属性,也不需要考虑。*/

Join…on: 允许在参与连接的关系上设置通用的谓词。

e.g.

select *
from student join takes on student.ID = takes.ID;
/*如果一个来自student的元组和一个来自takes的元组在ID上的取值相同,那么它们是匹配的。
查询结果中ID属性出现两次,分别表示为student.ID和takes.ID
等价from student, takes where student.ID = takes.ID */

 

外连接

内连接(inner join):不保留未匹配元组的常规连接运算,关键词inner可选(join子句默认连接类型时inner join)。

外连接(outer join):通过在结果中创建包含空值元组的方式,保留了在自然连接中丢失的元组(因为有些属性为空值而不满足自然连接条件的元组)。

任意连接形式(内连接、左外连接、右外连接、全外连接)可以和任意的连接条件(自然连接、using条件连接、on条件连接)进行组合。

三种形式的外连接:

·左外连接(left outer join)只保留出现在左外连接运算之前(左边)的关系中的元组。

操作过程:计算内连接结果,对于在内连接左侧关系中任意一个与右侧关系中任何元组都不匹配的元组t,向连接结果加入一个元组r。元组r从左侧关系得到的属性被赋为t中的值,其他属性被赋为空值。

·右外连接(right outer join)只保留出现在右外连接运算之后(右边)的关系中的元组。

操作过程:和左外连接对称

·全外连接(full outer join)保留出现在两个关系中的元组。

操作过程:左外连接和右外连接组合,左右侧中任何不匹配另一侧关系的任何元组被添加上空值加入结果中。

e.g.

select *
from student natural left outer join takes
select *
from takes natural right outer join students;/*结果相同,只是结果中属性出现的顺序不同。*/

e.g. 显示Comp.Sci.系所有学生以及他们在2009年春季选修的所有课程段的列表,2009年春季开设的所有课程段都必须显示(即使没有Comp.Sci系学生选修)

select *
from ( select *
 from student
 where dept_name = ‘Comp.Sci’)
natural full outer join
( select *
 from takes
 where semester = ‘Spring’ and year = 2009);

 

onwhere的不同点:on和where在外连接中的表现不同,on条件是外连接声明的一部分,where子句不是。

e.g.

/*ID为70557的学生Snow的student元组没有对应的takes元组
使用on条件的外连接的结果中有ID位70557的学生的元组并为其补上空值 */
select *
from student left outer join takes on student.ID = takes.ID;
/*使用where子句,on条件true的外连接结果不会产生补上空值的元组,该元组会被where子句谓词排除掉 */
select *
from student left outer join takes on true
where student.ID = takes.ID;

 

视图

视图(view):SQL允许通过查询来定义“虚关系”,虚关系在概念上包含查询的结果,但并不预先计算并存储,而是在使用虚关系的时候才通过执行查询被计算出来。任何不是逻辑模型的一部分,但作为虚关系对用户可见的关系称为视图。

视图可以把信息从多个关系手机到一个单一的视图中,隐藏不需要的信息。

定义视图时,数据库系统存储与视图关系相关联的表达式(视图的定义本身)而不存储定义该视图的查询表达式的执行结果。当视图关系被访问时,其中的元组都是通过重新计算查询结果才被创建出来的。

视图定义

create view名命令定义视图,必须给视图提供名称和计算视图的查询。格式:

create view v as <query expression>;
--v表示视图名,<query expression>可以是任何合法的查询表达式。

e.g. 定义提供给职员的视图关系faculty,职员需要访问instructor关系中除salary之外的数据

create view faculty as
select ID, name, dept_name
from instructor;

视图的属性名可显式指定。

e.g. 定义给出每个系中所有教师工资总合的视图,显示定义属性名total_salary为表达式sum(salary)的名称

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

使用视图

定义视图后,可用视图名指代该视图生成的虚关系,查询中视图名可出现在关系名可以出现的任何地方(e.g. 视图可能被用于定义另一个视图的表达式中。)。

e.g. 使用视图physics_fall_2009找到所有于2009年秋季学期在Watson大楼开设的Physics课程

select course_id
from physics_fall_2009
where building = ‘Watson’;

 物化视图

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

物化视图维护(materialized view maintenance):或简称视图维护(view maintenance),是保持物化视图一直在最新状态的过程。

视图更新

视图更新的困难在于用视图表达的数据库修改必须翻译为对数据库逻辑模型中实际关系的修改。视图的插入必须表示为用于构造该视图的实际关系的插入。

E.g.如果对视图关系插入元组,而实际关系的插入必须给出的某些属性的值不在视图关系中,存在两种解决方法:a. 拒绝插入并向用户返回错误信息;b. 向实际关系插入元组,视图关系中没有的属性值用空值来更新。

但有些情况下即使用空值来更新也无法产生更新视图关系所需的结果,所以一般不允许对视图关系进行修改。不同数据库系统指定了不同的条件以允许更新视图关系。

如果定义视图的查询满足下列所有条件,则称SQL视图是可更新的(updatable,可执行插入、更新或删除):

·from子句中只有一个数据库关系;

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

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

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

注意:即便在可更新的情况下,用户插入/更新的元组也可能由于不满足视图所要求的选择条件,虽然被插入/更新到实际关系中但不出现在视图关系中。(默认情况下SQL允许执行上述更新。)

处理方法:可在视图定义的末尾包含with check option子句,如果向视图中插入/更新一条不满足视图where子句条件的元组,数据库系统将拒绝该插入/更新操作。

 

事务

事务(transaction):由查询和(或)更新语句的序列组成。当一条SQL语句被执行,就隐式开始了一个事务。SQL语句Commit work或Rollback work会结束一个事务(关键词work在两条语句中都是可选的)。

Commit work:提交当前事务(将该事务所做的更新在数据库中持久保存)。在事务被提交后,一个新的事务自动开始。

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

一旦某事务执行了commit work,其影响就不能用rollback work来撤销。数据库系统保证在发生SQL语句错误/断电/系统崩溃等故障的情况下,如果一个事务还没有完成commit work,其影响将被回滚。

在很多SQL实现中默认每个SQL语句自成一个事务,且一执行完就提交。如果一个事务要执行多条SQL语句,就必须关闭单独SQL语句的自动提交。

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

 

完整性约束

完整性约束保证授权用户对数据库所做的修改不会破坏数据的一致性,防止对数据的意外破坏。

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

Create table命令中允许的完整性约束包括:not null、unique、check(<谓词>)。

1. not null约束

SQL中默认情况下空值是每个属性的合法值,但一些属性可能希望禁止空值,可通过not null声明禁止在该属性上插入空值空值:

e.g. 限定属性name和budget的域,排除空值

name varchar(20) not null
budget numeric(12,2) not null

SQL禁止在关系模式的主码中出现空值,因此声明属性为主码时不必显式声明为not null。

2. unique约束

unique(Aj1, Aj2, …, Ajm)

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

候选码属性可以为null,除非它们已经被显式声明为not null。

3. check子句

当应用于关系声明时,check(P)子句指定一个谓词P,关系中的每个元组都必须满足谓词P。

check子句通常用来保证属性值满足指定的条件,check子句中的谓词可以使包括子查询在内的任意谓词)。

e.g. 创建关系department的create table命令中的check(budget>0)子句保证budget上的取值是正数。

e.g. check子句模拟枚举类型,指定semester必须是’Fall’, ‘Winter’, ‘Spring’或’Summer’中的一个来实现

create table section
  ( course_id varchar(8),
   sec_id varchar(8),
   semester varchar(6),
   year numeric(4, 0),
   building varchar(15),
   room_number varchar(7),
   time_slot_id varchar(4),
   primary key(course_id, sec_id, semester, year),
   check(semester in (‘Fall’, ‘Winter’, ‘Spring’, ‘Summer’)));

4. 参照完整性

参照完整性(referential integrity):保证在一个关系中给定属性集上的取值也在另一关系的特定属性集的取值中出现。

参照完整性约束(referential-integrity constraint):令关系r1和r2的属性集分别为R1和R2,主码分别为K1和K2。如果要求对r2中任意元组t2均存在r1中元组t1使得t1.K1=t2.α,我们称R2的子集α为参照关系r1中K1的外码(foreign key)。

参照完整性约束又可称为子集依赖(subset dependency),表述为:r2中α上的取值集合必须是r1中K1上的取值集合的子集。为使参照完整性约束有意义,α和K1必须是相容的属性集。

可用create table语句中的foreign key子句声明外码。

e.g. course表定义中的foreign key子句

foreign key(dept_name) references department
/*在每个课程元组中指定的系名必须在department关系中存在。没有这个约束,就可能会为一门课程指定一个不存在的系名。*/

e.g. 简写定义属性并声明该属性为外码

dept_name varchar(20) references department

默认情况下,SQL中外码参照的是被参照表中的主码属性。不同于外码约束,参照完整性约束通常不要求K1是r1的主码。

reference子句可显示指定被参照关系的属性列表,指定的属性列表必须声明为被参照关系的候选码(使用primary key约束或unique约束)。在更为普遍的参照完整性约束形式中,被参照的属性不必是候选码,但此形式还不能在SQL中直接声明。

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

e.g. 在关系course上定义完整性约束

create table course
  ( …
  foreign key (dept_name) references department
on delete cascade
on update cascade,
  …);
/*on delete cascade子句与外码声明相关联。如果删除department中的元组导致此参照完整性约束被违反,则删除并不被系统拒绝,而是对course关系作“级联”删除(删除参照了被删除关系的元组)。
On update cascade子句与外码声明相关联,如果更新被参照字段时违反了约束,则更新操作并不被系统拒绝,而是将course中参照的元组的dept_name字段也改为新值。*/

SQL还允许foreign key子句指明其他动作。set null:如果约束被违反,可将参照域(e.g. dept_name)置为null;set default:置为默认值。

如果存在涉及多个关系的外码依赖链,则在链一端所做的删除或更新可能传至整个链。

如果一个级联更新或删除辺的对约束的违反不能通过进一步的级联操作解决,则系统中止该事务(该事务所做的所有改变及级联动作都将被撤销。)

外码中的属性允许为null(只要没有被声明为not null)。如果给定元组中外码的所有列上均取非空值,则对该元组采用外码约束的通常定义;如果某外码列为null,则该元组自动被认为满足约束。

5. 延迟约束检查

事务可能包括几个步骤,在某一步之后完整性约束也许会暂时被违反,但后面的某一步也许会消除这个违反。为处理这种情况,SQL标准允许将initially deferred子句加入到约束声明中,这样完整性约束不是在事务的中间步骤上检查,而是在事务结束的时候检查。

一个约束可以被指定为可延迟的(deferrable),使默认情况下它会被立即检查,但在需要时可以延迟检查。对于声明为可延迟的约束,执行set constraints constraint-list deferred语句作为事务的一部分,可使对指定约束的检查被延迟到该事务结束时执行。(许多数据库实现不支持延迟约束检查)。

6. 复杂check条件与断言

SQL标准也支持使用复杂check条件和断言来声明完整性约束(这些结构目前还没有被大多数数据库系统支持)。

复杂check条件:SQL标准定义check子句中的谓词可以使包含子查询的任意谓词,如果一个数据库实现支持在check子句中出现子查询,可以使用复杂check条件声明完整性约束。复杂check条件在确保数据完整性时非常有用,但检测开销可能较大。

e.g. 在关系section上声明参照完整性约束

check(time_slot_id in (select time_slot_id from time_slot))
/*check条件不仅在section关系发生更新时检测,而且可能在time_slot关系发生更新时也需要检测。*/

断言(assertion):断言是描述性表达式,指定了我们要求总是为真的谓词。一个断言就是一个谓词,表达了我们希望数据库总能满足的一个条件。域约束和完整性约束就是断言的特殊形式。

SQL中断言的形式:

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

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

/*通过”not exists X such that not P(X)”结构实现”for all X, P(X)”约束*/
create assertion credits_earned_constraint check
(not exists (select ID
  from student
  where tot_cred <> (select sum(credits)
                  from takes natural join course
                  where student.ID = takes.ID
                  and grade is not null and grade <> ‘F’)));

 

SQL的数据类型与模式

(基本数据类型见”DBMS-SQL:聚集函数、嵌套子查询、数据库修改:SQL数据定义/1. 属性的基本取值类型”)

SQL数据定义语言提供对定义诸如date和time等固有域类型以及用户定义域类型的支持。

1. SQL中的日期和时间类型

·date:日历时期,包括年(4位)、月、日。

·time:一天中的时间,包括小时、分、秒。

可用变量time(p)表示秒的小数点后的数字位数(默认值为0);

指定time with timezone可将时区信息连同时间一起存储。

·timestamp:date和time的组合。

可用变量timestamp(p)表示小数点后的数字位数(默认值为6);

指定with timezone可连同时区信息一起存储。

e.g.

date ‘2001-04-25’
time ’09:30:00timestamp2001-04-25 10:29:01.45/*日期类型必须按照年月日的格式顺序指定,time和timestamp的秒部分可能会有小数部分。*/

可使用cast e as t将字符串(或字符串表达式)e转换为类型t。其中t为date、time、timestamp中的一种,字符串必须符合正确的格式。

可使用extract(field from d)从date或time值d中提取出单独的域。其中域可以使year、month、day、hour、minute、second中的一种。

可使用timezone_hour和timezone_minute提取时区信息。

SQL定义了一些函数以获取当前日期和时间:current_date返回当前日期;current_time返回当前时间(带有时区);localtime返回当前本地时间(不带时区);current_timestamp返回时间戳(日期+时间,带有时区);localtimestamp返回本地时间戳(本地日期+时间,不带时区)。

SQL允许在以上列出类型上进行比较运算,在各种数字类型上进行算术和比较运算。

SQL允许在日期、时间和时间间隔上进行计算,e.g. date相减得到时间间隔;date或time上加减时间间隔得到新的date或time。

2. 默认值

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

e.g. 声明student关系的tot_cred属性的默认值为0

create table student
  ( ID varchar(5),
   name varchar(20) not null,
   dept_name varchar(20),
   tot_cred numeric(3, 0) default 0,
   primary key(ID) );
/*当一个元组被插入到student关系中时,如果没有给出tot_cred属性的值,那么该元组在此属性上取值就被置为默认值0。*/
--省略tot_cred属性的值的插入语句
insert into student(ID, name, dept_name)
  values(‘12789’, ‘Newman’, ‘Comp.Sci’);

3. 创建索引

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

许多数据库支持使用的创建索引的与发行时(SQL没有给出正式语法定义):

--在student关系的属性ID上创建一个名为studentID_index的索引
create index studentID_index on student(ID);

4. 大对象类型

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

e.g. 声明大对象数据类型属性

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

应用通常用SQL查询检索出一个大对象的定位器,然后在宿主语言中用这个定位器来操纵对象。

5. 用户定义的类型

SQL支持两种形式的用户定义数据类型:结构化数据类型(structured data type)和独特类型(distinct type)。

结构化数据类型允许创建具有嵌套记录结构、数组和多重集的复杂数据类型;

独特类型支持对不同类型赋值或比较的检测,避免类似“将一个以美元表示的货币值直接与一个以英镑表示的货币值比较”的程序错误。

e.g. 

/*create type子句定义新类型
定义用户定义类型Dollars和Pounds为总共12位数字的十进制数,其中两位放在小数点后。*/
create type Dollars as numeric(12, 2) final;
create type Pounds as numeric(12, 2) final;
--定义的新类型Dollars和Pounds可用作关系属性的类型
create table department
  (dept_name varchar(20),
   building varchar(15),
   budget Dollars);
--尝试为Pounds类型变量赋予一个Dollars类型的值会导致编译错误
/*由于强类型检查,表达式(department.budget+20)不会被接受,因为属性和整型常数为不同类型。
一种类型的数值可被cast到另一个域:*/
cast(department.budget to numeric(12, 2))
/*可在数值类型上做加法,再用另一个类型转换表达式转换回Dollars类型*/

drop type和alter type子句可删除或修改以前创建过的类型。

域(domainSQL-92引入,可在基本类型上施加完整性约束。域约束指定了在一个属性上可能取值的集合,这种约束也可以禁止在特定属性上使用空值。

e.g. 定义域DDollars

create domain DDollars as numeric(12, 2) not null;

定义的域可用作属性类型,用户定义类型和域之间有两个重大差别:

1)在域上可以声明约束,也可为域类型变量定义默认值;用户定义类型上不能声明约束或默认值。

2)域不是强类型的。一个域类型的值可以被赋给另一个域类型,只要它们的基本类型是相容的。

当把check子句应用到域上,允许指定一个谓词,被声明为来自该域的任何变量都必须满足这个谓词。

e.g. check子句约束教师工资域YearlySalary中只出现大于给定值的值

/*constraint salary_value_test子句可选,用于将该约束命名为salary_value_test*/
create domain YearlySalary numeric(8, 2)
  constraint salary_value_test check(value>=29000.00);

e.g. 使用in子句可限定一个域只包含指定的一组值

create domain degree_level varchar(10)
  constraint degree_level_test
    check(value in(‘Bachelors’, ‘Masters’, or ‘Doctorate’));

6. create table的扩展

create table like支持创建与现有某个表的模式相同的表。

e.g. 创建一个与instructor具有相同模式的新表temp_instructor

create table temp_instructor like instructor;

create table as + with data支持创建包含查询结果的新表。默认情况下列的名字和数据类型从查询结果中推导,通过在关系名后列出列名可给列显式指派名字。

e.g. 创建表t1,该表包含一个查询的结果

create table t1 as
  ( select *
   from instructor
   where dept_name = ‘Music’ )
with data;

SQL: 2003定义,如果省略with data子句,表会被创建但不会载入数据。(但很多数据库实现还是默认加载数据)

Create table…as语句和create view语句非常相似,主要区别在于当表被创建时表的内容被加载,而视图的内容总是反映当前查询的结果。

7. 模式、目录与环境

当代数据库系统提供三层结构的关系命名机制。最顶层由目录(catalog构成【一些数据库实现用术语“数据库”代替“目录”】,每个目录可以包含模式(schema,诸如关系和视图的SQL对象都包含在模式中。

每个用户都有一个默认的目录和模式,当一个用户连接到数据库系统时,将为该连接设置好默认的目录和模式。

为唯一标识出一个关系,必须使用一个包含三部分的名字:e.g. catalog5.univ_schema.course;

当名字的目录部分被认为是连接的默认目录时可省略目录部分。e.g. 如果catlog5是默认目录,可用univ_schema.course唯一标识该关系;

当关系存在于特定用户的默认模式中时可也省略模式部分。e.g. 如果catalog是默认目录并且univ_schema是默认模式,可用course唯一标识该关系;如果用户想访问存在于默认模式以外的模式中的关系,则必须指定模式的名字。

默认目录和模式是为每个连接建立的SQL环境(SQL environment)的一部分,环境还包括用户标识(a.k.a. 授权标识符)。所有通常的SQL语句都在一个模式的环境中运行。

可用create schema和drop schema语句创建和删除模式。

在大多数数据库系统中,模式随着用户账户的创建而自动创建在默认目录或创建用户账户时指定的目录中,模式名被置为用户账户名,新创建的模式成为用户账户的默认模式。

 

授权

对数据的授权包括:授权读取数据、授权插入新数据、授权更新数据、授权删除数据。对数据库模式的授权包括创建或删除关系、增加或删除关系的属性、增加或删除索引等。每种类型的授权都称为一个权限(privilege)。通过SQL授权机制,可按照在数据库中不同数据值上数据库用户所允许的访问类型对他们进行区分。可在数据库的某些特定部分上授权给用户这些权限的一个组合、所有权限或完全不授权。

SQL授权机制可对整个关系或一个关系的指定属性授权,但不允许对一个关系的指定元组授权。

用户名public指系统所有当前用户和将来的用户。

当用户提交查询或更新时,SQL执行先检查用户的此查询或更新是否经过授权,如果没有经过授权则拒绝执行。

默认情况下,被授予权限的用户/角色无权把此权限授予给其他用户/角色。SQL允许用授予权限来指定权限的接受者可以进一步把权限授予其他用户或撤销此前授出的权限。

最大的授权形式是被授予数据库管理员,数据库管理员可授权新用户、重构数据库等。

1. 权限的授予与回收

SQL标准包括select、insert、update和delete权限。所有权限(all privileges)用作所有允许权限的简写,一个创建了新关系的用户将被自动授予该关系上的所有权限。

Grant语句用于授予权限。基本形式:

grant <权限列表>
on <关系名或视图名>
to <用户/角色列表>;

e.g. 授予用户Amit和Satoshi在department关系上的select权限

grant select on department to Amit, Satoshi;

e.g. 授予用户Amit和Satoshi在department关系的budget属性上的更新权限

grant update (budget) on department to Amit, Satoshi;

e.g. 允许用户Mariano在创建关系时声明外码,该关系能够参照department关系的码dept_name

grant reference (dept_name) on department to Mariano;

Revoke语句用于收回权限。基本形式:

revoke <权限列表>
on <关系名或视图名>
from <用户/角色列表>;

e.g. 收回先前授予用户Amit和Satoshi在department关系上的权限

revoke select on department from Amit, Satoshi;
revoke update (budget) on department from Amit, Satoshi;

2. 角色

角色有助于根据用户在组织机构中所扮演的角色,把一组权限分配给用户。

在数据库中建立一个角色集,可以给角色授予权限,每个数据库用户被授予一组他有权扮演的角色(可能为空)。E.g. 指明教师角色应该被授予的权限,单独标示出哪些数据库用户是教师,系统从而确定其权限。当雇佣新教师并被标志时不需要重新单独授权。

相比建立共同用户标识的做法,使用角色需要用户用自己的用户标识来连接数据库,能够鉴别到底哪位用户执行了数据库更新,避免安全隐患。

e.g. 创建角色instructor

create role instructor;

e.g. 给角色instructor授权

grant select on takes
to instructor;

角色可以授权给用户,也可以授权给其他角色。E.g.

grant dean to Amit;
create role dean;
grant instructor to dean;
grant dean to Satoshi;

一个用户/角色的权限包括a. 所有直接授予该用户/角色的权限; b. 所有授予该用户/角色所拥有角色的权限

3. 权限的转移和收回

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

e.g. 授予Amit在department上的select权限,并允许Amit将该权限授予其他用户

grant select on department to Amit with grant option;

一个对象(关系/视图/角色)的创建者拥有该对象上的所有权限,包括给其他用户授权的权限。

授权图(authorization graph):指定权限从一个用户到另一个用户的传递的表示。

用户具有权限的充分必要条件:当且仅当存在从授权图的根(代表数据库管理员的顶点)到代表该用户顶点的路径。

级联收回:从一个用户/角色那里收回权限可能导致其他用户/角色也失去该权限。当数据库管理员决定收回某用户的授权时,如果使授权图中不再存在从根到另一用户(如从某用户获得过授权的用户)的路径,则另一用户的权限也该被收回。

在大多数数据库系统中级联是默认行为,可在revoke语句中申明restrict防止级联收回。此情况下如果存在任何级联收回,系统将返回一个错误,并不执行收权动作。E.g.

revoke select on department from Amit, Satoshi restrict.
--如果需要级联收回,可用关键字cascade替换restrict。(cascade为默认行为)

revoke语句可仅收回grant option。

e.g. 仅仅收回grant option而不真正收回select权限

revoke grant option for select on department from Amit;
/*一些数据库不支持此语法,采用“收回权限本身再不带grant option重新授权”的方式。*/

SQL允许权限由角色授予。可用set role role_name设置与会话所关联的当前角色(指定角色必须已经授予给用户,否则执行失败)。默认情况下一个会话所关联的当前角色为空。

如果要在授权时将授权人设置为一个会话所关联的当前角色(并且当前角色不为空),可在授权语句后加granted by current_role子句。

e.g. 授权人Satoshi用granted by current_role子句将角色instructor(或其他权限)授权给Amit,当前角色被设置为dean;

当从授权Satoshi处收回角色/权限(包括角色dean)时,不会导致收回Satoshi以角色dean作为授权曾授予的权限。(Satoshi权限被收回后,Amit仍能保持instructor角色)。

以上是关于DBMS-SQL:连接表达式视图事务完整性约束数据类型与模式授权的主要内容,如果未能解决你的问题,请参考以下文章

DBMS-SQL聚集函数嵌套子查询数据库修改

数据库概念与实现

连接池+事务

数据库系统概念:事务完整性约束

Oracle-视图,约束

JavaLearn#(17)MySQL基础知识DML及DDL语句外键及非外键约束外键策略DQL语句(单表多表)连接查询子查询索引事务视图存储过程用户权限及角色管理