資料庫系統概論第五章筆記
第五章 資料庫完整性
資料庫的完整性(integrity)是指資料的正確性(correctness)和相容性(compat-ability)。
1、資料的正確性是指資料是符合現實世界語義,反映了當前實際狀況的。
2、資料的相容性是指資料庫同一物件在不同關係表中的資料是符合邏輯的。
例如:
學生的學號必須唯一
性別只能是男或女
本科學生年齡的取值範圍為14~50的整數
學生所選的課程必須是學校開設的課程,學生所在的院系必須是學校已成立的院系
資料庫的完整性和安全性是兩個既有聯絡又不盡相同的概念。資料的完整性是為了防止資料庫中存在不合語義的資料,也就是防止資料庫中存在不正確的資料。資料的安全性是保護資料庫防止惡意破壞和非法存取。因此,完整性檢查和控制的防範物件是不合語義的、不正確的資料,防止它們進入資料庫。安全性控制的防範物件是非法使用者和非法操作,防止他們對資料庫資料的非法存取。
而為了維護資料庫的完整性,資料庫管理系統必須能夠實現如下功能:
一:提供定義完整性約束條件的機制
完整性約束條件也稱為完整性規則,是資料庫中的資料必須滿足的語義約束條件。
SQL標準使用了一系列概念來描述完整性,包括關係模型的實體完整性、參照完整性和使用者定義完整性。
這些完整性一般由SQL的資料定義語言語句來實現。
定義完整性分為:實體完整性、參照完整性、使用者定義完整性(又分為屬性和元組上的約束條件)
Ⅰ:實體完整性
單屬性構成的碼有兩種說明方法
- 定義為列級約束條件
Example:
CREATE TABLE Student
( Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);
- 定義為表級約束條件
Example:
CREATE TABLE Student
( Sno CHAR(9),
Sname CHAR(20) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno)
);
對多個屬性構成的碼只有一種說明方法定義為表級約束條件
Example:
CREATE TABLE SC
( Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno,Cno) //只能在表級定義主碼
);
Ⅱ:參照完整性
在CREATE TABLE中用FOREIGN KEY短語定義哪些列為外碼。
用REFERENCES短語指明這些外碼參照哪些表的主碼。
Example:
CREATE TABLE SC
( Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY (Sno, Cno), //在表級定義實體完整性
FOREIGN KEY (Sno) REFERENCES Student(Sno),
//在表級定義參照完整性
FOREIGN KEY (Cno) REFERENCES Course(Cno)
//在表級定義參照完整性
);
Ⅲ:使用者定義完整性
- 屬性上的約束條件
列值非空(NOT NULL)
列值唯一(UNIQUE)
檢查列值是否滿足一個條件表示式(CHECK)
可組合使用如 UNIQUE NOT NULL //要求列值唯一, 並且不能取空值
CHECK (Ssex IN(‘男’,’女’))//性別屬性Ssex只允許取'男'或'女'
CHECK (Grade>=0 AND Grade <=100) // Grade取值範圍是0到100
- 元組上的約束條件
在CREATE TABLE時可以用CHECK短語定義元組上的約束條件,即元組級的限制。
同屬性值限制相比,元組級的限制可以設定不同屬性之間的取值的相互約束條件。
Example:
CREATE TABLE Student
( Sno CHAR(9),
Sname CHAR(8) NOT NULL,
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20),
PRIMARY KEY (Sno),
CHECK (Ssex='女' OR Sname NOT LIKE 'Ms.%')
//定義了元組中Sname和 Ssex兩個屬性值之間的約束條件
性別是女性的元組都能通過該項檢查,因為Ssex=‘女’成立;
當性別是男性時,要通過檢查則名字一定不能以Ms.打頭
);
使用者定義的完整性是針對某一具體應用的資料必須滿足的語義要求。
二:提供完整性檢查的方法
資料庫管理系統中檢查資料是否滿足完整性約束條件的機制稱為完整性檢查。
一般在INSERT、UPDATE、DELETE語句執行後開始檢查,也可以在事務提交時檢查。
三:違約處理
資料庫管理系統若發現使用者的操作違背了完整性約束條件,就採取一定的動作
- 拒絕(NO ACTION)執行該操作
- 級連(CASCADE)執行其他操作
實體完整性檢查和違約處理按照實體完整性規則自動進行檢查,檢查是否唯一和為空進行拒絕插入和修改。
參照完整性檢查和違約處理:
被參照表 參照表 違約處理
可能破壞參照完整性 <- 插入元組 拒絕
可能破壞參照完整性 <- 修改外碼值 拒絕
刪除元組 -> 可能破壞參照完整性 拒絕/級聯刪除/設定為空值
修改主碼值 -> 可能破環參照完整性 拒絕/級聯修改/設定為空值
使用樣例:
CREATE TABLE SC
( Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
Grade SMALLINT,
PRIMARY KEY(Sno,Cno),
FOREIGN KEY (Sno) REFERENCES Student(Sno)
ON DELETE CASCADE //級聯刪除SC表中相應的元組
ON UPDATE CASCADE, //級聯更新SC表中相應的元組
FOREIGN KEY (Cno) REFERENCES Course(Cno)
ON DELETE NO ACTION
//當刪除course 表中的元組造成了與SC表不一致時拒絕刪除
ON UPDATE CASCADE
//當更新course表中的cno時,級聯更新SC表中相應的元組
);
使用者定義完整性檢查和違約處理:
- 屬性上的約束條件檢查和違約處理
插入元組或修改屬性的值時,關係資料庫管理系統檢查屬性上的約束條件是否被滿足,如果不滿足則操作被拒絕執行。
- 元組上的約束條件檢查和違約處理
插入元組或修改屬性的值時,關係資料庫管理系統檢查元組上的約束條件是否被滿足,如果不滿足則操作被拒絕執行
斷言
SQL中,可以使用 CREATE ASSERTION語句,通過宣告性斷言來指定更具一般性的約束。
可以定義涉及多個表的或聚集操作的比較複雜的完整性約束。
斷言建立以後,任何對斷言中所涉及的關係的操作都會觸發關係資料庫管理系統對斷言的檢查,任何使斷言不為真值的操作都會被拒絕執行
建立斷言的語句格式
CREATE ASSERTION<斷言名><CHECK 子句>
每個斷言都被賦予一個名字,<CHECK 子句>中的約束條件與WHERE子句的條件表示式類似。
刪除斷言的語句格式
DROP ASSERTION <斷言名>;
如果斷言很複雜,則系統在檢測和維護斷言的開銷較高,這是在使用斷言時應該注意的
觸發器
觸發器(Trigger)是使用者定義在關係表上的一類由事件驅動的特殊過程
觸發器儲存在資料庫伺服器中
任何使用者對錶的增、刪、改操作均由伺服器自動啟用相應的觸發器
觸發器可以實施更為複雜的檢查和操作,具有更精細和更強大的資料控制能力
CREATE TRIGGER語法格式
CREATE TRIGGER <觸發器名>
{BEFORE | AFTER} <觸發事件> ON <表名>
REFERENCING NEW|OLD ROW AS<變數>
FOR EACH {ROW | STATEMENT}
[WHEN <觸發條件>]<觸發動作體>
定義觸發器的語法說明
(1)表的擁有者才可以在表上建立觸發器
(2)觸發器名
觸發器名可以包含模式名,也可以不包含模式名
同一模式下,觸發器名必須是唯一的
觸發器名和表名必須在同一模式下
(3)表名
觸發器只能定義在基本表上,不能定義在檢視上
當基本表的資料發生變化時,將啟用定義在該表上相應觸發事件的觸發器
(4)觸發事件
觸發事件可以是INSERT、DELETE或UPDATE也可以是這幾個事件的組合還可以UPDATE OF<觸發列,...>,即進一步指明修改哪些列時啟用觸發器。
AFTER/BEFORE是觸發的時機
AFTER表示在觸發事件的操作執行之後啟用觸發器
BEFORE表示在觸發事件的操作執行之前啟用觸發器
(5)觸發器型別
①行級觸發器(FOR EACH ROW)
②語句級觸發器(FOR EACH STATEMENT)
例如,TEACHER表上建立一個AFTER UPDATE觸發器,觸發事件是UPDATE語句: UPDATE TEACHER SET Deptno=5;
假設表TEACHER有1000行
如果是語句級觸發器,那麼執行完該語句後,觸發動作只發生一次
如果是行級觸發器,觸發動作將執行1000次
(6)觸發條件
觸發器被啟用時,只有當觸發條件為真時觸發動作體才執行;否則觸發動作體不執行。
如果省略WHEN觸發條件,則觸發動作體在觸發器啟用後立即執行
(7)觸發動作體
觸發動作體可以是一個匿名PL/SQL過程塊也可以是對已建立儲存過程的呼叫
如果是行級觸發器,使用者都可以在過程體中使用NEW和OLD引用事件之後的新值和事件之前的舊值
如果是語句級觸發器,則不能在觸發動作體中使用NEW或OLD進行引用
如果觸發動作體執行失敗,啟用觸發器的事件就會終止執行,觸發器的目標表或觸發器可能影響的其他物件不發生任何變化
注意:不同的RDBMS產品觸發器語法各不相同
啟用觸發器
觸發器的執行,是由觸發事件啟用的,並由資料庫伺服器自動執行
一個數據表上可能定義了多個觸發器,遵循如下的執行順序:
(1) 執行該表上的BEFORE觸發器;
(2) 啟用觸發器的SQL語句;
(3) 執行該表上的AFTER觸發器。
刪除觸發器
刪除觸發器的SQL語法:DROP TRIGGER <觸發器名> ON <表名>;
觸發器必須是一個已經建立的觸發器,並且只能由具有相應許可權的使用者刪除。