學習數據庫概論第六天

第五章

數據庫的完整性是指數據的正確性和相容性。數據的正確性是指數據是符合現實世界語義、反映當前實際狀況的,數據的相容性是指數據庫同一對象在不同關係表中的數據是符合邏輯的。
數據的完整性是爲了防止數據庫中存在不符合語義的數據,也就是防止數據庫中存在不正確的護數據。數據的安全性是保護數據庫防止惡意破壞和非法存取。因此,完整性檢查和控制的防範對象是不合語義的、不正確的數據,防止它們進入數據庫。安全性控制的防範對象是非法用戶和非法操作,防止他們對數據庫數據的非法存取。

爲維護數據庫完整性,數據庫管理系統必須實現:
1.提供定義完整性約束條件的機制
完整性約束條件也稱爲完整性規則,是數據庫中數據必須滿足的語義約束條件。它表達了給定的數據模型中數據及其聯繫所具有的制約和依存規則,用以限定符合數據模型的數據庫狀態以及狀態的變化,以保證數據的正確、有效和相容。如關係模型的實體完整性、參照完整性和用戶定義完整性。
2.提供完整性檢查的方法
數據庫管理系統中檢查數據是否滿足完整性約束條件的機制稱爲完整性檢查。一般在insert、update/delete語句執行後開始檢查,也可以在事務提交時檢查。
3.進行違約處理

5.1實體完整性

1.定義實體完整性
對單屬性有兩種說明方法,一種是列級約束條件,另一種是定義爲表級約束條件。對多個屬性只有一種說明方法,即定義爲表級約束條件。
例5.1 將Student表中的Sno屬性定義爲碼。
create table Student
(Sno char(9) primary key,
Sname char(20) not null,
Ssex char(2),
Sage smallint,
Sdept char(20)
);
例5.2 將SC表中的Sno、Cno屬性組定義爲碼。
Create table SC
(Sno char(9),
Sname char(20),
Ssex char(2),
Sage smallint,
Sdept char(20),
Primary key(Sno,Cno)
);
2.實體完整性檢查和違約處理
用primary key定義關係的主碼後每當用戶程序對基本表插入一條記錄或對主碼列進行更新操作時,關係數據庫管理系統的實體完整性規則自動進行檢查。包括:
(1)檢查主碼值是否唯一,如果不唯一則拒絕插入或修改。
(2)檢查主碼的各個屬性是否爲空,只要有一個爲空就拒絕插入或修改。
從而保證了實體完整性。

5.2參照完整性

1.定義參照完整性
關係模型的參照完整性在create table中用foreign key短語定義定義哪些列爲外碼,用references短語指明這些外碼參照哪些表的主碼。
例5.3 定義SC中的參照完整性
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)
);
2.參照完整性檢查和違約處理
(1)SC表中增加一個元組,該元組的Sno屬性值在表Student中找不到一個元組,其Sno屬性值與之相等。
(2)修改SC表中的一個元組,修改後該元組的Sno屬性值在表Student中找不到一個元組,其Sno屬性值與之相等。
(3)從Student表中刪除一個元組,造成SC表中某些元組的Sno屬性值在表Student中找不到一個元組,其Sno屬性值與之相等。
(4)修改Student表中一個元組的Sno屬性,造成SC表中某些元組的Sno屬性值在表Student中找不到一個元組,其Sno屬性值與之相等。
當上述額不一致發生時,系統可以採用以下策略。
(1)拒絕(no action)執行
不允許該操作執行。該策略一般設置爲默認策略。
(2)級聯(cascade)操作
(3)設置爲空值
例5.4 顯示說明參照完整性的違約處理示例。
Create table SC
(Sno char(9),
Cno char(4),
Grade smallint,
Primary key(Sno,Cno),
Foreign key(Sno) references Student(Sno)
On delete cascade
On update cascade,
Foreign key(Cno) references Course(Cno)
On delete no action
On update cascade
);

5.3用戶定義的完整性

1.屬性上的約束條件
可以根據應用要求定義屬性上的約束條件,即屬性值限制,包括:
列值非空(not null)
列值唯一(unique)
檢查列值是否滿足一個條件表達式(check短語)。
(1)不允許取空值
例5.5 在定義SC表時,說明Sno、Cno、Grade屬性不允許取空值。
Create table SC
(Sno char(9) not null,
Cno char(4) not null,
Grade smallint not null,
Primary key(Sno,Cno)
);
(2)列值唯一
(3)用check短語指定列值應該滿足的條件
例5.7 Student表的Ssex只允許取“男”或“女”。
Create table Student
(Sno char(9) primary key,
Sname char(8) not null,
Ssex char(2) check(Ssex in (‘男’,’女’)),
Sage smallint,
Sdept char(20)
);
例5.8 SC表的Grade的值應該在0和100之間。
Create table SC
(Sno char(9),
Cno char(4),
Grade smallint check(Grade>=0 and Grade<=100),
Primary key(Sno,Cno),
Foreign key(Sno) references Student(Sno),
Foreign key(Cno) references Course(Cno)
);
2.元組上的約束條件
同屬性值限制相比,元組級的限制可以設置不同屬性之間的取值的相互約束條件。
例5.9 當學生的性別是男時,其名字不能以Ms.打頭。
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.%’)
);

5.4完整性約束命名子句

SQL在create table語句中提供了完整性約束命名子句constraint,用來對完整性約束條件命名,從而可以靈活地增加、刪除一個完整性約束條件。
1.完整性約束命名子句
Constraint 完整性約束條件名 完整性約束條件
完整性約束條件包括not null、unique、primary key、foreign key、check短語等。
例5.10 建立學生登記表Student,要求學號在90000-99999之間,姓名不能取空值,年齡小於30,性別只能是“男”或“女”。
Create table Student
(Sno numeric(6)
Constraint C1 check(Sno between 90000 and 99999),
Sname char(20)
Constraint C2 not null,
Sage numeric(3)
Constraint C3 check(Sage<30),
Ssex char(2)
Constraint C4 check(Ssex in (‘男’,’女’),
Constraint Student primary key(Sno)
);
2.修改表中的完整性限制
例5.12 去掉Student表中對性別的限制。
Alter table Student
Drop constraint C4;
例5.13 修改表Student中的約束條件,要求學號改爲在900000-999999之間,年齡由小於30改爲小於40.
Alter table Student
Drop constraint C1;
Alter table Student
Add contraint C1 check(Sno>=900000 and Sno<=999999);
Alter table Student
Drop contraint C3;
Alter table Student
Add contraint C3 check(Sage<40);

5.6斷言

在SQL中可以使用數據定義語言中的create assertion語句,通過聲明性斷言來指定更具一般性的約束。可以定義涉及多個表或聚集操作的比較複雜的完整性約束。斷言創建以後,任何對斷言中涉及關係的操作都會觸發關係數據庫管理系統對斷言的檢查,任何使斷言不爲真值的操作都會被拒絕執行。
1.創建斷言的語句格式
Create assertion斷言名 check子句
每個斷言都被賦予一個名字,check子句中的約束條件與where子句的條件表達式類似。
例5.18 限制數據庫課程最多60名學生選修。
Create assertion ASSE_SC_DB_NUM
Check(60>=(select count()
From Course,SC
Where Course.Cno=SC.Cno and Cname=’數據庫’) );
例5.19 限制每一門課程最多60名學生選修。
Create assertion ASSE_SC_CNUM1
Check(60>=all(select count(
)
From SC
Group by Cno));
2.刪除斷言的語句格式
Drop assertion 斷言名

5.7觸發器

觸發器是用戶定義在關係表上的一類由事件驅動的特殊過程。一旦定義,觸發器將被保存在數據庫服務器中。任何用戶對錶的增、刪、改操作均由服務器自動激活相應的觸發器,在關係數據庫管理系統核心層進行集中的完整性控制。
1.定義觸發器
觸發器又叫事件-條件-動作規則。當特定的系統事件(如對一個表的增、刪、改操作,事務的結束等)發生時,對規則的條件進行檢查,如果條件成立則執行規則中的動作,否則不執行該動作。
Create trigger 觸發器名
Before|after 觸發事件 on 表名
Referencing new|old row as 變量
For each row|statement
[When 觸發條件 觸發動作體]

(1)只有表的擁有者,即創建表的用戶纔可以在表上創建觸發器,並且一個表上只能創建一定數量的觸發器。觸發器的具體數量由具體的關係數據庫管理系統在設計時確定。
(2)觸發器名
觸發器名可以包含模式名,也可以不包含模式名。同一模式下,觸發器名必須是唯一的,並且觸發器名和表名必須在同一模式下。
(3)表名
觸發器只能定義在基本表上,不能定義在視圖上。當基本表的數據發生變化時,將激活定義在該表上相應觸發事件的觸發器,因此該表也稱爲觸發器的目標表。
(4)觸發事件
觸發事件可以是insert、delete或update,也可以是這幾個事件的組合,如insert or delete等,還可以是update of觸發列,…,即進一步指明修改哪些列時激活觸發器。Before|after是觸發時機。Before表示在觸發事件的操作執行之前激活觸發器,after表示在觸發事件的操作執行之後激活觸發器。
(5)觸發器類型
觸發器按照所觸發動作的間隔尺寸可以分爲行級觸發器(for each row)和語句級觸發器(for each statement)
(6)觸發條件
觸發器被激活時,只有當觸發條件爲真時觸發動作體才執行,否則觸發動作體不執行。如果省略when觸發條件,則觸發動作體在觸發器激活後立即執行。
(7)觸發動作體
觸發動作體既可以是一個匿名PL/SQL過程塊,也可以是對已創建存儲過程的調用。如果是行級觸發器,用戶可以在過程體中使用NEW和OLD引用update/insert事件之後的新值和update/delete事件之前的舊值,如果是語句級觸發器,則不能在觸發動作體中使用new或old進行引用。
如果觸發動作體執行失敗,激活觸發器的事件(即對數據庫的增、刪、改操作)就會終止執行,觸發器的目標表或觸發器可能影響的其他對象不發生任何變化。
例5.21 當對錶SC的Grade屬性進行修改時,若分數增加了10%,則將此次操作記錄在另一個表SC_U(Sno、Cno、Oldgrade、Newgrade)中,其中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.1oldtuple.Grade)
Insert into SC_U(Sno,Cno,Oldgrade,Newgrade)
Values(oldtuple.Sno,oldtuple.Cno,oldtuple.Grade,newtuple.Grade)
例5.22 將每次對錶Student的插入操作所增加的學生個數記錄到表的Student-InsertLog中。
Create trigger Student_Count
After insert on Student
Referencing
Newtable as delta
For each statement
Insert into Studnet-InsertLog(Numbers)
Select count(
) from delta
例5.23 定義一個before行級觸發器,爲教師表Teacher定義完整性規則“教授的工資不得低於4000元,如果低於4000元,自動改爲4000元”。
Create trigger Insert_Or_Update_Sal
Before insert or update on Teacher
Referencing newrow as newtuple
For each row
Begin
If(newtuple.Job=’教授’) and(newtuple.Sal<4000)
Then newtuple.Sal:=4000;
End if;
End;
2.激活觸發器
觸發器的執行是由觸發事件激活,並由數據庫服務器自動執行的。一個數據表上可能定義多個觸發器。
3.刪除觸發器
Drop trigger 觸發器名 on 表名;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章