數(shù)據(jù)庫完整性 為了維護(hù)數(shù)據(jù)庫完整性DBMS需要提供: 1. 提供定義完整性約束條件的機(jī)制 2. 提供完整性檢查方法:一般在INSERT UPDATE DELETE語句執(zhí)行后開始檢查或者在事物提交之前進(jìn)行檢查 3. 違約處理機(jī)制:比如拒絕,級(jí)聯(lián)或者其他操作 實(shí)體完整性 用PRIMARY
為了維護(hù)數(shù)據(jù)庫完整性DBMS需要提供:
1. 提供定義完整性約束條件的機(jī)制
2. 提供完整性檢查方法:一般在INSERT UPDATE DELETE語句執(zhí)行后開始檢查或者在事物提交之前進(jìn)行檢查
3. 違約處理機(jī)制:比如拒絕,級(jí)聯(lián)或者其他操作
用PRIMARY KEY進(jìn)行定義,對(duì)于單屬性,實(shí)體完整性可以定義為列級(jí)約束也可以定義為表級(jí)約束;對(duì)于多個(gè)屬性構(gòu)成的碼,只能定義為表級(jí)約束。
例如:
定義為列級(jí)約束(列級(jí)主碼)
CREATE TABLE S(
Sno CHAR(9) PRIMARY KEY,
Sname CHAR(20) NOT NULL,
.....
);
定義為表級(jí)約束(表級(jí)主碼)
CREATE TABLE S(
Sno CHAR(9) ,
Sname CHAR(20) NOT NULL,
.....
PRIMARY KEY(Sno)
);
檢查和違約處理:
1. 檢查主碼值是否唯一,如果不唯一就拒絕插入或者修改(全表掃描或者在DBMS為主碼建立的索引上進(jìn)行查找,例如B+樹索引)
2. 檢查主碼值對(duì)應(yīng)的各個(gè)屬性是否為空,如果存在為空的屬性,那么拒絕插入或者修改
在創(chuàng)建表的時(shí)候使用FOREIGN KEY 定義外碼,用REFERENCES短語指定這些外碼參照哪些表的主碼。和主碼類似,外碼也同樣可以定義表級(jí)和列級(jí)參照完整性。不過感覺沒什么區(qū)別
例如:
CREATE TABLE SC(
Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
.....
PRIMARY KEY(Sno, Cno),
FOREIGN KEY (Sno) REFERENCES Sudent(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno),
);
破壞參照完整性的情形以及違約處理:
1. SC表中插入一個(gè)元組但是該元組的Sno屬性在被參照表Student中是不存在的
2. SC表中更新一個(gè)元組但是該元組的Sno屬性在被參照表Student中是不存在的
3. Student表中刪除一個(gè)元組,導(dǎo)致參照表SC中某些元組的Sno在Student表中不存在
4. Student表中更新一個(gè)元組,導(dǎo)致參照表SC中某些元組的Sno在Student表中不存在
發(fā)生不一致的時(shí)候一般采取的措施是:
1. 拒絕執(zhí)行
2. 級(jí)聯(lián)操作:刪除或者修改被參照表導(dǎo)致不滿足參照完整性的時(shí)候,級(jí)聯(lián)刪除慘遭表中所有的不一致元組
3. 設(shè)置空值(這也引起一個(gè)問題就是在定義外碼的時(shí)候是否允許外碼列為空,如果不允許為空,那么就不能按3來處理)
至于采用哪種處理策略,可以在建表的時(shí)候顯式指定
CREATE TABLE SC(
Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
.....
PRIMARY KEY(Sno, Cno),
FOREIGN KEY (Sno) REFERENCES Sudent(Sno)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (Cno) REFERENCES Course(Cno)
ON DELETE NO ACTION
ON UPDATE CASCADE,
);
根據(jù)具體應(yīng)用而定義的數(shù)據(jù)必須滿足的語義要求。分類:
CREATE TABLE SC(
Sno CHAR(9) UNIQUE,
Cno CHAR(4) NOT NULL,
Grade SMALLINT CHECK(Grade >=0 AND Grade <=100),
.....
PRIMARY KEY(Sno, Cno),
FOREIGN KEY (Sno) REFERENCES Sudent(Sno),
FOREIGN KEY (Cno) REFERENCES Course(Cno),
);
和前面一樣,用戶自定義完整性同樣是可以定義為列級(jí)限制也可以定義為表級(jí)限制。入上述例子就是列級(jí)用戶自定義完整性,表級(jí)用戶自定義完整新如下:
CREATE TABLE Student(
Sno CHAR(9) UNIQUE,
Sname CHAR(8) NOT NULL,
Ssex CHAR(2),
.....
PRIMARY KEY(Sno),
CHECK (Ssex = '女' OR Sname NOT LIKE 'Ms.%')
);
兩者的區(qū)別是表級(jí)限制可以定義不同屬性取值之間的限制。如上述的例子中定義了性別屬性以及姓名屬性兩者之間的約束。
約束檢查和違約處理:
一般采用拒絕執(zhí)行的方式處理。
除了直接使用上述的3中完整性約束之外,SQL還提供了CONSTRAINT完整性約束命名子句,用來對(duì)完整性約束條件命名,以方便增加和刪除完整性約束。
完整性命名子句的定義:
直接看例子:
CREATE TABLE Student(
Sno NUMERIC(6)
CONSTRAINT C1 CHECK(Sno BETWEEN 90000 AND 99999),
Sname CHAR(8)
CONSTRAINT C2 NOT NULL,
Sage NUMERIC(3)
CONSTRAINT C3 CHECK(Sage < 30),
Ssex CHAR(2)
CONSTRAINT C4 CHECK(Ssex IN ('男', '女')),
.....
CONSTRAINT StudentKey PRIMARY KEY(Sno)
);
完整性命名子句的修改:
直接刪除并重新定義即可
ALTER TABLE Student
DROP CONSTRAINT C1;
ALTER TABLE Student
ADD CONSTRAINT C1 CHECK(Sno BETWEEN 900000 AND 9999999);
觸發(fā)器是用戶定義在關(guān)系表上的一類由事件驅(qū)動(dòng)的特殊過程。定義之后,任何用戶對(duì)數(shù)據(jù)庫的增刪該操作均由DBMS自動(dòng)激活相應(yīng)的觸發(fā)器。觸發(fā)器類似于約束但是比約束更加靈活。可以實(shí)現(xiàn)比foreign key check約束更為復(fù)雜的檢查和操作,具有更加精細(xì)和強(qiáng)大的數(shù)據(jù)控制能力。
觸發(fā)器實(shí)例:
CREATE TABLE Sql_log(
Eno NUMERIC(4) REFERENCE teacher(Eno),
Sal NUMERIC(7, 2),
Username CHAR(10),
Date TIMESTAMP
);
CREATE TRIGGER Insert_Sal
AFTER INSERT ON Teacher
FOR EACH ROW
AS BEGIN
INSERT INTO Sal_log VALUES(new.Eno, new.Sal, CURRENT_USER, CURRENT_TIMESTAMP);
END;
CREATE TRIGGER Update_Sal
AFTER UPDATE ON Teacher
FOR EACH ROW
AS BEGIN
IF(new.Sal <> old.Sal) THEN INSERT INTO Sal_log VALUES(new.Eno, new.Sal, CURRENT_USER, CURRENT_TIMESTAMP);
END IF;
END;
注意:
1. 表的擁有者才可以創(chuàng)建該表的觸發(fā)器
2. 觸發(fā)事件可以使INSERT / DELETE /UPDATE也可以是三者的組合
3. 行級(jí)觸發(fā)器
同一個(gè)表上的觸發(fā)器激活順序:
1. 執(zhí)行before觸發(fā)器-同一個(gè)表上的多個(gè)before觸發(fā)器按定義順序執(zhí)行
2. 激活觸發(fā)器的sql語句
3. 觸發(fā)器被激活之后,只有當(dāng)觸發(fā)條件為真的時(shí)候才執(zhí)行觸發(fā)動(dòng)作體。如果省略when觸發(fā)條件,那么觸發(fā)動(dòng)作體在觸發(fā)器被激活之后立刻執(zhí)行
4. 觸發(fā)動(dòng)作體既可以是一個(gè)匿名SQL語句也可以是對(duì)已經(jīng)創(chuàng)建的存儲(chǔ)過程的調(diào)用。
觸發(fā)器的刪除:
被刪除的觸發(fā)器必須是一個(gè)已經(jīng)創(chuàng)建的觸發(fā)器,而且刪除者也必須有相應(yīng)的用戶權(quán)限。
DROP TRIGGER Insert_Sql ON Teacher;
觸發(fā)器分為事前觸發(fā)和事后觸發(fā),兩者的區(qū)別?行級(jí)觸發(fā)(FOR EACH ROW)和語句級(jí)觸發(fā)( FOR EACH STATEMENT)的區(qū)別是什么?
事前觸發(fā)發(fā)生在事件發(fā)生之前,用驗(yàn)證一些條件或者準(zhǔn)備工作;事后觸發(fā)發(fā)生在事件發(fā)生之后,做收尾工作。事前觸發(fā)可以獲取之前的值old和新值new,事后觸發(fā)可以保證事務(wù)的完整性。
語句級(jí)觸發(fā)可以在語句執(zhí)行之前或者執(zhí)行之后進(jìn)行,一般只執(zhí)行一次,而行級(jí)觸發(fā),觸事件根據(jù)被影響的行的數(shù)量,一般會(huì)執(zhí)行多次。同時(shí),行級(jí)觸發(fā)器可以使用new 和old來引用update/insert事件執(zhí)行前后的值,但是語句級(jí)觸發(fā)是不行的。
范式就是符合一定的級(jí)別的關(guān)系模式的集合,一般有1NF 2NF 3NF BCNF 4NF
1NF是指滿足數(shù)據(jù)庫中的每一列都是不可再分的基本數(shù)據(jù)項(xiàng),是數(shù)據(jù)庫最基本的要求(同一列中不能有多個(gè)值或者出現(xiàn)重復(fù)屬性)。
2NF是在1NF的基礎(chǔ)上,消除了每一個(gè)非主屬性的部分函數(shù)依賴。通俗的講就是要求數(shù)據(jù)庫中的每一行或者每一個(gè)實(shí)例是可以唯一的被區(qū)分開(不存在多種區(qū)分方式,也就沒有了部分函數(shù)依賴)。
3NF 是在2NF的基礎(chǔ)上消除了非主屬性的傳遞函數(shù)依賴。
BCNF在3NF的基礎(chǔ)上又消除了主屬性對(duì)碼的傳遞依賴和部分依賴,也就是說BCNF消除了任何屬性(包括主屬性和非主屬性)對(duì)碼的部分依賴和傳遞依賴。
一個(gè)特殊的BCNF例子就是全碼,顯然全碼不存在非主屬性,因此至少是3NF,而且全碼也不存在傳遞和部分依賴,所以也是BCNF
BCNF是函數(shù)依賴范圍內(nèi)的最佳優(yōu)化,基本消除了插入和刪除異常,但是對(duì)多值依賴范圍內(nèi)是無效的。
4NF限制關(guān)系模式的屬性之間不存在非平凡且非函數(shù)依賴的多值依賴(唯一允許的非平凡多值依賴是函數(shù)依賴)。
涉及到的概念:多值依賴,平凡多值依賴,函數(shù)依賴等等,直接找本書看看就可以了,確實(shí)抽象了一點(diǎn)點(diǎn)。
在多值依賴范圍內(nèi),4NF已經(jīng)是優(yōu)化程度最高的。
規(guī)范化過程:
1NF消除非主屬性的部分函數(shù)依賴->2NF消除非主屬性的函數(shù)依賴->3NF消除主屬性的部分函數(shù)依賴和傳遞函數(shù)依賴->BCNF消除非平凡且非函數(shù)依賴的多值依賴->4NF
視圖是從一個(gè)或者多個(gè)基本表中導(dǎo)出的表,數(shù)據(jù)庫中值存放視圖的定義而不存放對(duì)應(yīng)視圖的數(shù)據(jù)。視圖被定義之后就可以和基本表一樣被查詢和刪除,同時(shí)在視圖之上還可以繼續(xù)定義視圖。對(duì)視圖的更新操作(增刪改)是有一定的限制
視圖的定義:
CREATE VIEW IS_Student
AS
SELECT Sno, Sname, Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION;
WITH CHECK OPTION表示對(duì)數(shù)據(jù)進(jìn)行更新update insert delete操作的時(shí)候需要保證更新操作滿足定義視圖中的謂詞條件。也就是AS之后的子查詢。
此外,組成視圖的屬性列名要么全部省略要么全部指定,必須指定列名的情形:1)目標(biāo)列是聚集函數(shù)或者是列表達(dá)式 2)多表連接時(shí)選擇了同名列作為視圖的字段 3)需要在視圖中定義更合適的名字。
如上述的實(shí)例,所創(chuàng)建的視圖僅僅是從一個(gè)基本表中導(dǎo)出,去掉了基本表的某些行某些列但是保留了主碼,此類視圖稱為是行列子集視圖。
CREATE VIEW BT_S(Sno, Sname, Sbirth)
AS
SELECT Sno, Sname, 2016-Sage
FROM Student
在視圖中的數(shù)據(jù)是不存儲(chǔ)的,有些時(shí)候,視圖中的列是經(jīng)過基本表派生出來的,這些派生列由于在數(shù)據(jù)庫中并不存儲(chǔ),因此被稱為是虛擬列。帶虛擬列的視圖也被稱為是帶表達(dá)式的視圖;
CREATE VIEW S_G(Sno, Gavg)
AS
SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno;
使用聚集函數(shù)和GROUP BY子句的查詢來定義的視圖被稱為是分組視圖。
行列子集視圖是可以更新的,但是分組視圖和帶表達(dá)式的視圖一般是不可更新的。
視圖的刪除,一般刪除和級(jí)聯(lián)刪除。級(jí)聯(lián)刪除的時(shí)候,基于本視圖而定義的視圖也被刪除。
視圖消解:在進(jìn)行基于視圖的查詢的時(shí)候,首先會(huì)進(jìn)行有效性檢查,通過之后,把定義的子查詢和用于的查詢結(jié)合起來,轉(zhuǎn)化為等價(jià)的基本表的查詢,最后執(zhí)行修正了的查詢。該轉(zhuǎn)換過程就稱為是視圖消解。
視圖消解并不一定總是成功的,尤其是非行列子集視圖,因此這類視圖的查詢盡量直接基于基本表進(jìn)行。
對(duì)視圖的更新也是基于視圖消解進(jìn)行的,而且視圖的更新要求更加嚴(yán)格,除了行列子集視圖是可以直接更新之外,其他視圖有些視圖理論上就被證明是無法更新的。
視圖的作用:
1. 簡化用戶操作
2. 使用戶能夠以多種角度看待同一數(shù)據(jù)
3. 視圖對(duì)于重構(gòu)數(shù)據(jù)庫提供了一定程度的邏輯獨(dú)立性
4. 視圖可以對(duì)機(jī)密數(shù)據(jù)提供安全保護(hù)
5. 適當(dāng)?shù)囊晥D可以實(shí)現(xiàn)更加清晰簡潔的查詢
事務(wù)是指用戶定義的一個(gè)數(shù)據(jù)庫操作序列,這些操作序列是一個(gè)不可分割的工作單位,要么全做要么全不做。事務(wù)的開始和結(jié)束可以由用戶進(jìn)行顯示的定義和控制,如果沒有定義事務(wù),那么由DBMS按缺省規(guī)定自動(dòng)劃分事務(wù)。
事務(wù)的特性:
1. 原子性
2. 一致性:事務(wù)的執(zhí)行時(shí)使數(shù)據(jù)庫從一個(gè)一致性狀態(tài)到達(dá)另外一個(gè)一致性狀態(tài)
3. 隔離性:一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)于其他并發(fā)執(zhí)行的事務(wù)而言是隔離的,也就是并發(fā)執(zhí)行的各個(gè)事務(wù)之間是互不干擾的。
4. 持續(xù)性:一個(gè)事務(wù)一旦提交,對(duì)于數(shù)九的更改就是永久的。接下來的事務(wù)或者故障不應(yīng)對(duì)其產(chǎn)生影響
事務(wù)是恢復(fù)和并發(fā)控制的基本單位
可能破壞ACID特性的場(chǎng)景:
1. 多個(gè)事務(wù)并發(fā)執(zhí)行,不同的事務(wù)出現(xiàn)交叉
2. 事務(wù)在運(yùn)行過程中被強(qiáng)行停止
一個(gè)查詢中涉及多個(gè)表,該查詢稱為是連接查詢。包括等值連接查詢,自然連接查詢,非等值連接查詢,自身連接查詢,外連接查詢和符合條件連接查詢。
當(dāng)連接運(yùn)算符為’=’的時(shí)候,稱為是等值連接,其他都是非等值連接。在等值連接中,將目標(biāo)列中的重復(fù)的去掉,稱為是自然連接。
查詢中的連接如果是一個(gè)表與自身進(jìn)行連接,稱為是自身連接。
通常的查詢中,只有滿足連接條件的元組才會(huì)輸出,如果在插敘中將主體表中不滿足條件的元組一并輸出,并且在不滿足條件的列上填NULL,這種類型的連接稱為是外連接。根據(jù)主體表的選擇的不同,尅分為左外連接(主體表為左邊關(guān)系,輸出左邊關(guān)系中不滿足連接條件的列)和右外連接(主體表為右邊關(guān)系,輸出右邊關(guān)系中不滿足連接條件的列)。
如果where子句中,有多個(gè)條件(連接條件或者其他限定條件),稱為復(fù)合條件連接。
例如:
SELECT Student.Sno, Sname
FROM Student, SC
WHERE Student.Sno=SC.Sno AND SC.Cno='2' AND SC.Grade>90;
連接可以使兩個(gè)表之間,也可以是多個(gè)表之間,多表之間的連接稱為是多表連接。
SQL的執(zhí)行需要先進(jìn)行編譯然后才可以執(zhí)行。大型DBMS為了提高效率,將完成特定功能的SQL語句進(jìn)行編譯優(yōu)化,存儲(chǔ)在數(shù)據(jù)庫服務(wù)器中,用戶可以通過指定存儲(chǔ)過程的名字來調(diào)用執(zhí)行。
創(chuàng)建:
create procedure pro_name @ [參數(shù)名] [類型]
as
begin
….
end
調(diào)用: exec pro_name [參數(shù)名]
刪除: drop procedure pro_name
存儲(chǔ)過程可以增強(qiáng)SQL語言的功能和靈活性,因?yàn)榭梢允褂昧鞒炭刂普Z句編寫,所以具有很強(qiáng)的靈活性,可以用于實(shí)現(xiàn)復(fù)雜的判斷和運(yùn)算。存儲(chǔ)過程不是函數(shù),兩者的區(qū)別:
1. 存儲(chǔ)過程可以作為獨(dú)立的部分執(zhí)行,而函數(shù)可以作為查詢語句的一部分被調(diào)用
2. 存儲(chǔ)過程一般實(shí)現(xiàn)的功能比較復(fù)雜,而函數(shù)實(shí)現(xiàn)的比較有針對(duì)性
3. 函數(shù)可以嵌套在SQL中,也可以在select中使用,而存儲(chǔ)過程不可以
4. 函數(shù)不可以操作實(shí)體表,只能操作內(nèi)建表
5. 存儲(chǔ)過程創(chuàng)建的時(shí)候就在服務(wù)器上進(jìn)行了編譯,所以速度比較快
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com