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