数据库一致性被破坏:
- 系统故障
- 许多用户的并发访问
- 人为破坏
- 事务本身不正确
保护数据库一致性的方法:
- 视图/查询修改
- 访问控制
- 普通用户
- 拥有资源特权的用户
- DBA
数据库的安全问题
- 身份验证
- 口令
- 物理设备
GRANT CONNECT TO John IDENTIFIED BY 123456;
GRANT SELECT on TABLES table-name TO user-name WITH GRANT OPTION
--with grant option 表示用户具有将对这张表的操作权限转给其他用户的能力
- 角色
- 数据加密
- 审计追踪
统计数据库
个体追踪器
通用追踪器
完整性约束
每一个合法实例都必须满足的条件
如果不满足完整性约束,DBMS不会允许进入数据库
- 静态约束
- 数据模型固有的约束
- 隐含约束:域完整性约束、主键约束(实体完整性约束)、外键约束(引用完整性约束)
- 显式约束
- 动态约束:数据库在转换过程中应该遵循的规则
静态约束
当有引用完整性约束的时候,如果要删除所引用的表中的元组,需要检查该元组的主键是否在引用表的外键中出现,如果出现,有两个选择:
- 报错(默认)
- 级联删除(需要进行设置)
引用完整性约束更新主键:
- 报错(默认)
- 级联更新
显式约束
- 程序进行限制
- 使用DBMS断言ASSERTION
ASSERT balanceCons ON account:balance>=0; //balanceCons是断言的名字
- 使用
CHECK
:在建表的时候
CREATE TABLE Reserves
(sname CHAR(10),
bid INTEGER,
day DATE,
PRIMARY KEY (bid,day),
CONSTRAINT noInterlakeRes
CHECK('Interlake' <> (SELECT B.bnameFROM Boats BWHERE B.bid=bid)))
--规定名字为Interlake的船不能外借
如果牵涉到两个以上的表的约束就不能在CREATE
语句中使用CHECK
,因为这样只有对其中一个表进行增删改的时候才会触发CHECK
约束,如果不进行增删改就没法保持约束。应该使用断言进行约束。
CREATE ASSERTION smallClub
CHECK
((SELECT COUNT(*) FROM Sailors) +
(SELECT COUNT(*) FROM Boats)<100)
可以保证在两个表任何一个进行增删改操作的时候都要满足约束
动态约束+触发器
主动数据库:数据库中的数据达到某种状态的时候主动进行一些动作
触发器:E(事件)C(检查数据库)A(动作)规则
--监视水手这张表,更新年轻水手表
CREATE TRIGGER youngSailorUpdate
AFTER INSERT ON Sailors -- ON 后面跟需要监视的表
--AFTER/BEFORE控制动作发生之前还是之后
--INSERT/DELETE/UPDATE 控制发生什么动作
REFERENCING NEW TABLE NewSailors
--NEW表示插入操作的新值,OLD表示老值
--TABLE表示把前面引用的值看作一张表
FOR EACH STATEMENT
--还可以是FOR EACH ROW 当操作涉及多个元组的时候可以分别进行不同的操作
--可以使用WHEN子句进行检查
INSERT INTO YoungSailors VALUES SELECT * FROM NewSailors N WHERE N.age<=18
实现方法:
- 立即执行(常见)
- 延迟
- 分离
触发器的连锁触发:
- 根据触发图,限制触发器执行
- 连续触发的次数进行限制
触发器的定义需要小心,不能定义太多的触发器
触发器实现方法:
- 松耦合
- 紧耦合
- 嵌套