数据库系统概论笔记(5)
第5章数据库完整性
数据库完整性是指:数据的正确性和相容性
- 数据的正确性:防止数据库中存在不正确的数据
- 数据的相容性:防止恶意破坏和非法存取
为保证数据库的完整性,DBMS要实现的功能:
- 提供定义完整性约束条件的机制
包括:关系模型的实体完整性、参照完整性、用户定义完整性 - 提供完整性检查的方法
一般在INSERT、UPDATE、DELETE语句执行后开始检查 - 进行违约处理
包括:拒绝该操作、级联进行其它操作等
5.1实体完整性
定义实体完整性
关系模型的实体完整性在CREATE TABLE
中用PRIMARY KEY
定义
说明方法:
- 对单属性构成的码(两种):定义为列级约束条件,定义为表级约束条件
- 对多属性构成的码(一种):定义为表级约束条件
列级约束:在定义属性时定义(Sno CHAR(9) PRIMARY KEY
)
表级约束:放在最后定义(PRIMARY KEY (Sno)
)
实体完整性检查和违约处理
用户对基本表进行插入或更新主码列时进行检查
检查内容:
- 主码值是否唯一(不唯一则拒绝)
- 检查主码的各个属性是否为空(有一个为空则拒绝)
检查的方法:
- 全表扫描(费时)
- 在主码上建立索引(例如建立B+树索引)
5.2参照完整性
定义参照完整性
参照完整性在CREATE TABLE
中用FOREIGN KEY
短语定义哪些列为外码,用REFERENCES
短语指明外码参照哪些表的主码
... FOREIGN KEY (Sno) REFERENCES Student(Sno)
参照完整性检查和违约处理
相关违约处理:
- 拒绝执行(NO ACTION)
不允许该操作执行。(一般是默认策略) - 级联操作(CASCADE)
删除或修改参照表中的所有导致不一致的元组 - 设置为空值
将参照表中的所有造成不一致的元组的对应属性设置为空值
对于参照完整性,除了定义外码,还应定义外码列是否允许空值
若想让系统采用其他策略则必须在创建参照表时显式地加以说明:
5.3用户定义的完整性
属性上的约束条件
- 定义方法:
列值非空(NOT NULL)(例:Sno CHAR(9) NOT NULL
)
列值唯一(UNIQUE)(例:Sno CHAR(9) UNIQUE
)
检查列值是否满足一个条件表达式(CHECK短语)(例:Ssex CHAR(2) CHECK(Ssex IN ('男','女'))
) - 违约处理:不满足测操作被拒绝执行
元组上的约束条件
- 定义方法:在CREATE TABLE语句中用CHECK语句定义元组上的约束条件(可以设置不同属性之间取值的相互约束条件)
(例:CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%')
) - 违约处理:不满足测操作被拒绝执行
5.4完整性约束命名子句
在CREATE TABLE语句中用子句CONSTRAINT对完整性约束条件命名
好处:更加灵活地增加/删除一个完整性条件约束
- 完整性约束命名子句
一般格式:
CONSTRAINT <完整性约束条件名> <完整性约束条件>
完整性约束条件包括:NOT NULL、UNIQUE、PRIMARY KEY、FOREIGN KEY、CHECK等
(例:CONSTRAINT C1 CHECK(Sno BETWEEN 900 AND 999)
)
- 修改表中的完整性限制
使用ALTER TABLE
语句:
例: 去除约束条件 ALTER TABLE Student DROP CONSTRAINT C1; 修改约束条件(先删除再增加) ALTER TABLE Student DROP CONSTRAINT C1; ALTER TABLE Student ADD CONSTRAINT C1 CHECK(Sno BETWEEN 90 AND 99);
5.5域中的完整性限制
略,老师未讲
5.6断言
使用CREATE ASSERTION
语句,通过声明性断言来指定更具一般性的约束
作用:任何对断言中所涉及关系的操作都会触发关系数据库管理系统对断言的检查
注意:若断言很复杂,则系统在检测和维护断言上的开销会较高
创建断言
语句格式:
CREATE ASSERTION <断言名> <CHECK子句> //<CHECK子句>中的约束条件与WHERE子句的条件表达式类似 例: 限制每个学期每一门课最多60名学生选修 CREATE ASSERTION ASSE_SC_CNUM CHECK( 60>=( SELECT COUNT(*) FROM SC GROUP BY Cno,TREM ) );
删除断言
语句格式:
DROP ASSERTION <断言名>;
5.7触发器
概念:是用户定义在关系表上的一类由事件驱动的特殊过程(动态约束)
定义触发器
触发器又叫做事件-条件-动作规则
建立触发器的一般格式:
CREATE TRIGGER <触发器名> //每当触发事件发生时,该触发器被激活 {BEFORE|AFTER} <触发事件> ON <表名> //指明触发器激活的时间是在执行触发事件之前或后 REFERENCING NEW|OLD ROW AS<变量> //REFERENCING 指出引用的变量(行级用NEWROW/OLDROW,语句级用NEWTABLE/OLDTABLE) FOR EACH{ROW|STATEMENT} //定义触发器的类型,指明动作体执行的频率 [WHEN <触发条件>] <触发动作体> //仅当触发条件为真时才执行触发动作体 说明: 只有表的拥有者才可以在表上创建触发器,并且一个表上只能创建一定数量的触发器 触发器名:可以包含模式名 表名:只能定义在基本表上,不能定义在视图上 触发事件:可以是INSERT、DELETE、UPDATE或这几个事件的组合 触发器类型:按照所触发动作的间隔尺寸分为行级触发器(FOR EACH ROW)和语句级触发器(FOR EACH STATEMENT) 触发条件:只有触发条件为真时才触发动作体执行,若忽略WHEN,则触发动作体在触发器激活后立即执行 触发动作体:可以是PL/SQL过程块,或是对已创建存储过程的调用 例: 当对表SC的Grade属性进行修改时,若分数增加了10%,则将此次操作记录到另一个表SC_U(Sno,Cno,Oldgrade,Newgrade)中 CREATE TRIGGER SC_T AFTER UPDATE OF Grade ON SC REFERENCING OLDROW AS OldTuple, NEWROW AS NewTuple FOR EACH ROW WHEN(NewTuple.Grade >= 1.1*OldTuple.Grade) INSERT INTO SC_U(Sno,Cno,OldGrade,NewGrade)0 VALUES(OldTuple.Sno,OldTuple.Cno,OldTuple.Grade,NewTuple.Grade)
激活触发器
触发器的执行时由触发事件激活,并由数据库服务器自动执行的
同一个表的多个触发器激活时遵循的执行顺序
- 执行该表上的BEFORE触发器
- 激活触发器的SQL语句
- 执行该表上的AFTER触发器
对于多个BEFORE(AFTER)触发器,遵循“谁先创建谁先执行”的原则
删除触发器
SQL语法:
DROP TRIGGER <触发器名> ON <表名>;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律