完整性
數(shù)據(jù)庫(kù)的完整性(DB Integrity): 是指DBMS應(yīng)保證DB的一種特性 -- 在任何情況下的正確性, 有效性, 和一致性.
其包括:
- 廣義完整性: 泛指引起數(shù)據(jù)錯(cuò)誤可能性的問(wèn)題, 語(yǔ)義完整性, 并發(fā)控制, 安全控制, DB故障恢復(fù)等
- 狹義完整性: 專(zhuān)指語(yǔ)義完整性, DBMS通常的完整性管理機(jī)制與程序來(lái)處理語(yǔ)義完整性問(wèn)題.(本講專(zhuān)指語(yǔ)義完整性)
關(guān)系模型的完整性要求:
- 實(shí)體完整性: 主鍵不為空
- 參照完整性: 針對(duì)外鍵來(lái)說(shuō)的, 外鍵必須是空或其作為主鍵的某一個(gè)值
- 用戶(hù)自定義完整性: 即語(yǔ)義完整性
完整性管理避免用戶(hù)對(duì)數(shù)據(jù)庫(kù)的不正當(dāng)操作.
完整性約束條件的一般形式
Integrity Constraint ::= (O, P, A, R)
- O: 數(shù)據(jù)集合: 約束的對(duì)象, 列, 多列(元組), 元組集合
- P: 謂詞條件: 約束的條件
- A: 觸發(fā)條件
- R: 相應(yīng)動(dòng)作
數(shù)據(jù)庫(kù)完整性的分類(lèi)
按約束條件分類(lèi):
- 域完整性約束條件: 施加于某一列上(列 完整性)
- 關(guān)系完整性約束條件: 施加于關(guān)系/table上(表 完整性)
按約束來(lái)源分類(lèi)
- 結(jié)構(gòu)約束: 來(lái)自于模型的約束(函數(shù)依賴(lài), 主鍵約束, 外鍵約束, 數(shù)值是否可以為空)
- 內(nèi)容約束: 來(lái)自于用戶(hù)的約束(用戶(hù)自定義完整性, 元組或?qū)傩缘娜≈捣秶?
按約束狀態(tài)分類(lèi)
- 靜態(tài)約束: 要求DB在任一時(shí)候均滿(mǎn)足的約束
- 動(dòng)態(tài)約束: 要求DB從一個(gè)狀態(tài)轉(zhuǎn)變?yōu)榱硪粋€(gè)狀態(tài)時(shí)應(yīng)滿(mǎn)足的約束
利用SQL語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)庫(kù)的完整性
- 靜態(tài)約束:
- 列完整性: 域的完整性約束
- 表完整性: 關(guān)系完整性約束
- 動(dòng)態(tài)約束:
- 觸發(fā)器
靜態(tài)約束
靜態(tài)完整性約束: 在定義表的時(shí)候可以設(shè)置, 后期可以添加約束, 也可以撤銷(xiāo)約束(如果約束有名字的話(huà), 更方便撤銷(xiāo))
約束條件有:
-
not null
: 列值非空 -
constraint constraint_name
: 為約束命名, 便于以后撤銷(xiāo) -
unique
: 列值是唯一 -
primary key
: 主鍵 -
check (search_cond)
: 列值滿(mǎn)足條件, 條件只能使用當(dāng)前列值 -
references table_name [(colname)] [on delete {cascade | set null}]
: 引用另一表table_name的列colname的值舷手,如有on delete cascade(刪除)或on delete set null(設(shè)為null)語(yǔ)句盛末,則刪除被引用表的某列值v時(shí)翁脆,要將本表該列值為v的記錄刪除或列值更新為null歌粥;缺省為無(wú)操作
-- 列約束
-- 示例: 假定Ssex只能取{男, 女}, 年齡在1~150之間, D#是外鍵
create table Student(
`S#` char(8) not null unique,
Sname char(10),
Ssex char(10) constrain ctssex check (Ssex='男' or Ssex='女'),
Sage integer check(Sage>=1 and Sage<150),
`D#` char(2) references Dept(`D#`) on delete cascade,
Sclass char(6));
-- 表約束, 在最后 ","后面定義
-- 主鍵定義為S#
create table Student(
`S#` char(8) not null unique,
Sname char(10),
Ssex char(10) constrain ctssex check (Ssex='男' or Ssex='女'),
Sage integer check(Sage>=1 and Sage<150),
`D#` char(2) references Dept(`D#`) on delete cascade,
Sclass char(6), primary key(`S#`) );
-- 較為復(fù)雜的約束條件
create Table SC(
`S#` char(8) check(`S#` in (select `S#` from student)),
`C#` char(3) check( `C#` in (select `C#` from course)),
Score float(1) constraint ctscore check (Score>=0.0 and Score<=100.0));
還可以通過(guò)alter table實(shí)現(xiàn)對(duì)約束的控制(不展開(kāi))
add
drop
modify
斷言: 一個(gè)謂詞表達(dá)式, 它表達(dá)了希望數(shù)據(jù)庫(kù)總能滿(mǎn)足的條件.
create assertion <assertion-name> check <predicate>
當(dāng)一個(gè)斷言創(chuàng)建后, 系統(tǒng)將檢測(cè)其有效性, 并在每一次更新中測(cè)試更新是否違反該斷言.
斷言測(cè)試增加了數(shù)據(jù)庫(kù)維護(hù)的負(fù)擔(dān), 小心使用復(fù)雜的斷言.
(很少用.....)
動(dòng)態(tài)約束
動(dòng)態(tài)約束的實(shí)現(xiàn) --> 觸發(fā)器Trigger
Trigger 是一種過(guò)程完整性約束, 是一段程序, 在特定時(shí)刻觸發(fā)(xx前, xx后).
-- 示例1: 設(shè)計(jì)一個(gè)觸發(fā)器, 當(dāng)進(jìn)行Teacher表更新元組時(shí), 使其工資只能升, 不能降
create trigger teacher_chgsal before update of salary -- 表示在更新前的操作
on teacher
referencing new x, old y -- 對(duì)xx前后分別命名
for each row when (x.salary < y.salary)
begin
raise_application_error(-20003, 'invalid salary on update'); -- 該函數(shù)是Oracle的錯(cuò)誤處理函數(shù)
end;
-- 示例2: 假設(shè)student(`S#`, Sname, SumCourse), SumCourse為該同學(xué)已學(xué)習(xí)課程的門(mén)數(shù), 初始值為0,
-- 以后每選修一門(mén), 就自動(dòng)+1
create trigger sumc after insert on sc
reference new row newi
for each row
begin
update student set SumCourse = SumCourse + 1
where `S#` = :newi.`S#`; -- 更新前的row與更新后的row它們的`S#`一樣
end;
-- 示例3: 假設(shè)Student(`S#`, Sname, Sage, Ssex, Sclass)中某一學(xué)生要變更其主碼S#,
-- 此時(shí), 其選課記錄的`S#`也需要更改
create trigger `updateS#` after update of `S#` on student
referencing old oldi, new newi
for each row
begin
update sc set `S#`=newi.`S#` where `S#`=:old.`S#`;
end;
安全性
數(shù)據(jù)庫(kù)的安全性是指DBMS應(yīng)該保證的數(shù)據(jù)庫(kù)的一種特性(機(jī)制或手段): 免受非法, 非授權(quán)用戶(hù)的使用, 泄露, 更改或者破壞.
DBMS的安全機(jī)制
- 自主安全性機(jī)制: 存取控制(Access Control)
- 強(qiáng)制安全性機(jī)制: 通過(guò)對(duì)數(shù)據(jù)和用戶(hù)強(qiáng)制分類(lèi), 使得不同的用戶(hù)能夠訪問(wèn)不同類(lèi)別的數(shù)據(jù)
自主安全性
- 授權(quán)者
- 授權(quán)
兩種控制示例:
- 按名稱(chēng)控制安全性: 存儲(chǔ)矩陣
- 視圖
- 視圖是安全性控制的重要手段
- 通過(guò)視圖可以限制用戶(hù)對(duì)關(guān)系中某些數(shù)據(jù)項(xiàng)的存取(只提供局部信息給用戶(hù)而達(dá)到目的)
- 通過(guò)視圖和存儲(chǔ)矩陣結(jié)合起來(lái), 進(jìn)行有效的安全性控制
利用SQL語(yǔ)言實(shí)現(xiàn)數(shù)據(jù)庫(kù)自主安全性控制
SQL語(yǔ)言包括DDL, DML和DCL, 數(shù)據(jù)庫(kù)安全性控制屬于DCL范疇.
3個(gè)級(jí)別大小(級(jí)別高自動(dòng)包含級(jí)別低的):
- 級(jí)別1, Select: 讀
- 級(jí)別2, Modify: 更新(插入, 更新, 刪除元組)
- 級(jí)別3, Create: 創(chuàng)建(創(chuàng)建表空間, 模式, 表, 索引, 視圖等)
超級(jí)用戶(hù)(DBA) --> 賬戶(hù)級(jí)別(程序員用戶(hù)) --> 關(guān)系級(jí)別(普通用戶(hù))
級(jí)別1,2是關(guān)系級(jí)別的權(quán)利, 級(jí)別3稱(chēng)為賬戶(hù)級(jí)別的權(quán)利
-- 示例, 假定高級(jí)領(lǐng)導(dǎo)是Emp0001, 部門(mén)領(lǐng)導(dǎo)Emp0021, 員工管理員為Emp2001, 收發(fā)員為Emp5001(均為UserId, 也即員工的`P#`)
grant all priviledages on Employee to Emp2001; -- 授予賬戶(hù)級(jí)別
grant select on EmpV2 to Emp5001;
grant select on EmpV3 to public;
grant select on EmpV4 to Emp0021;
-- 授權(quán) 權(quán)利 on 表或者視圖 to 用戶(hù)
-- 收回授權(quán)
revoke select on employee from UserB;
自主安全性的問(wèn)題
權(quán)利的傳播
grant select on Employee to UserB with grant option;
grant select on Employee to UserC with grant option;
傳播的范圍包括:
- 水平傳播數(shù)量
- 垂直傳播數(shù)量
傳播范圍具體是多少, SQL標(biāo)準(zhǔn)中也沒(méi)有限制, 看各種系統(tǒng)本身的控制.
存在的問(wèn)題:
當(dāng)一個(gè)用戶(hù)被多次授權(quán), 則會(huì)導(dǎo)致某一個(gè)用戶(hù)回收權(quán)限時(shí)該用戶(hù)仍然保留有權(quán)限.
強(qiáng)制安全性
- 強(qiáng)制安全性對(duì)數(shù)據(jù)對(duì)象進(jìn)行安全性分級(jí):
絕密(T
opS
ecret), 機(jī)密(S
ecret), 可信(C
onfidential)和無(wú)分類(lèi)(U
nclassified) - 同時(shí)也對(duì)用戶(hù)進(jìn)行上述的安全性分級(jí)
- 從而強(qiáng)制實(shí)現(xiàn)不同級(jí)別用戶(hù)訪問(wèn)不同級(jí)別數(shù)據(jù)的一種機(jī)制
與自主安全性的區(qū)別: 可能出現(xiàn)多重實(shí)例, 多級(jí)關(guān)系完整性等新問(wèn)題