【数据库理论】数据库的安全和保护

本系列为《数据库系统原理与应用(刘先锋等著)》的读书笔记。

一,安全与保护概述

1)数据安全性控制:防止未经授权的用户和存取数据库中的数据,避免数据的泄露,更改或破坏;

2)数据完整性控制:保证数据库中数据及语义的正确性和有效性,防止任何对数据库造成错误的操作;

3)数据库的并发控制:在多用户同时对一个个数据进行操作时,系统应能够加以控制,防止破坏数据库中的数据;

4)数据库的恢复:在数据库遭到破坏或者数据不正确时,系统有能力把数据库恢复到正确的状态。

二,数据库的安全性

1,数据库安全性控制

1)用户标识与鉴别:系统提供的最外层的安全保护措施,其方法是由系统提供一定的方式让用户标识自己的名字或身份。

2)存取控制

(1)定义用户权限,并将用户权限等存储在数据字典中。用户权限是指不同等用户对不同对数据对象允许执行对操作权限,这些定义经过编译后存放在数据字典中,这些定义称为安全规则授权规则
(2)合法权限检查。用户权限定义和合法权限检查机制组成类DBMS的安全子系统。

3)试图机制:数据安全性,逻辑数据独立性和操作简便性。

4)审计审计追踪是一个对数据库进行更新对日志,还包括一些其他信息,如哪个用户执行了更新和什么时候执行的更新等。

5)数据加密:防止数据库中数据在存储和传输中失密的有效手段。

2,SQL Server的安全性措施

1)SQL Server安全控制概述

(1)操作系统安全验证(网络层):通过设置安全模式来实现。
(2)SQL Server安全验证(服务器):通过SQL Server服务器登录名管理来实现。
(3)SQL Server数据库安全验证:通过SQL Server数据库用户管理来实现。
(4)SQL Server数据库对象安全验证(处理权限):通过权限管理来实现。

2)SQL Server的安全认证模式

(1)身份验证阶段:Windows身份验证,混合模式验证。
(2)权限认证阶段
(3)设置身份验证

3)登录名和用户管理

1
2
3
4
USE <DATABASE NAME>
go

CREATE USER <new user_name> FOR LOGIN <login name>;

4)权限管理

(1)权限分类语句权限对象权限隐含权限
(2)角色分类:在SQL Server中,组是通过角色来实现的。角色分为服务器角色数据库角色(预定义的数据库角色,用户自定义数据库角色和应用程序角色)。

三,数据库的完整性

1,数据库的完整性定义数据库的完整性是指数据的正确性(Correctness),有效性(Validity)和相容性(Consistency)。正确性是指数据的合法性;有效性是指数据是否属于所定义的有效范围;相容性是指表示同一事实的两个数据应一致,不一致就是不相容。

完整性检查:在DBMS中,检查数据库中的数据是否满足语义规定的条件。

2,完整性约束条件

1)完整性约束作用的对象可以是元组关系。其中:列的约束主要是列的类型,取值范围,精度,排序等约束条件;元组的约束是元组中各个字段间的联系约束;关系的约束是若干元组间,关系集合上及关系之间的联系约束。

2)静态约束:指数据库在每个确定状态时的数据对象所应满足的约束条件,是反映数据库状态合理性的约束。

(1)静态列级约束:对一个列的取值范围的说明,即对数据类型的约束(数据的类型,长度,单位,精度等),对数据格式的约束,对取值范围或者取值集合的约束,对空值的约束,其他约束。
(2)静态元组约束:规定元组的各个列之间的约束关系。
(3)静态关系约束:实体完整性约束,参照完整性约束,函数依赖约束,统计约束。

3)动态约束:指数据库从一种状态转变为另一种状态时,新旧值之间所应满足的约束条件,是反映数据库状态变迁的约束。

(1)动态列级约束:修改列定义或者列值时应满足的约束条件。
(2)动态元组约束:修改元组中各个字段间需要满足某种约束条件。
(3)动态关系约束:加在关系变化前后状态上的限制条件,如事务一致性,原子性等。

3,完整性控制

1)定义功能:提供定义完整性约束条件的机制。

2)检查功能:检查用户发出的操作请求是否违背列完整性约束条件。

3)如果发现用户的操作请求使数据违背了完整性约束条件,则采取恰当的操作。

4,SQL Server的完整性实现

1)声明型数据完整性约束:在 create tablealter table 定义中使用约束限制表中的值。

2)过程型数据完整性约束:由缺省,规则和触发器实现,由视图和存储过程支持。

(1)约束:是SQL Server提供的自动保持数据库完整性的一种方法。分为:
i)空值约束

1
[CONSTRAINT constraint_name] [NULL/NOT NULL]

ii)主键约束

1
2
3
4
-- 列级
[CONSTRAINT constraint_name] PRIMARY KEY
-- 表级
[CONSTRAINT constraint_name] PRIMARY KEY(<column_name>[{,<column_name>}])

iii)唯一约束

1
2
3
4
-- 列级
[CONSTRAINT constraint_name] UNIQUE
-- 表级
[CONSTRAINT constraint_name] UNIQUE(<column_name>[{,<column_name>}])

  • 唯一约束主键约束的区别:

    (1)在一个基本表中,只能定义在一个主键约束,但可以定义多个唯一约束;
    (2)两者都为指定但列建立唯一索引,但主键约束限制更为严格,不但不允许有重复值,而且也不允许由空值;
    (3)唯一约束与主键约束产生但约束可以是聚集索引,也可以是非聚集索引,在缺省情况下,唯一约束产生非聚集索引,主键约束产生聚集索引;
    (4)不能同时为同一列或者一组列既定义唯一约束,又定义主键约束。

iv)外键约束和参照约束

1
[CONSTRAINT constraint_name] [FOREIGN KEY] REFERENCES ref_table (ref_column[{,<trf_column>}])

v)缺省值约束

1
[CONSTRAINT constraint_name] DEFAULT constraint_expression

vi)检查约束

1
[CONSTRAINT constraint_name] CHECK(logical_expression)

  • 例如:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    use master
    go

    create table Titles
    (
    title_id varchar(6) constraint pk_title_id primary key,
    title varchar(80) not null constraint uniq_title unique,
    [type] char(12) not null constraint def_type default 'UNDECIDED',
    pub_id char(4),
    price money constraint chk_price check(price between 5 and 100),
    ytd_sales int,
    pub_date datetime not null constraint def_pub_date default getdate()
    )

(2)规则:当向表当某列(或使用与该规则绑定的用户定义数据类型的所有列)插入列或更新数据时,它指定限制输入新值的取值范围。

1
2
3
4
5
6
7
8
use master
go

create rule rule_price as @price >= 5 and @price <= 100
go

exec sp_bindrule 'rule_price', 'Titles.price'
go

(3)缺省:它指定在向数据库中的表插入数据时,如果用户没有明确给出某列的值,SQL Server自动为该列(使用与该缺省绑定的用户定义数据类型的所有列)输入值。

1
2
3
4
5
6
7
8
use master
go

create default def_price as 50
go

exec sp_bindefault def_price, 'Titles.price'
go

四,事务

1,事务的概念

1)事务定义:用户定义的一个数据库操作序列,这些操作要么可全部成功执行,否则,将不执行其中任何一个操作。事务是一个不可分割的工作单元。

2)事务基本性质(ACID)

(1)原子性(Atomicity):事务中包含的所有操作要么全做,要么一个也不做。
(2)一致性(Consistency):定义在数据库上的各种完整性约束。
(3)隔离性(Ioslation):确保事务并发执行后的系统状态与这些事务以某种次序串行执行后的状态是等价的。
(4)持久性(Durability):一个事务一旦成功完成,它对数据库的改变必须是永久的,即使是在系统遇到故障的情况下也不会丢失。

2,事务调度

1)事务调度的定义:在一个大型的DBMS中,可能会同时存在多个事务处理请求,系统需要确定这组事务的执行次序,即每个事务的指令在系统中执行的时间顺序,这称为事务的调度

2)合法调度须满足以下条件:

i)调度必须包含所有的事务的指令;
ii)一个事务中指令的顺序在调度中必须保持不变。

3)调度的基本形式

i)串行调度

  • 串行调度:在前一个事务完成之后,在开始另外一个事务,类似与操作系统中的单道批处理作业。
  • 可串行化调度:定义多个事务的并发执行是正确的,当且仅当其结果与按某一次序串行地执行它们时的结果相同,这种调度策略称为可串行化调度

ii)并行调度

  • 并行调度可串行化:如果一组事务并行调度的执行结果等价于这组事务中所有提交事务的某个串行调度,则称该并行调度可串行化
  • 级联回滚:由于一个事务的故障而导致一系列其他事务的回滚。
  • 无级联调度:应该对调度做出某种限制以避免级联回滚发生,这样的调度称为无级联调度
  • 可恢复调度:对每对事务$T_i$和$T_j$,如果$T_j$读取了由$T_i$所写的数据项,则$T_i$必须先于$T_j$提交。

3,事务隔离级别

1)并发操作带来的问题

i)丢失修改:又称写-写错误,两个事务$T_1$和$T_2$读入同一数据并修改,$T_2$提交的结果破坏了$T_1$提交的结果,导致$T_1$的修改被丢失。
ii)脏读:又称写-读错误,事务$T_1$修改某一数据,并将其写回磁盘,事务$T_2$读取同一数据后,$T_1$由于某种原因被撤销,这时$T_1$已修改过的数据恢复原值,$T_2$读到的数据就与数据库中的数据不一致,则$T_2$读到的数据即为“脏”数据,即不正确的数据
iii)不可重复读:又称读-写错误,事务$T_1$读取某一数据后,事务$T_2$对其做了修改,当$T_1$再次读取该数据时,得到与前次不同的值。
iv)幻想读:事务$T_2$按一定条件读取了某些数据后,事务$T_1$插入(删除)了一些满足这些条件的数据,当$T_2$再次按相同条件读取数据时,发现多(少)了一些记录。

2)事务隔离级别的定义

i)未提交读:又称脏读,允许运行在该隔离级别上的事务读取当前数据页上的任何数据,而不管该数据是否已提交,解决了丢失修改问题。
ii)提交读:保证运行在该隔离级别上的事务不会读取其他未提交事务所修改的数据,解决了丢失修改脏读的问题。
iii)可重复读:保证一个事务如果再次访问同一数据,与此前访问相比,数据不会发生修改,解决了丢失修改脏读不可重复读问题。
iv)可串行化:在这个级别上的一组事务的并发执行与它们的某个串行调度是等价的,解决了并发操作带来的四个不一致问题。

4,SQL Server中的事务定义

1)事务定义模式

1
2
3
4
5
6
7
8
9
10
11
12
-- 定义
BEGIN TRAN[SACTION] [事务名[WITH MARK['事务描述']]]

-- 提交1
COMMIT [TRAN[SACTION] [事务名]]
-- 提交2
COMMIT[WORK]

-- 回滚1
ROLLBACK [TRAN[SACTION] [事务名|保存点名]]
-- 回滚2
COMMIT[WORK]

2)事务执行模式

i)显式事务:每个事务均以 BEGIN TRANSACTION 语句显式开始,以 COMMIT 或者 ROLLBACK 语句显式结束。
ii)隐性事务:每个事务无须描述事务的开始,但仍以 COMMITROLLBACK语句显式完成。
iii)自动提交事务SQL Server 的默认事务管理模式,意指每条单独的语句都是一个事务。在完成每个 T-SQL 语句时,都被提交或者回滚。

1
2
-- 隐性事务设置方法
SET IMPLICIT_TRANSACTIONS {ON|OFF}

3)事务隔离级别的定义

1
2
3
4
5
6
7
set transaction isolation level read uncommitted;

set transaction isolation level read committed;

set transaction isolation level repeatable read;

set transaction isolation level serializable;

4)批处理,触发器的事务

批处理是包含一个或者多个SQL语句的组,从应用程序一次性地发送到服务器执行。服务器将批处理语句编译成一个可执行单元,此单元称为执行计划

五,并发控制

1,相关概念

事务是并发控制的基本单位,事务最基本的特征之一是隔离性。为保证事务的隔离性,系统必须对并发事务之间的相互作用加以控制,这称为并发控制。并发控制的主要技术是封锁

2,封锁技术

1)封锁:事务$T$在对某个数据库对象操作之前,先向系统发出请求,对其加锁。最基本的封锁模式有排他锁(X锁)共享锁(S锁)

i)排他锁:又称写锁,如果事务$T$对数据对象$A$加上$X$锁,则只允许$T$读取和修改$A$,其他任何事务都不能再对$A$加任何类型的锁,直到$T$释放$A$上的锁。申请对$A$的排他锁可表示为$XLOCK(A)$。
ii)共享锁:又称读锁,如果事务$T$对数据对象$A$加上$S$锁,则只允许$T$读取$A$但不允许修改$A$,其他事务只能再对$A$加$S$锁而不能加$X$锁,直到$T$释放$A$上的$S$锁。申请对$A$的共享锁可表示为$SLOCK(A)$。

3,事务隔离级别与封锁规则

1)封锁协议(Locking Protocol):在运用$X$锁和$S$锁这两种基本封锁对数据对象加锁时,还需要约定规则,如何时申请$X$锁或$S$锁,持锁时间,何时释放等,这些规则称为封锁协议

2)长锁:保持到事务结束的锁;短锁:用完就释放的锁。

4,封锁粒度(MGL

1)封锁粒度定义:封锁对象的大小称为粒度

i)多粒度封锁:数据库中被封锁的资源按粒度大小会呈现处一种层次关系,元组隶属于关系,关系隶属于数据库,称为粒度树。当为某结点加上意向锁($I$锁)时,就表明某些内层结点已发生事实上的封锁,防止其他事务再去封锁该结点,这种封锁方式称为多粒度封锁(Multi Granularity Lock)
ii)意向锁:如果对一个结点加意向锁,则说明该节点的下层结点正在加锁;对任意节点加锁时,必须先对它所在的上层结点加意向锁。

  • 意向共享锁(IS锁):如果对一个数据对象加IS锁,表示它的后裔结点拟(意向)加S锁。
  • 意向排他锁(IX锁):如果对一个数据对象加IX锁,表示它的后裔结点拟(意向)加X锁。
  • 共享意向排他锁(SIX锁):如果对一个数据对象加SIX锁,表示对它加S锁,再加IX锁。

5,并发控制

1)SQL Server锁模式:共享锁(S锁),更新锁(U锁),排他锁(X锁),意向共享锁(IS锁), 意向排他锁(IX锁),共享意向排他锁(SIX锁)。

2)SQL Server锁粒度:行级(Row),页面级(Page),表级(Table

3)强制封锁类型
在通常情况下,数据封锁由DBMS控制,对用户是透明的,但可以在SQL语句中加入锁定提示来强制 SQL Server 使用特定类型但锁。

六,数据库恢复技术

1,恢复的概念:负责将数据库从故障所造成的错误状态中恢复到某一已知的正确状态(也称为一致性状态或者完整状态)。

2,故障的种类

1)事务故障:指事务的运行没达到预期对象终点就终止,有两种错误可能造成事务执行失败。

i)非预期故障:是指不能由应用程序处理的故障,如运算溢出,但该事务可以在以后但某个时间重新执行。
ii)可预期故障:指应用程序可以发现的事务故障,并且可以控制让事务回滚。

2)系统故障:又称软故障,指在硬件故障,软件错误的影响下,导致内存中的数据丢失,并使得事务处理终止,但未破坏外存中数据库。
由于硬件错误和软件漏洞致使系统终止,而不破坏外存内容但故障又称为故障-停止假设

3)介质故障:又称硬故障,指由于磁盘的磁头碰撞,瞬时的强磁场干扰等造成磁盘的损坏,破坏外存上的数据库,并影响正在存取的这部分数据的所有事务。

4)恢复的基本原理冗余,即数据库中任意部分的数据可以根据存储在系统别处的冗余数据来重建。一般的冗余形式:副本日志

3,恢复的实现技术

1)数据转储DBA定期将整个数据库复制到磁带或者在另一个磁盘上保存起来的过程。

i)静态转储:在系统中无运行事务时进行的转储操作,即转储操作开始的时刻,数据库处于一致性状态,而转储期间不允许对数据库的任何存取,修改活动。
ii)动态转储:指在转储期间允许对数据库进行存取或修改,即转储与用户事务可以并发执行。
iii)全量转储:每次转储全部数据库。
iv)增量转储:每次只转储上一次转储后更新过的数据。

2)登记日志文件

日志是以事务为单位记录数据库每次更新活动的文件,由系统自动记录。遵循以下原则

i)登记的次序严格按并发事务执行的时间次序;
ii)必须先写日志文件,然后写数据库。

前像:要撤消事务,日志中必须包含数据库发生变化前的所有记录的备份,这些记录称为前像(Before-Images)

后像:为了恢复事务,日志中必须包含数据库改变之后的所有记录的备份,这些记录称为后像(After-Images)

3)基本日志结构

日志是日志记录(Log Records)的序列,主要包含:

(1)事务开始标识,如<$T_i$ start>;
(2)更新日志记录,描述一次数据库写操作,如<$T_i,X_i,V_1,V_2$>

事务标识$T_i$是执行WRITE操作的事务的唯一标识;
数据项标识$X_i$是所写数据项的唯一标识,通常是数据项在磁盘上的位置;
更新前数据的旧值$V_1$ (对插入操作而言此项为空值);
更新后数据的新值$V_2$ (对删除操作而言此项为空值)。
(3)事务结束标识
<$T_i$ COMMIT>,表示事务$T_i$提交;
<$T_i$ ABORT>,表示事务$T_i$中止。

4,SQL Server基于日志的恢复策略

1)事务分类

i)圆满事务:指日志文件中记录了事务的COMMIT标识,说明日志中已经完整地记录下事务所有的更新活动。
ii)夭折事务:指日志文件只有事务的开始标识,而无COMMIT标识,说明对事务更新活动的记录是不完整的,无法根据日志来重现事务。

2)基本的恢复操作

i)重做:对圆满事务所做过的修改操作应执行REDO操作,即重新执行该操作,修改对象赋予其新记录值,这种方法称为前滚
ii)撤销:对夭折事务所做过的修改操作应执行UNDO操作,即撤销该操作,修改对象赋予其旧记录值,这种方法又称为回滚

3)事务故障恢复

i)反向扫描日志文件,查找该事务的更新操作;
ii)对该事务的更新操作执行逆操作,即将事务更新前的旧值写入数据库;
iii)继续反向扫描日志文件,查找其他事务的其他更新操作,做同样处理;
iv)如此处理下去,直至读到该事务的开始标识,事务恢复故障完成。

4)系统故障恢复

i)正向扫描日志文件,找出圆满事务,将其事务标识记入重做队列;找出夭折事务,将其事务标识记入撤销队列;
ii)对撤销队列中的各个事务进行撤销处理,即反向扫描日志文件,对每个撤销事务对更新操作执行逆操作;
iii)对重做队列中的各个事务进行重做处理,即正向扫描日志文件,对每个重做事务重新执行日志文件登记的操作。

5)介质故障恢复

i)装入最新的数据库后备副本,将数据库恢复到最近一次转储时的一致性状态;
ii)装入相应的日志文件副本,重做已完成的事务。

5,SQL Server的备份与恢复

1)SQL Server的备份

i)数据库备份:即完全备份

  • 设置简单恢复模式:

    1
    alter database master set recovery simple;
  • 执行完全备份:

    1
    2
    3
    4
    5
    use master;
    go

    -- init:如果已存在bak文件,则首先删除,后执行
    backup database master to disk='E:\mater_full.bak' with init;

ii)差异备份:只存储上一次完备之后发生改变的数据。

1
2
3
4
5
use master;
go

-- init:如果已存在bak文件,则首先删除,后执行
backup database master to disk='E:\mater_diff.bak' with init, differential;

iii)日志备份:数据库的恢复模式必须设为完整恢复模式并且必须在数据更改为完整恢复模式后至少执行一次完整数据库备份。

  • 设置完整恢复模式:

    1
    alter database master set recovery full;
  • 执行日志备份:

    1
    2
    3
    4
    use master;
    go

    backup log master to disk='E:\master_log.bak'

2)SQL Server恢复

i)使用SQL Server管理工具还原数据库
ii)使用T-SQL语句从简单备份策略还原数据库

1
restore database master from disk='E:\master_full.bak';

iii)使用T-SQL语句还原差异备份

1
2
restore database master from disk='E:\master_full.bak' with norecovery;
restore database master from disk='E:\master_diff.bak';

iv)使用T-SQL语句从完整备份策略还原数据库

1
2
3
restore database master from disk='E:\master_full.bak' with replace, norecovery;
restore log master from disk='E:\master_log1.bak' with norecovery;
restore log master from disk='E:\master_log2.bak';

坚持原创技术分享,您的支持将鼓励我继续创作!