数据库系统原理复习提纲

数据库系统原理复习提纲

参考文献:A First Course in Database Systems | 3rd Edition
Authors:Jennifer Widom,Jeffrey D Ullman

视频教程:https://www.bilibili.com/video/BV13J411J7Vu
中国人民大学信息学院-数据库系统概论完整版(基础篇+高级篇+新技术篇)

期末复习用,时间有限,难免有疏漏,还望各位批评指正,主要是写一些对书里内容的理解。——©️Sylvan Ding ❤️


关系数据模型

关系模型的组成

  1. 关系数据结构

    关系模型中的数据在逻辑上是一张二维表,由行和列组成(二维表、行列)

  2. 关系操作

    插入、删除、更新、查询(增删改查)

  3. 关系完整性约束

    实体完整性约束:属性A是关系R的主属性,则A不能取空值(主属性不能为空)

    参照完整性约束:F是R的外码,和S中的主键K相对应,F必须为空或等于K中某个值(下文必须在上文出现)

    用户定义的完整性:对某一应用所涉及的数据必须满足语意要求(根据实际自定义的约束)

定义关系模式(表创建)

数据类型
类型说明
char(n)定长n个字符,不足位补空格,效率最优
varchar(n)变长,最多n个字符,实际存储长度+1(存字符长度),空间最优
text变长,非unicode,存储量很大
nchar(n)定长unicode
nvarchar(n)变长unicode
ntext变长unicode
binary/varbinary定长/变长 二进制
image变长二进制,用于保存图像
bigint/int/smallint/tinyint整型
bit模拟BOOLEAN
decimal(n,d)n位有效位,d位小数位
real/float浮点
datetime“YYYY-MM-DD HH:MM:SS”
约束条件
create table <tb_name>(
  <attr_1> char(1) primary key, -- 主键约束
  <attr_2> int references tb_2(att_name) -- 外键约束
    on update cascade -- 级联更新
    on delete set null, -- 置空值原则(默认“缺省原则”,拒绝更新)
  <attr_3> datetime unique not null default date '1900-12-12', -- 唯一、非空、默认值约束
  <attr_4> real [constraint c_name] check(attr_4<>10), -- 基于属性的check约束,[约束命名],不等于用<>
  -- 也可以在末尾声明约束
  constraint c_name primary key(attr_1),
  foreign key(attr_2) references tb_2(att_name),
  unique(attr_3),
  check(attr_1 in ('F','M'))
);
-- 删除约束
alter table <tb_name> drop constraint <c_name>;
-- 添加约束,<type_of_constraint>=[primary key|foreign key|unique...]
alter table <tb_name> add constraint <c_name> <type_of_constraint>(<attr>)...;

修改/删除关系模式(表修改/删除)

-- 表删除
drop table <t_name>
-- 添加/删除列
alter table <t_name> [add|drop] <column_name>;
-- 添加/删除约束
alter table <t_name> [add|drop] constraint <c_name>;
-- 修改某列类型
alter table <t_name> alter column <col_name> <type>;

代数查询语言

关系表达式

投影: π A 1 , A 2 , ⋯ \pi _{A_1,A_2,\cdots} πA1,A2,

选择: σ C \sigma _C σC

自然连接:公共属性相同的行保留,去掉重复列

θ \theta θ 连接:不去重复列(比如用 R.A, S.A 表示),根据条件保留行

重命名: ρ s ( A 1 , A 2 , ⋯   ) ( R ) \rho _s (A_1,A_2,\cdots) (R) ρs(A1,A2,)(R) 将R重命名为S,其属性重命名为A1, A2…,也可省略S或A1, A2…

赋值:R(a1,a2) := <表达式>

关系表达式树

表达式->表达式树:表达式由外及里,表达式树自上到下

表达式树->表达式:表达式树自下到上,表达式由里及外

查询优化

顺序:选择、投影、连接

注意:先画连接关系(简单理解为找输入-输出-连接),确定连接个数,是对直接连接再选择和投影的优化。在表达式中,可以用交、并、差运算,若题目中出现“没有”字样,则用差运算。

Students(Sno,Sname,Ssex,Sage,Sdept)
Courses(Cno, Cname, Cpno,Ccredit)
SC(Sno,Cno,Grade)

Q: 查询选修了以2号课为先修课的课程的学生的名字?

输入条件:2号课 Courses.Cpno=‘2’
输出:学生的名字 Students.Sname
连接:Courses.Cno -> SC.Cno, SC.Sno -> Students.Sno

在连接前,先做选择和投影即可。

关系数据库设计理论

求属性集合的闭包

  1. 输入:A={A1,A2,…}, FD集合S
  2. A+ = {A} 并上那些可以由 A+ 推导出来的属性

求某关系的所有候选码/所有非平凡函数依赖

  1. 构造关系的所有属性的子集
  2. 闭包算法找出这些子集的所有非平凡依赖
  3. 非平凡依赖的右边有全部属性的,是候选码

求FD的最小基本集

  1. FD右边分解为单一属性

  2. 去除能由其他FD推出的FD(整体最小化)

  3. 去除FD左边多余的属性(局部最小化)

    两种方法判定是否多余:(计算闭包是不用像2那样除去FD)

    1. 求左边属性的闭包,闭包是否包含右边所有属性,若包含则左边其余属性多余

    2. 去除左边某个属性,观察新FD集和原FD集是否依然等价

      (去除左边那个属性后的新FD集是否能推出原FD集),若等价则该属性多余

  4. 重复2-3,直到不能再化简为止

投影依赖的计算

  1. 写出投影的所有属性子集的闭包,得到所有非平凡函数依赖FD集
  2. 最小化FD集,得到投影的依赖集

BCNF

定义

当且仅当所有非平凡FD的左边均包含任意一个候选码,或者说所有非平凡FD都是超码。

满足BCNF,则一定满足NF-1、2、3,即不存在非主属性对主属性的部分依赖、传递依赖,主属性间不存在部分依赖、传递依赖。

注意:任何二元关系都满足BCNF。

分解算法

假定输入的FD集已经为最简,否则需要最小化FD集。

  1. 根据定义找BCNF违例

    先确定所有候选码,再找违例

  2. 对违例进行分解

    如违例 X->Y,X 中不包含候选码,那么求 X+,由X+组成一个分组,另一个分组由X和不在X+的其他属性组成,也就是说X要在两个分组中均存在,以此作为分解后二者连接的依据。求X+并组成一个分组也就是希望这个分组尽量满足BCNF,分解到最后一定能满足BCNF

  3. 最小化两分组的FD集,求投影FD集,递归进行1-2分解,直到所有分组满足BCNF

R(ABCD), {AB-C,C-D,D-A}

A+={A},B+={B},C+={C,D,A},D+={D,A}
{AB}+={ABCD},{AC}+={A,C,D},{AD}+={A,D}
{BC}+={B,C,D,A},{BD}+={B,D,A,C},{CD}+={C,D,A}
{ABC}+=-,{ABD}+=-,{ACD}+={C,D,A},{BCD}+=-
{ABCD}不必考虑,肯定是平凡依赖

注意:{ABC}+、{ABD}+、{BCD}+可由{AB}+={ABCD}…等直接得出,无需再计算
而且,{ABC}+、{ABD}+、{BCD}+是超码,不算入候选码中,所以结果用-表示
A+={A},B+={B},{AD}+={A,D},{ACD}+={C,D,A}是平凡依赖,不考虑

候选码:AB,BC,BD
除去上述超码、平凡依赖、候选码后,剩余的:
C+={C,D,A},D+={D,A}
{AC}+={A,C,D},{CD}+={C,D,A}

此时,BCNF违例为
C-D,C-A,D-A,AC-D,CD-A

选择一个违例进行分解,应当经可能向右边添加属性,以减少工作量
选择C-DA进行分解,{C}+={ACD}
则分解为R1{ACD},R2{BC}

计算R1投影的函数依赖
A+={A},C+={CDA},D+={DA}
{AC}+=-,{AD}+={AD},{CD}+=-
候选码:C
BCNF违例:D-A
{D}+={DA}
分解为R11{AD},R12{CD}

又知,二元关系肯定满足BCNF,所以分解结果{BC},{AD},{CD}

3NF

定义

BCNF放宽要求,要么FD左边是超码,要么FD右边全是主属性。

分解算法
  1. 求最小基本集
  2. 对最小基本集中每一个FD X->Y ,将 X U Y 作为一个分组进行分解
  3. 修正(删和添):2步骤分解时,没必要得到子集,所以将子集去除;
    若没有一个分组包括原关系的候选键,则添加一个分组,分组为任一候选键,一次确保无损连接性

注意:该分解算法具有无损连接和依赖保持性质。

R(ABCDE), {AB-C,C-B,A-D}

最小化基本集:
{A}+={AD},{B}+={B},所以AB不多余,也没有FD是多余的,所以已经最小化

那么,{ABC},{BC},{AD},其中{BC}是{ABC}的子集,所以删除

计算候选键:
AB+=ABCD,AC+=ABCD, 显然,ABE和ACE是候选键

添加候选键,则分解结果为 {ABC}{AD},{ABE}或{ACE}

高级数据库模型

ER模型建立

注意:一对多联系,一方那段连线要画箭头。

多路联系:箭头指向的那个实体集,由其他实体集函数决定

多路联系转二元联系:“联系中心转实体集,再添加多个联系”

isa联系:父类的主键一定在子类中出现

参照完整性约束:A–)B,说明A参照B,A一定要在B文中出现,而且是一对一或者多对一(一方带箭头)

弱实体集:依赖一个实体集而存在,本质上就是参照完整性约束,也就是说A的主键一定在B的主键中出现过,然后再为弱实体集设置一个主键,即弱实体集的主键由对应“强”实体集的主键和弱实体集的主键共同构成(对比外键的概念即可)

注意:isa联系和弱实体集的区别是,弱实体集本质上是参照完整性约束,需要增加属于弱实体集的主键部分,而isa联系则不能改变父类的主键,子类都要继承父类主键,可以添加其他属性,但属性不能成为子类键的一部分。

ER模型转关系模式

  1. 联系转关系

    联系的属性是和该联系直接相连的实体的键。

    多对一联系,联系的键为多方实体集的键;

    多对多联系,联系的键为联系的所有属性;

    一对一联系,联系的键为任意一方实体集的键。

    (和“函数决定”理论相关)

  2. 关系组合

    上述联系转关系不一定是最优的,比如“多对一”、“一对一”关系都可以合并

    实体集转化为另一个实体集的属性,要求改实体集是全码,否则会冗余

  3. 处理弱实体集

    支持联系无需转化为关系,因为已经“关系组合”到弱实体集的关系属性中

  4. 子类结构处理

    1. ER方法:每个实体集都建一个关系,子类包含父类的主键(每个实体都有自己的关系)
    2. 面向对象:枚举可能出现的子树(包含根),为每个子树单独建一个关系,这个关系模式含有子树中所有实体的所有属性(找子树)
    3. 空值法:只创建一个关系模式,包含所有属性,空项用空值NULL填充(所有属性塞一块)

    对比:空值法占用空间最多,ER法有信息重复,面向对象法占空间最少,且无重复。

ER模型设计原则

  1. 忠实性:设计要反映现实情况

    Stars和Movies之间定义联系Star-in,应该是多对多联系;

    不能把属性“气缸数”与stars联系,却可以把它作为汽车的属性。

  2. 避免冗余:一件事在模型中只出现一次

    在电影和电影公司之间用了联系Owns。又把电影公司的名称studioName选作电影实体集的一个属性。

    两次表示“所属的制片公司”这一同样的事实

  3. 简单性考虑:模型元素越少越好

  4. 选择正确联系:舍弃冗余、无关的联系

  5. 选择正确元素种类:用属性还是用实体集?用实体集还是用联系?属性<–>实体<–>联系

    属性代替实体集E的条件:

    1. E是一方实体集
    2. E的键是全码
    3. 没有联系包含E多次

记忆:装b剪连元(一个装b的人剪断了连在一起的元宵)= (装)忠实性(b)避免冗余(剪)简单性考虑(连)联系(元)元素种类

ODL模型

class Movie {
  attribute string title;
  attribute integer year;
  attribute enum Genres{drama,comedy...} genre; // enum声明枚举型属性genre,Genres为枚举名称
  // relationship声明名为stars的联系
  // Set<Star>为一对多联系,表示一部电影有多个影星
  // inverse Star::starredIn 说明stars联系为Star类中starredIn联系的反向联系
  relationship Set<Star> stars
    inverse Star::starredIn; 
  relation Studio ownedBy
    inverse Studio::owns;
};

class Star {
  attribute string name;
  attribute Struct Addr
    {string street, string city} addr; // Struct声明结构型属性addr
  relationship Set<Movie> inverse Movie::stars;
};

class Studio {
  attribute string name;
  attribute Star::Addr address; // 引用Star域的Addr结构
  relationship Set<Movie> owns
    inverse Movie::ownedBy;
};

注意:

类中元素有两种:attribute和relationship,其后接类型和元素名

[attribute|relationship] <type> <ele_name>;

比如 relationship Set<Movie> owns inverse Movie::ownedBy 表示Studio中,有一组Movie,和Movie的ownedBy这个Studio类互为反向关系。

class CMM (key(k1,k2)) extends M1:M2 {
  relationship Array<...> rs_name;
  // CMM继承了M1和M2的所有元素,并添加了自己的属性 re_name
  // 用 key(k1,k2) 声明了CMM的键(K1,K2)
}

代数和逻辑查询语言

包上的关系操作

注意:包可以有重复

  1. R 交 S,元组t出现 min(m,n) 次
  2. R - S,元组t出现 max(0,m-n) 次
  3. 包连接:先笛卡尔积,再按条件筛选

扩展操作符

消重: δ \delta δ

聚集:MIN、MAX、AVG、COUNT、SUM

分组聚集: γ A 1 , A 2 , a g g ( A 3 ) → a g g 3 , a g g ( A 4 ) → a g g 4 ( R ) \gamma _{A1,A2,agg(A3)\to agg3,agg(A4)\to agg4} (R) γA1,A2,agg(A3)agg3,agg(A4)agg4(R) ,表示将R的A1和A2作为分组属性,在A3和A4属性上做agg聚合,聚合结果投影到agg3和agg4这两列上, x → y x\to y xy 表示将x重命名为y

投影扩展: π A − B → C ( R ) \pi _{A-B \to C}(R) πABC(R) 将R上A-B的结果重命名为C

排序: τ B , C \tau _{B,C} τB,C ,从小到大排序,按B,C属性先后

外连:悬浮元组指的是不能和另一张表配对(配对指的是符合条件,比如自然连接需要符合名相同的列值相等的条件,theta连接需要符合特定条件)的本表元组。解题方法:先正常内连(笛卡尔积+筛选),最后再加入各表的悬浮元组。左连和右连表示只保留左/右悬浮元组。!注意:如果是自然连接,要去除重复列,如果是theta连接,则不去除重复列,相同列名加前缀保留!

数据库语言

SQL语法

字符串匹配通配符:%任意字符串(n>=0),_单个字母,[ ] 字符选择,[^] 字符选择的否定,两个’‘表示一个’

排序:ORDER BY A1,A2 [DESC],默认升序,DESC降序

From:FROM (table1) new_name 在table名后为table命新名

交、并、差:INTERSECT、UNION、EXCEPT. 例如 (SELECT ...) INTERSECT [ALL] (SELECT ...), 注意:三者默认消重,若不希望消重,则应加[ALL]

比较运算符:用 ANY/ALL 对WHERE选择的结果进行聚合

theta连接:SELECT...FROM ...JOIN...ON... ON 后为连接条件

自然连接:NATURE [FULL/LEFT/RIGHT] [OUTER] JOIN [ON]...

消重:SELECT DISTINCT ...

COUNT查不重复:SELECT COUNT(DISTINCT ...) FROM ...

查询顺序:select > from > where > group by > having > order by

插入查询值:insert into <table_name> (select...)

修改:update ...set ...=..., ...=... where ...

字符串拼接:‘A’||‘B’

事务

保证事务正确执行的ACID性质
  • A(Atomicity)原子性

    事务不可分割,事务中的操作要么都发生,要么都不发生(不可分)

  • C(Consistency)一致性

    事务前后数据的完整性必须一致

  • I(Isolation)隔离性

    并发事务间相互隔离,不相互干扰

  • D(Duration)持久性

    一旦事务被提交,对数据的改变是永久性的

事务的隔离级别
脏读不可重复读幻读
读未提交 read uncommitted
读提交 read committed
可重复读 repeatable read
可串行化 serializable

约束与触发器

断言

本质上,断言就是对数据库的全局的check约束。任何引起断言为假的数据库更新都将被阻止,且断言的条件<condition>中不能有任何属性,可以用自查询和EXISTS做判断。断言的条件可能暂时为假(比如在事件的执行过程中),在事件结束时再检查断言条件。

create assertion <ass_name> check (<condition>); -- 创建断言
drop assertion <ass_name>; -- 删除断言

check约束和断言的对比

基于属性的check约束:在某属性上更新时检查,对子查询没有约束效力;

基于表的check约束:在某表的任何一个属性更新时检查,对子查询没有约束效力;

断言:对引起断言条件变化的任何可能的更新检查,对子查询有约束效力,是基于数据库的约束。

触发器

create trigger <tg_name> -- 创建触发器
[after|before|instead of] [options] on <tb_name> -- options是增删改查,其中update可以加of,表示对某属性的更新
referencing -- 声明新旧元组/表
  old [row|table] as <old_name> -- 删除操纵
  new [row|table] as <new_name> -- 插入操作
  -- 二者均存在:更新操作
for each [row|statement] -- 定义行/语句级触发器
-- 行级触发器每行触发一次,而语句级触发器每条语句出发一次
when(<condition>) -- 触发条件(可以没有),比如可以是 old.val<new.val
begin -- (执行语句,多条则用begin和end包括)
...; 
-- 比如 update <tb_name> 
-- set <col_name>=<new_name>.<col_name> 
-- where <col_name>=<old_name>.<col_name>;
end;

视图与索引

视图创建:create view <view_name>(newA1,newA2,...) as ... ,newA1、newA2给属性重命名

视图删除:drop view...

视图更新

只能更新 行列子集视图:由单表导出的,含有其某些行列的视图。必须要含有所有主键,因为主键不能为空。where子句不能查询自己。可以在视图上定义 instead of 触发器从而解决一些更新异常。

索引

create index <index_name> on <tb_name>(<att1>,<att2>...) -- 创建索引
drop index <index_name> -- 删除索引
计算最佳索引

考虑上述员工表Staff上的索引,假定:Staff(sid,pay_rank,service_year)
员工编号sid是主键;(给定一个sid值,只可能查出1条元组,只需调入1个磁盘页)
每个索引需占用2个磁盘页
存储关系Staff的磁盘页为100,如果要检查整个关系,则代价为100;
关系按照薪酬级别pay_rank聚合,这样只需一次磁盘访问操作就可以找到给定薪酬级别的员工;
每个service_year平均有5名员工,且平均分散在5个磁盘页上;
仅需一次磁盘访问就可读取用于容纳新元组的磁盘页。在该关系上有如下形式的查询
Q1: SELECT * FROM Staff WHERE sid = s;
Q2: SELECT * FROM Staff WHERE pay_rank=p;
Q3: SELECT * FROM Staff WHERE service_year=y;
I: 插入新元组到表staff中。

计算上面4种操作在无索引、sid索引、pay_rank索引、service_year索引和全索引5种情况下的平均操作代价,填入表1中。

无索引的情况下,任何Q查询都需要访问所有100个磁盘页,遍历所有数据页。

有索引时,先读入索引,消耗一次访存(本题是两次,因为每个索引需占用2个磁盘页),再根据索引直接读对应的磁盘页(一次),索引Q1和Q2在有相应索引时是3=2+1。

而Q3,每个service_year平均有5名员工,且平均分散在5个磁盘页上,所以要读入5个磁盘页,7=2+5。

无索引插入,读一页,写回一页,两次访存。有索引插入,读+写回索引2次,每个索引2页,4次,加上数据读和写回2次,共6次。全索引插入,读+写回索引2次,每个索引2页,3个索引,12次,14=12+2.

无索引sid索引pay_rank 索引service_year索引全索引
Q110031001003
Q210010031003
Q310010010077
I266614

服务器环境下的SQL

嵌入宿主语言的SQL

// **游标更新**
// 查看MovieExec的每个元组,决定删除还是将其净资产翻倍
#define NO_MORE_TUPLE !(strcmp(SQLSTATE,"02000")) // 宏定义,游标取完的标识

void changeWorth(){
  // 共享变量声明
  EXEC SQL BEGIN DECLARE SECTION;
    int certNo,worth; 
    char SQLSTATE[6]; // SQLSTATE 返回SQL状态,5个字节
  EXEC SQL END DECLARE SECTION;
  
  EXEC SQL DECLARE execCursor CURSOR FOR <query>; 
  // 声明游标:declare <cursor_name> cursor for ...查询语句,也可以直接是一个表名
  EXEC SQL OPEN execCursor; // 开启游标 open <cursor_name>
  // 进入循环
  while(1){
    // 取数据 fetch from <cursor_name> into [:share_variables]...;
    EXEC SQL FETCH FROM execCursor INTO :certNo, :worth;
    // SQL语句中使用共享变量要加:
    if(NO_MORE_TUPLE) break; // 跳出条件,fetch查完了
    if(worth<10000)
      EXEC SQL DELETE FROM MovieExec 
        WHERE CURRENT OF CURSOR; // 使用游标,where只能用CURRENT OF CURSOR
    else
      EXEC SQL UPDATE MovieExec SET netWorth=2*netWorth WHERE CURRENT OF CURSOR;
  }
  // 关游标
  EXEC SQL CLOSE execCursor;
}

存储过程

计算某电影公司制作的影片长度的平均值和方差

-- **方差=\sum x_i^2/n-\bar{x}^2
-- loop循环结构,需要写退出条件 delcare NOT_FOUND condition for sqlstate '02000'
create procedure MeanVar( -- 存储过程创建
  in s char(15),
  out mean real,
  out variance real
  -- 声明参数,输入/输出,[in|out|inout] <param_name> <type>
  -- SQL中,变量名在前,类型在后
)
-- 局部变量声明
declare NOT_FOUND condition for sqlstate '02000'; -- 循环退出条件声明
declare MV cursor for select lenth from movies where studioName=s; -- 游标声明
declare MC integer; declare newlenth integer;
-- 注意:在存储过程声明中创建的输出参数不需要重复声明
-- 程序体
begin
  -- 存储过程中赋值操作用set
  set mean=0.0;
  set variance=0.0;
  set MC=0;
  set newlenth=0;
  -- 开游标
  open MV;
  movieloop:loop
  -- loop循环,<loop_name>:loop ~~~ end loop;
    -- 取数据
    fetch from MV into newlenth;
    -- 判退出
    if NOT_FOUND then leave movieloop end if;
    -- 数据处理
    set MC=MC+1;
    set mean=mean+newlenth;
    set variance=variance+newlenth*newlenth;
  end loop;
  -- 关闭游标
  close MV;
  -- 输出
  set mean = mean/MC;
  set variance = variance/MC - mean*mean;
end;
-- for 循环结构,无需写退出条件
-- for <loop name> as <cursor name> cursor for <query>;
-- do <statement list>
-- end for;
-- 1. 创建存储过程
create procedure (
  -- 2. 填写参数:输入输出
  in s char(15),
  out mean real,
  out variance real
)
-- 3. 局部变量声明,因为是for循环,所以不用声明退出条件变量
declare MC int;

-- 开始语句,记得加begin和end
begin
  -- 4. 变量赋初值(包括输出变量)
  set MC = 0;
  set mean = 0.0;
  set variance = 0.0;
  -- 5. 创建for循环,在for循环中创建游标,注意for循环的尾部有个 ;
  for movieLoop as MV cursor for 
    select lenth from movies where studioName=s;
  -- 6. 定义数据处理
  do
    -- 注意:for循环不用取数据了,可直接使用上述select的属性
    set mean = mean + lenth;
    set variance = variance + lenth*lenth;
    set MC = MC + 1;
  end for;
  set mean = mean/MC;
  set variance = variance/MC + mean*mean;
end;

记忆(一般模式):

-- 1. 创建存储过程
create procedure(
  -- 2. 声明输入输出参数
)
-- 3. declare 声明局部变量
declare ...;
-- 4. 如果是loop,那么要声明退出条件变量
declare ... condition for sqlstate '02000';

-- 5. 写操作体
begin
-- 6. 初始化变量和参数
set ... = ...;
-- 7. 开游标(loop循环)
-- 8. 写loop循环
  <loop_name>:loop
    -- 8.1 取数据
    fetch from <cursor_name> into ...;
    -- 8.2 判退出
    if NOT_FOUND then leave <loop_name> end if;
    -- 8.3 数据操作
    ...;
  end loop;
  -- 8.4 关游标
-- 9. 写for循环
  for <loop_name> as <cursor_name> cursor for <query>;
  -- 9.1 写循环体
  do
  ...;
  end for;
-- 10. 后续操作
end;

关系数据库安全机制

授权和销权

<权限>:ALL PRIVILEGES 表示所有权限

<数据库元素>:除了表和视图以外,其余数据库元素应当加上 <类型>,即<类型><元素名称>

-- 授权
grant <权限> on <数据库元素> to <用户1>,<用户2>... [with grant option];
-- 销权
revoke <权限> on <数据库元素> from <用户1>,<用户2>... [cascade];

习题10.1.1解答 Chegg

In SQL there are nine types of privileges, those are:

  • SELECT
  • INSERT
  • DELETE
  • UPDATE
  • REFERENCES

The statement Select-From-Where always requires the SELECT privileges on every table on which it queried or accessed.

On other hand REFERENCES privileges on a relation , which it refers to that relation in an integrity constraint.

Not only reference to relation but also it will consider some other form as referential integrity constraint or assertions or tuple based checks etc.

授权图

注意事项:

  1. 两颗心心 ** 表示“属主”
  2. 一颗心心 * 表示有权分发权限
  3. 用cascade销权,授权图去掉某边后,“属主”达不到的点均要删除
  4. 点内容自上而下分别是:用户名 > 权限名 > “权限表示”(心心)
  5. 执行语句带或不带授权选项是不同的权限,必须用两个不同的节点表示
  6. 若某用户的一个权限比另一个权限更通用,也要用两个不同的节点表示

——©️Sylvan Ding ❤️

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值