寫在前面:本篇博客大部分內(nèi)容參考數(shù)據(jù)庫系統(tǒng)概念(本科教學(xué)版)第四章(第三章的多表部分會挪到這一部分講)
筆者接下來的代碼示例會主要在SQL Server數(shù)據(jù)庫中測試
在開始今天的摸魚大業(yè)之前,讓我們繼續(xù)延用之前用的表(′`)
BONUS.png
DEPT.png
EMP.png
SALGRADE.png
視圖
首先還是來談?wù)劰P者對視圖概念的理解吧趾诗,在筆者看來視圖這個數(shù)據(jù)庫對象在不考慮物化的情況下就是一張?zhí)摫恚旧頉]有實(shí)際的數(shù)據(jù),但是可以利用視圖在某個視角下觀察一張或多張表的數(shù)據(jù)鬼廓。所有對視圖的操作最后都將轉(zhuǎn)成對表的操作
-
視圖定義(創(chuàng)建一個視圖)
- 格式:
CREATE VIEW 視圖名 AS 子查詢
- 舉個栗子:
-- 下面的語句創(chuàng)建了一個簡單的視圖temp_view,其中包含員工名以及其所在部門名兩個字段 CREATE VIEW temp_view AS SELECT e.ENAME, d.DNAME FROM EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO;
- 接下來我們對上面創(chuàng)建的視圖進(jìn)行查詢操作
SELECT * FROM temp_view;
得到如下結(jié)果:
1.png -
數(shù)據(jù)庫只存儲視圖的定義本身
- 視圖通常是這樣來實(shí)現(xiàn)的:當(dāng)我們定義一個視圖的時候致盟,數(shù)據(jù)庫系統(tǒng)就吧這個視圖的定義(其實(shí)就是一個子查詢語句)本身存儲下來碎税,一旦我們使用這個視圖,數(shù)據(jù)庫系統(tǒng)就會用定義中的查詢語句替換視圖
- 舉個栗子
-- 我們繼續(xù)沿用上面定義的視圖temp_view馏锡,它的定義是這樣的 CREATE VIEW temp_view AS SELECT e.ENAME, d.DNAME FROM EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO; -- 則對視圖的查詢操作可以作下面的等價(下面兩個查詢語句是等價的) SELECT * FROM temp_view; SELECT * FROM (SELECT e.ENAME, d.DNAME FROM EMP e JOIN DEPT d ON e.DEPTNO = d.DEPTNO) as temp_view;
-
可更新的視圖
-
條件
- FROM子句中只有一個數(shù)據(jù)庫關(guān)系(即在定義視圖的時候雷蹂,后面的SELECT語句中只能查詢一個表)
- SELECT子句中只包含關(guān)系的屬性名,不包含任何的表達(dá)式杯道,集聚函數(shù)或distinct聲明
- 任何沒有出現(xiàn)在SELECT子句中的屬性可以取空值(即這些屬性既沒有not null 約束匪煌,也不構(gòu)成主碼的一部分)
- 查詢中不含有g(shù)roup by 或 having 子句
-
滿足上述條件的視圖我們稱作可更新的視圖,在可更新視圖上允許執(zhí)行update党巾、insert萎庭、delete操作
-
視圖是在表的基礎(chǔ)上定義的,所有對視圖的操作最后都將作用在表上
-
-
視圖的update齿拂、insert驳规、delete
-
先定義一個視圖,值包括員工的職工號署海、名字和工資
CREATE VIEW emp_info AS SELECT EMPNO, ENAME, SAL FROM EMP;
視圖查詢的結(jié)果如下:
2.png -
update
- 舉個栗子
-- 下面的語句更新SMITH的工資 UPDATE emp_info SET SAL = 900 WHERE ENAME = 'SMITH' --接下來查詢表中的數(shù)據(jù)是否受到影響(查詢的結(jié)果是900吗购,就不貼圖了) SELECT ENAME, SAL FROM EMP WHERE ENAME = 'SMITH';
-
insert
- 舉個栗子
-- 往視圖中插入一條數(shù)據(jù)(下面插入是可以執(zhí)行成功的,可以自己試試砸狞,創(chuàng)建一個視圖捻勉,只包含員工名字和工資,不包含EMPNO刀森,這樣就不能執(zhí)行插入語句踱启,違反了上面四個條件中的第三個條件) INSERT INTO emp_info (EMPNO, ENAME, SAL) VALUES ( 8888, 'Robbin', '1000' );
--查詢一下原表中的數(shù)據(jù),會發(fā)現(xiàn)多了下面這條
3.png- 視圖的插入操作,最終作用到表上禽捆,并且是給視圖中有的字段賦值笙什,沒有的字段都賦null值(這就解釋了上面可更新視圖的四個條件中的條件3)
-
delete
- 舉個栗子
-- 執(zhí)行結(jié)構(gòu)就是原表中的數(shù)據(jù)也被刪除了 DELETE emp_info WHERE emp_info.EMPNO = 8888
-
-
物化視圖
- 就是保存視圖的結(jié)構(gòu),再使用時直接用保存的結(jié)果表胚想,而不用再去將視圖替換成定義琐凭,再次執(zhí)行一遍查詢視圖的操作。這個在對視圖的操作很頻繁的時候是對效率很有增益的浊服,但是同時帶來的是同步的問題统屈。就是原表中的數(shù)據(jù)更新了,但是視圖物化的數(shù)據(jù)卻沒有更新牙躺,導(dǎo)致數(shù)據(jù)不一致愁憔。
- 一般用的很少,常用于數(shù)據(jù)倉庫
事務(wù)
- 一個事務(wù)就是一個原子的孽拷,不可分割的任務(wù)吨掌,里面可能包含多條SQL語句。在事務(wù)機(jī)制下脓恕,一個事務(wù)中的多條SQL語句要么都執(zhí)行膜宋,要么都不執(zhí)行。
-
性質(zhì)
- 原子性
- 事務(wù)是原子的炼幔,里面包含的一條或多條SQL語句要么都執(zhí)行秋茫,要么都不執(zhí)行
- 一致性
- 在隔離的執(zhí)行多個事務(wù)時,用同步鎖保證對數(shù)據(jù)庫數(shù)據(jù)的一致性訪問
- 隔離性
- 多個事務(wù)并行執(zhí)行乃秀,若其中一個事務(wù)還沒有結(jié)束肛著,其他事務(wù)內(nèi)是無法觀察到這個事務(wù)對數(shù)據(jù)庫的影響的
- 持久性
- 一旦事務(wù)正常完成,并提交跺讯,則其對數(shù)據(jù)庫的修改就會持久化到數(shù)據(jù)庫內(nèi)枢贿。
- 原子性
-
事務(wù)的開始和終止
- 雖然各種關(guān)系型數(shù)據(jù)庫都支持事務(wù),但是不同的數(shù)據(jù)庫的實(shí)現(xiàn)不同抬吟。具體的事務(wù)的開始和終止有隱式和顯示之分
-
事務(wù)的開始
- 顯示:begin transition (例如SQL Server數(shù)據(jù)庫)
- 隱式:第一條DML語句(增刪改查語句)開始執(zhí)行就會開啟一個事務(wù) (例如Oracle數(shù)據(jù)庫)
-
事物的終止
- 顯示: end transition (例如SQL Server數(shù)據(jù)庫)
- 隱式:執(zhí)行 rollback萨咕、commit或者一條DDL語句 (例如Oracle數(shù)據(jù)庫)
-
數(shù)據(jù)庫加鎖的范圍不同
- 表級鎖
- 頁級鎖
- 行級鎖
-
舉個栗子(由于使用SQL Server做的測試,所以采用顯示的事務(wù)開啟和關(guān)閉)
-- 首先查看博客開頭ALLEN的工資是1600 -- 下面開啟一個事務(wù)火本,并執(zhí)行一條漲工資的操作(執(zhí)行會立即完成) BEGIN TRANSACTION UPDATE EMP SET SAL = SAL * 2 WHERE ENAME = 'ALLEN'; -- 與此同時危队,開啟另一個事務(wù),執(zhí)行一條漲工資的操作(語句沒有執(zhí)行钙畔,一直在等待茫陆。這是因?yàn)樯厦婺莻€事務(wù)對ALLEN的數(shù)據(jù)進(jìn)行操作了,并且事務(wù)沒有結(jié)束擎析,由于同步鎖的緣故簿盅,所以本事務(wù)中的修改語句要等上面那個事務(wù)執(zhí)行完才能繼續(xù)執(zhí)行) BEGIN TRANSACTION UPDATE EMP SET SAL = SAL * 3 WHERE ENAME = 'ALLEN'; -- 如果此時結(jié)束第一個事務(wù)挥下,那么第二個事務(wù)的語句就能繼續(xù)執(zhí)行,此時提交第二個事務(wù)桨醋,最后得到的結(jié)果是棚瘟,ALLEN的工資為9600 COMMIT
完整性約束
-
主鍵約束
-
外鍵約束(參照完整性約束)
-
單關(guān)系上的約束
- not null
- unique
- check(<謂詞>)