關係型數據庫知識小結

一、基礎術語

DML(data manipulation language):

如SELECT、UPDATE、INSERT、DELETE,主要用來對數據庫裏的數據進行操作的語言

DDL(data definition language):

主要的命令有CREATE、ALTER、DROP等,DDL主要是用在定義或改變表(TABLE)的結構,數據類型,表之間的鏈接和約束等初始化工作上,大多在建立表時使用。

DCL(Data Control Language):
數據庫控制功能。是用來設置或更改數據庫用戶或角色權限的語句,包括(grant,deny,revoke等)語句。默認情況下,只有sysadmin,dbcreator,db_owner或db_securityadmin等人員纔有權力執行DCL

二、數據庫三範式

關係型數據庫設計表時爲了減小冗餘,增強數據的有效性和存儲效率,需要遵循一定的規範,這些規範按照嚴格程度來區分可以分爲第一範式(1NF),第二範式(2NF),第三範式(3NF),BC範式(BCNF),第四範式(4NF),第五範式(5NF)等。

數據庫範式是數據庫設計中必不可少的理論依據,不理解數據庫範式就無法設計出搞笑優雅的數據庫,甚至依賴混亂,操作經常出錯。實際應用中常用的範式有第一範式(1NF),第二範式(2NF)和第三範式(3NF),後面三個範式則用的比較少,這是因爲適當的冗餘可以增加數據庫的查詢效率。

第一範式(1NF):屬性不可分

第一範式要求數據庫表中所有字段都是不可分的原子值。不滿足第一範式的數據庫,不是關係數據庫!

第二範式(2NF):非主屬性完全依賴於碼

第二範式是在第一範式的基礎上更進一步,要求數據庫要有主鍵,其他非主屬性完全依賴於主鍵,而不能只依賴主鍵中的一部分。即聯合主鍵的情況,如果某一個非主屬性只依賴於聯合主鍵中的一個或者部分屬性,則不符合第二範式。第二範式隱式要求數據庫一張表只保存一種數據,儘量不要把多種數據保存到一張表中。

第三範式(3NF):非主屬性之間不存在傳遞依賴

第三範式是在第二範式的基礎上更進一步,要求屬性不能依賴於表中的非主屬性。第三範式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。

三、事務:

事務(Transaction)是併發控制的基本單位。所謂事務,即一系列操作的集合,這些操作要麼都不執行,要麼全部執行,不允許執行其中一部分,即把一系列操作作爲一個整體進行控制。比如銀行轉賬,簡化下來至少需要兩步操作,1:要從A賬戶扣除100元,2:給B賬戶增加100元,這兩步操作必須作爲一個整體進行控制,假如從A賬戶扣款成功,給B賬戶增加金額失敗,則事務必須回滾(roolback),即把A賬戶的扣款返回給A賬戶。

事務具有四個基本特徵(ACID):

Atomic(原子性):
事務中包含的操作被看做一個邏輯單元,這個邏輯單元中的操作要麼全部成功,要麼全部失敗。

Consistency(一致性):
只有合法的數據可以被寫入數據庫,否則事務應該將其回滾到最初狀態。

Isolation(隔離性):
事務允許多個用戶對同一個數據進行併發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其他並行事務的修改相互獨立。這表明事務必須是獨立的,不應該以任何方式以來於或影響其他事務。

Durability(持久性):
事務結束後,事務處理的結果必須能夠得到固化。事務完成之後,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留,真實的修改了數據庫。

如果多個事務同時影響同一條或者同一些數據,將會導致數據混亂或者事務執行失敗,因此需要對事務的併發進行控制。隔離級別就是對對事務併發控制的等級。SQL-92標準中定義了四個隔離級別,串行化(SERIALIZABLE)、可重複讀(REPEATABLE READ)、讀已提交(READ COMMITED)、讀未提交(READ UNCOMMITED)

 

√ 表示可能發生,× 表示不會發生

 

髒讀

不可重複讀

幻讀

Read uncommitted

Read committed

×

Repeatable read

×

×

Serializable

×

×

×

 
 

假如有兩個事務A和B都在對同一個數據庫進行操作:

1、如果數據庫隔離級別設爲Read uncommitted,事務A先操作數據庫,修改了一條數據,但未提交事務,此時事務B讀數據庫,則會讀取到事務A未提交的髒數據,即爲髒讀

2、如果數據庫隔離級別設爲Read committed,事務A先操作數據庫,讀取數據data_a,然後事務B講數據庫中對應的數據修改爲data_b並提交事務,此時事務A再去讀同一條數據,則數據 變爲data_b,即不可重複讀

3、如果數據庫隔離級別設爲Repeatable read,事務A先讀取某一條件下的一些數據,然後事務B插入一條數據並提交,而這條數據又恰好滿足事務A的select條件,此時事務A再去數據庫查詢該條件下的數據,發現比上一次多了一條,好像出現幻覺一般,稱爲幻讀

4、如果數據庫隔離級別設爲Serializable,則所有事務都是排着隊一條一條執行的,只有上一條事務執行完畢纔會開始下一條事務,因而髒讀、不可重複讀、幻讀這些情況都不可能出現。

 
不可重複讀與幻讀的區別是,不可重複讀是因爲修改了數據而造成的數據不一致,幻讀是因爲插入數據造成的數據不一致。
SQL Server 和Oracle默認的隔離級別是Read committed,MySQL數據庫默認的隔離級別是Repeatable read
 
四、數據庫鎖

數據庫系統本身的鎖機制 :

1、共享鎖(Shared Lock) S鎖允許多個事務同時對同一數據進行讀操作,但是不允許修改數據(與X鎖衝突)。

2、更新鎖(Update Lock) 更新所也稱修改鎖,事務在更新某一項數據時需要加U鎖,讀取該數據項,此時允許其他事務在該項上加S鎖,待事務讀出並修改後,將U鎖升級爲X鎖,然後寫入修改後的數據。

3、排他鎖(Exclusive Lock):排他鎖是獨佔鎖,一般修改數據時使用,select...for update

4、意向鎖(Intent Lock):意向鎖是表級鎖,說明在資源底層獲得共享鎖或獨佔鎖的意向。例如,當讀取表裏的頁面時,在請求頁共享鎖(S鎖)之前,事務在表級請求共享意向鎖。這樣可以防止其他事務隨後在表上獲取排他鎖(X鎖),修改整個表格。意向鎖可以提高性能,因爲數據庫引擎僅在表級檢查意向鎖,確定事務是否能安全地獲取該表上的鎖,而不需要檢查表中的每行或每頁上的鎖以確定事務是否可以鎖定整個表。意向鎖有兩種用途:防止其他事務以會使較低級別的鎖無效的方式修改較高級別資源;提高數據庫引擎在較高的粒度級別檢測鎖衝突的效率。

意向共享鎖(IS):表示事務準備給數據行加入共享鎖,也就是說一個數據行加共享鎖前必須先取得該表的IS鎖

意向排他鎖(IX):類似上面,表示事務準備給數據行加入排他鎖,說明事務在一個數據行加排他鎖前必須先取得該表的IX鎖。

各種鎖的兼容性如下:
 

意向共享(IS)

共享(S)

更新(U)

意向排他(IX)

排他(X)

意向共享(IS)

共享(S)

更新(U)

意向排他(IX)

排他(X)

5、模式鎖(Schema Lock):Altert table,改變表結構時使用

6、批量更新鎖(Bulk Update Lock):數據庫備份恢復

業務級別上的鎖機制,hibernate支持有以下兩種類型的鎖

悲觀鎖:

對數據被外界修改持保守態度,即認爲經常會發生不止一個事務修改同一條數據的情況,因此所有事務對數據修改前都要獲取一把鎖,用來排斥其他事務對該數據的操作。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能 真正保證數據訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系 統不會修改數據)。如 select * form user where id=#{id} for update;語句,就會使數據庫系統鎖定該條記錄。

樂觀鎖:

樂觀鎖認爲多個事務併發修改數據庫同一條記錄這樣的情況是不經常發生的,對事務操作加鎖也是非必須的,即對此事持樂觀態度。但是同樣要保證數據的一致性,樂觀鎖要使用一個標誌位來標示是否存在其他事務同時在操作該條數據,這樣的標誌位大多是基於數據版本(Version)記錄機制實現的。

鎖的分類(oracle)

1、按操作劃分,可分爲DML鎖、DDL鎖

2、按鎖的粒度劃分,可分爲表級鎖、行級鎖、頁級鎖(MySQL

3、按鎖級別劃分,可分爲共享鎖、排他鎖

4、按加鎖方式劃分,可分爲自動鎖、顯示鎖

5、按使用方式劃分,可分爲樂觀鎖、悲觀鎖

五、其他

視圖(View)

數據庫視圖是一張虛表,邏輯上的表,有時爲了區別視圖和表,也稱表爲基本表——Base Table。視圖所對應的數據不進行實際存儲,不佔用物理空間。視圖掩碼數據庫的複雜性,視圖把數據庫設計的複雜性與用戶屏蔽分開,也能起到用戶程序與實際數據庫表結構解耦的作用。

存儲過程

存儲過程是 SQL 語句和可選控制流語句的預編譯集合,以一個名稱存儲並作爲一個單元處理。存儲過程存儲在數據庫內,可由應用程序通過一個調用執行,而且允許用戶聲明變量、有條件執行以及其它強大的編程功能。

存儲過程與函數的區別:

1.一般情況下,函數實現的功能針對性比較強而存儲過程實現的功能要複雜一點。

2..存儲過程來說可以返回參數,而函數只能返回值或者表對象。

3.一般將存儲過程作爲一個獨立的部分來執行,而把函數作爲查詢語句的一個部分來調用,由於函數可以返回一個表對象,因此它可以出現在查詢語句FROM關鍵字的後面。

觸發器

觸發器和存儲過程一樣,也是一段sql程序。不同的是存儲過程通過名字直接調用,而觸發器則相當於事件監聽器,在某個特定的事件發生時由數據庫系統自動調用的。

觸發器語法:

create trigger 觸發器的名字 on 操作表 
befor|after instead of 
update|insert|delete 
as 
SQL語句

在mysql的innoDB引擎下(該引擎下表爲事務表),觸發器和引起觸發器執行的Sql語句具有事務性,如果before類型的觸發器執行失敗則sql語句不執行,如果sql語句執行失敗則after觸發器不執行,如果after觸發器執行失敗則引起觸發器執行的sql語句回滾。

遊標

遊標是一個數據緩衝器,也就是一個內存區域,用來暫時存放受SQL語句影響到的數據。即受影響的數據暫時存放在一張虛表中,這個虛表就是遊標。

Orale中游標的類型:

1,隱式遊標:在 PL/SQL 程序中執行DML SQL 語句時自動創建隱式遊標,名字固定叫sql。數據庫中的事物可以回滾,而遊標在其中起着非常重要的作用,由於對數據庫的操作我們會暫時放在遊標中,只要不提交,我們就可以根據遊標中內容進行回滾,在一定意義有利於數據庫的安全。

2,顯式遊標:用於從表中取出多行數據,並將多行數據一行一行的單獨進行處理.

declare 
--1,聲明遊標
cursor cur is 
select * from user;
begin 
--2,直接使用,Oracle會自動打開和關閉等操作。 
for v_user in cur loop 
dbms_output.put_line(v_user.userName); 
end loop 
end;
發佈了33 篇原創文章 · 獲贊 31 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章