数据库的完整性是指数据的正确性和相容性。
数据的正确性是指数据符合现实世界语义,反映当前实际情况;数据的相容性是指数据库在同一对象的不同关系表中的数据是符合逻辑的。
数据的完整性:为了防止数据库中存在不和语义的数据
数据的安全性:为了保护数据库防止恶意破坏和非法存取。
1.实体完整性
关系数据库中每个元组应该是可区分的,是唯一的。
关系模型的实体完整性在CREATE TABLE中用PRIMARY KEY定义。
2.参照完整性
参照完整性规则就是定义外码和主码之间的引用规则。
关系模型的参照完整性在CREATE TABLE 中用FOREIGN KEY 短语定义哪些列为外码,用REFERENCES短语指明这些外码参照哪些表的主码。
FORGEIGN KEY(sno) REFERENCES course(sno) |
3.用户定义完整性
用户定义的完整性就是针对某一具体关系数据库的约束条件,它反映某一具体应用所涉及的数据必须满足的语义要求。
3.1属性上的约束条件
在CREATE TABLE中定义属性的同时,可以根据应用要求定义属性上的约束条件。包括:
列值非空(NOT NULL)
Sno CHAR(9) NOT NULL, |
列值唯一(UNION)
Dname CHAR(9) UNIQUE NOT NULL, |
检查列值是否满足一个条件表达式(CHECK短语)
#sex只允许取男女 Ssex CHAR(2) CHECK(Ssex IN('男','女')), |
当往表中插入元组或修改属性的值时,关系数据库管理系统将检查属性上的约束条件是否被满足,如果不满足则操作被拒绝执行。
3.2元组上的约束条件
在CREATE TABLE语句中可以使用CHECK短语定义元组上的约束条件,元组级的限制可以设置不同属性之间的取值的相互约束条件。
#创建表时规定性别是男性时名字不能以Ms打头 CHECK (Ssex='女'OR Sname NOT LIKE 'Ms.%') |
4.完整性约束子句
SQL在CREATE TABLE 语句中提供了完整性约束子句CONSTRAINT,用来对完整性约束条件命名,从而可以灵活的增加或删除一个完整性约束条件。
CONSTRAINT 完整性约束条件名 完整性约束条件 #完整性约束条件包括NOT NULL、UNIQUE、PRIMARY KEY、FOREIGN KEY、CHECK短语等 |
修改表中的完整性限制
#删除 ALTER TABLE table_name DROP CONSTRAINT 完整性约束条件名 |
#添加 ALTER TABLE table_name ADD CONSTRAINT 名 条件 |
5.断言
SQL使用CREATE ASSERTION语句,通过声明性断言来指定更具一般性的约束,可以涉及多个表或聚集操作的约束,使断言不为真值的操作都会被拒绝执行。
CREATE ASSERTION 断言名 CHECK子句 |
例子:
CREATE ASSERTION num CHECK( 60>=( SELECT COUNT(*) FROM course,sc WHERE sc.cno=course.cno AND course.name='数据库' ) ); |
删除断言:
DROP ASSERTION 断言名 |
6.触发器
触发器是用户定义在关系表上的一类由事件驱动的特殊过程,一旦定义,触发器将被保存在数据库服务器中,任何用户对表的增删查改均由服务器自动激活相应的触发器,在关系数据库管理系统核心层进行集中的完整性控制。
CREATE TRIGGER 触发器名#每当触发事件发生时,触发器被激活 {BEFORE|AFTER} 触发事件 ON 表名#指明触发器激活的时间在执行触发事件前或后 REFERENCING NEW|OLD ROW AS 变量#REFERENCING指出引用的变量 FOR EACH{ROW|STATEMENT}#定义触发器的类型,指明动作执行的频率,EACH ROW是行级触发器,EACH STATEMENT是语句级触发器 [WHEN 触发条件] 触发动作体#仅当触发条件为真时才执行触发动作体 |
触发事件:触发事件可以是INSERT,UPDATE,DELETE,也可以是这几个事件的组合,如INSERT OR UPDATE;还可以是UPDATE OF 列名表明修改哪些列时触发服务器
REFERENCING NEW|OLD ROW AS 变量:的ROW也可以是TABLE等,用来指明处理后的触发事件的对象和处理前的触发事件的对象。
例子:当对表SC的grade值进行修改时,若分数增加10%,则将此处操作记录到另一个表中,其中oldgrade是修改前的分数,newgrade是修改后的分数。
CREATE TRIGGER sc_t AFTER UPDATE OF grade ON SC
REFERENCING OLD ROW AS oldtuple NEW ROW AS newtuple FOR EACH ROW WHEN(newtuple.grade>=1.1*oldtuple.grade) INSERT INTO SCNEW(……) VALUES(……) |
删除触发器:DROP TRIGGER 触发器名 ON 表名