Security and Integrity Constraints of Database 数据库安全与完整性约束
概述
数据库的安全
数据库数据被破坏的原因
- 系统的软硬件故障 【DBMS的恢复机制】
- 很多用户的并发访问控制不当 【DBMS的并发控制】
- 人为破坏 【数据库的安全性】
- 数据库输入的数据不正确 【数据库的完整性约束】
保证数据库数据安全的措施
-
利用视图和查询修改
-
访问控制
- 对用户进行分类来给不同的权限
- 普通用户
- DBA
- 有资源特权的用户
- 对用户进行分类来给不同的权限
-
用户标识和用户认证
- 每个用户有一个用户标识
- 通过password进行用户认证
-
授权【权限检查】
-
例子
-
GRANT CONNECT TO JOHN IDENTIFIED BY jjjjj;//在数据库建立一个用户JOHN,password为jjjjj GRANT SELECT ON TABLE S TO U1 WITH GRANT OPTION;//对数据对象进行授权,U1的用户可对S表做select操作,with grant option是运行权力转授
-
-
-
role【角色机制】
- 通过该方法提高权限控制
-
数据加密
- 加密后存储【密码学】
- 代价:加密解密影响效率
-
审计追踪
- 结合数据库日志,可以在关注的对象上添加审计追踪,会记录该对象上进行的操作
统计数据库的安全
- 实际应用中一些统计结果可以给所有人看,但个体数据不可公开的情况
- 防止合法用户通过合法查询经过推算得到他不可得的隐私数据
- 统计数据库的安全难以保证:因为有个体追踪器和通用追踪器,而数据库不可能检查每一条谓词
个体追踪器
-
如果谓词P=P1 and p2 ,在一个关系中只有一条元组满足
-
SET(p) = SET(p1 and p2) = SET(p1) - SET(p1 and not p2)
-
只能追踪一个元组
通用追踪器
- 找到一个谓词T满足:
- 2b<=|SET(T)|<=(n-2b),b<n/4
- n为表的总元组数
- 如果只有一个元组R谓词p,那么:
- SET§ = SET(p or T) union all SET(p or not T) - SET(T) - SET(not T)
- union all means union without eliminating repeated tuples.
完整性约束
- 完整性约束就是规则,一张表内所有元组都要满足的条件就是完整性约束
- 保证所有进入数据库的数据都是干净的
- 可以在建立表的时候家伙是那个CHECK语句表明约束
静态约束
-
数据模型固有的约束:
- 关系模型中的一范式
-
隐含约束
- 数据库表的模式定义里面的约束
- 如:域约束、主键约束、外键约束【引用完整性约束】
- 数据库表的模式定义里面的约束
-
显示约束
-
通过断言ASSERTION
-
ASSERT balanceCons【断言名字】 ON account【表名】 :balance>=0 【要求满足的属性条件】
-
-
通过应用程序,不满足条件的数据不接受
-
动态约束
- 数据库在状态转换中要满足的约束叫做动态约束
数据库的更新与引用完整性
数据库的更新
- 当有外键映射关系的两张表发生增删改操作时,数据库要做检查
增
- 当要在外键的表中增加元组时,要在主键的表进行检查,是否有对应的,若没有就报错
删
- 如果要删除主键的表的某条元组时,要检查外键的表内是否有对应的值,如果查询结果为空,那么可以删,如果不为空的话,数据库会提供两种情况【由用户在定义表的时候决定】:
- 报错【默认】
- 级联删除
- 主键的表和外键的表的对应元组一同删除
更新
- 想对外键表内已有的元组做更新,要检查要修改的新址是否在主键的表内有,如果有就能更新,如果没有就报错
- 向对主键表内已有的元组做更新,要检查外键的表内是否有对应的值,如果查询结果为空,那么可以修改,如果不为空的话,数据库会提供两种选择【由用户在定义表的时候决定】:
- 报错【默认】
- 级联更新
- 主键的表和外键的表的对应元组一同更改
针对单个表的约束
- 要求该表的级别的属性的值为大于等于1,小于等于10的整数
CREATE TABLE Sailors(
sid INTEGER,
sname CHAR(10),
rating INTEGER,
age REAL,
PRIMARY KEY(sid),
CHECK(rating>=1 AND rating<=10));
CREATE TABLE Reserves
( sname CHAR(10),
bid INTEGER,
day DATE,
PRIMARY KEY (bid, day),
CONSTRAINT noInterlakeRes 约束的名字
CHECK (‘Interlake’ <> 不等于 Interlake的船
( SELECT B.bname
FROM Boats B
WHERE B.bid=bid)))
针对多个表的约束
- 要求水手数和船的数的和要小于100
CREATE TABLE Sailors (
sid INTEGER,
sname CHAR(10),
age REAL,
PRIMARY KEY(sid),
CHECK(
(SELECT COUNT(S.sid) FROM Sailors S)
+(SELECT COUNT(B.bid) FROM Boats B)<100);//这样查询,如果长时间在船的表添加,而不往水手的表内添加的话就无法进行合理查询,当涉及多个表的约束要使用断言更好
# ASSERTION is the right solution; not associated with either table
CREATE ASSERTION smallClub
CHECK
( (SELECT COUNT (S.sid) FROM Sailors S)
+(SELECT COUNT (B.bid) FROM Boats B) < 100 )
- 只在该表进行查、删、改操作时才执行CHECK的检查
触发器
-
主动数据库:能对数据库采取一些主动的动作。
- 数据库的主动依赖于规则
- 规则:ECA规则,E为事件、C为条件、A为动作。即当事件A发生,且条件C满足时,采取A动作
- 数据库的主动依赖于规则
-
触发器就是ECA规则
-
不同数据库的实现方法不同
-
例子:当在水手的表插入的水手年龄小于等于18时,同时向年轻水手的表内也插入
-
CREATE TRIGGER youngerSailorUptate //触发器名字 AFTER【触发时机】 INSERT ON SAILORS REFERENCING NEW TABLE NewSailors 【对水手表新插入的元组看出一张表】 FOR EACH STATEMENT INSERT INTO YoungSailors(sid,name,age,rating) SELECT sid,name,age,rating FROM NewSailors N WHERE N.age <=18;
-
触发器的执行策略
- 立即执行【常用】
- 当事件发生时立刻去检查条件是否满足
- 延迟执行
- 等事务要提交时执行
- 分离执行
- 把ECA规则中的动作单独作为一个事务,作为原来事务的衍生事务
- 级联触发
- 控制规则的嵌套执行
- 防止不终止
- 触发图
- 设置级联次数上限
- 因此,应合理使用触发器
触发器的连锁触发问题
- 当触发器的动作内也有触发器产生连锁触发
- 连锁触发可能产生环路:类似递归中的无限递归
- 触发器过程性的,不能被DBMS优化
避免连锁触发
- 构造触发图
- 对连锁触发的次数进行限制