數據庫三大范式
為了建立冗余較小、結構合理的數據庫,設計數據庫時必須遵循一定的規則。在關系型數據庫中這種規則就稱為范式。范式是符合某一種設計要求的總結。要想設計一個結構合理的關系型數據庫,必須滿足一定的范式。
在實際開發中最為常見的設計范式有三個:
1.第一范式(確保每列保持原子性)
第一范式是最基本的范式。如果數據庫表中的所有字段值都是不可分解的原子值,就說明該數據庫表滿足了第一范式。
第一范式的合理遵循需要根據系統的實際需求來定。比如某些數據庫系統中需要用到“地址”這個屬性,本來直接將“地址”屬性設計成一個數據庫表的字段就行。但是如果系統經常會訪問“地址”屬性中的“城市”部分,那么就非要將“地址”這個屬性重新拆分為省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一部分操作的時候將非常方便。這樣設計才算滿足了數據庫的第一范式,如下表所示。
上表所示的用戶信息遵循了第一范式的要求,這樣在對用戶使用城市進行分類的時候就非常方便,也提高了數據庫的性能。
2.第二范式(確保表中的每列都和主鍵相關)
第二范式在第一范式的基礎之上更進一層。第二范式需要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能保存一種數據,不可以把多種數據保存在同一張數據庫表中。
比如要設計一個訂單信息表,因為訂單中可能會有多種商品,所以要將訂單編號和商品編號作為數據庫表的聯合主鍵,如下表所示。
訂單信息表
這樣就產生一個問題:這個表中是以訂單編號和商品編號作為聯合主鍵。這樣在該表中商品名稱、單位、商品價格等信息不與該表的主鍵相關,而僅僅是與商品編號相關。所以在這里違反了第二范式的設計原則。
而如果把這個訂單信息表進行拆分,把商品信息分離到另一個表中,把訂單項目表也分離到另一個表中,就非常完美了。如下所示。
這樣設計,在很大程度上減小了數據庫的冗余。如果要獲取訂單的商品信息,使用商品編號到商品信息表中查詢即可。
3.第三范式(確保每列都和主鍵列直接相關,而不是間接相關)
第三范式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。
比如在設計一個訂單數據表的時候,可以將客戶編號作為一個外鍵和訂單表建立相應的關系。而不可以在訂單表中添加關於客戶其它信息(比如姓名、所屬公司等)的字段。如下面這兩個表所示的設計就是一個滿足第三范式的數據庫表。
這樣在查詢訂單信息的時候,就可以使用客戶編號來引用客戶信息表中的記錄,也不必在訂單信息表中多次輸入客戶信息的內容,減小了數據冗余。
E-R圖
E-R圖為實體-聯系(Entity-Relation)圖,提供了表示實體型、屬性和聯系的方法,用來描述現實世界的概念模型。
構成E-R圖的基本要素是實體型、屬性和聯系,其表示方法為:
· 實體型(Entity):用矩形表示,矩形框內寫明實體名;比如學生張三豐、學生李尋歡都是實體。
· 屬性(Attribute):用橢圓形表示,並用無向邊將其與相應的實體連接起來;比如學生的姓名、學號、性別、都是屬性。
· 聯系(Relationship):用菱形表示,菱形框內寫明聯系名,並用無向邊分別與有關實體連接起來,同時在無向邊旁標上聯系的類型(1 : 1,1 : n或m : n)。 比如老師給學生授課存在授課關系,學生選課存在選課關系。
如下圖所示:是一個班級、學生、課程、教師之間的ER圖:
實體-聯系圖(Entity-Relation Diagram)用來建立數據模型,在數據庫系統概論中屬於概念設計階段,形成一個獨立於機器,獨立於DBMS的ER圖模型。 通常將它簡稱為ER圖,相應地可把用ER圖描繪的數據模型稱為ER模型。ER圖提供了表示實體(即數據對象)、屬性和聯系的方法,用來描述現實世界的概念模型。
ER模型最早由Peter Chen於1976年提出,它在數據庫設計領域得到了廣泛的認同,但很少用作實際數據庫管理系統的數據模型。即使對SXL-92數據庫來說,設計好的數據庫也是具有挑戰性的。它們可以在許多關於數據庫設計的文獻中找到,比如Toby Teorsey 的著作(1994 )。
大部分數據庫設計產品使用實體-聯系模型(ER模型)幫助用戶進行數據庫設計。ER數據庫設計工具提供了一個“方框與箭頭”的繪圖工具,幫助用戶建立ER圖來描繪數據。
編輯本段
構成E-R圖的基本要素是實體、屬性和聯系。 一個簡單的例子
實體(entity):客觀存在並且可以相互區分的事物稱為實體。實體既可以是具體的對象,也可以是抽象的對象。
屬性(attribute):實體的特性稱為屬性。主屬性(identifier)則是能唯一標識實體的屬性。
聯系(relationship):實體之間的相互關系稱為聯系。聯系可分為“一對一聯系”、“一對多聯系”、“多對多聯系” 3種類型。
編輯本段
成分
在ER圖中有如下四個成分:
矩形框:表示實體,在框中記入實體名。
菱形框:表示聯系,在框中記入聯系名。
橢圓形框:表示實體或聯系的屬性,將屬性名記入框中。對於主屬性名,則在其名稱下划一下划線。
連線:實體與屬性之間;實體與聯系之間;聯系與屬性之間用直線相連,並在直線上標注聯系的類型。(對於一對一聯系,要在兩個實體連線方向各寫1; 對於一對多聯系,要在一的一方寫1,多的一方寫N;對於多對多關系,則要在兩個實體連線方向各寫N,M。)
單元測試
http://blog.csdn.net/sunzhenhua0608/article/details/8858151
事務(Transaction)是並發控制的基本單位。所謂的事務,它是一個操作序列,這些操作要么都執行,要么都不執行,它是一個不可分割的工作單位。例如,銀行轉賬工作:從一個賬號扣款並使另一個賬號增款,這兩個操作要么都執行,要么都不執行。所以,應該把它們看成一個事務。事務是數據庫維護數據一致性的單位,在每個事務結束時,都能保持數據一致性。
針對上面的描述可以看出,事務的提出主要是為了解決並發情況下保持數據一致性的問題。
事務具有以下4個基本特征。
● Atomic(原子性):事務中包含的操作被看做一個邏輯單元,這個邏輯單元中的操作要么全部成功,要么全部失敗。
● Consistency(一致性):只有合法的數據可以被寫入數據庫,否則事務應該將其回滾到最初狀態。
● Isolation(隔離性):事務允許多個用戶對同一個數據進行並發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其他並行事務的修改相互獨立。
● Durability(持久性):事務結束后,事務處理的結果必須能夠得到固化。
2.事務的語句
開始事物:BEGIN TRANSACTION
提交事物:COMMIT TRANSACTION
回滾事務:ROLLBACK TRANSACTION
3.事務的4個屬性
①原子性(Atomicity):事務中的所有元素作為一個整體提交或回滾,事務的個元素是不可分的,事務是一個完整操作。
②一致性(Consistemcy):事物完成時,數據必須是一致的,也就是說,和事物開始之前,數據存儲中的數據處於一致狀態。保證數據的無損。
③隔離性(Isolation):對數據進行修改的多個事務是彼此隔離的。這表明事務必須是獨立的,不應該以任何方式以來於或影響其他事務。
④持久性(Durability):事務完成之后,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留,真實的修改了數據庫
4.事務的保存點
SAVE TRANSACTION 保存點名稱 --自定義保存點的名稱和位置
ROLLBACK TRANSACTION 保存點名稱 --回滾到自定義的保存點
其他高手的一些補充:
事務的標准定義: 指作為單個邏輯工作單元執行的一系列操作,而這些邏輯工作單元需要具有原子性, 一致性,隔離性和持久性四個屬性,統稱為ACID特性。
所謂事務是用戶定義的一個數據庫操作序列,這些操作要么全做要么全不做,是一個不可分割的工作單位。例如,在關系數據庫中,一個事務可以是一條SQL語句、一組SQL語句或整個程序。
事務和程序是兩個概念。一般地講,一個程序中包含多個事務。
事務的開始與結束可以由用戶顯式控制。如果用戶沒有顯式地定義事務,則由DBMS按缺省規定自動划分事
務。在SQL語言中,定義事務的語句有三條:
BEGIN TRANSACTION
COMMIT
ROLLBACK
同生共死。。
顯示事務被用begin transaction 與 end transaction 標識起來,其中的 update 與 delete 語句或者全部執行或者全部不執行。。 如:
begin transaction T1
update student
set name='Tank'
where id=2006010
delete from student
where id=2006011
commit
簡單地說,事務是一種機制,用以維護數據庫的完整性。
其實現形式就是將普通的SQL語句嵌入到Begin Tran...Commit Tran 中(或完整形式 Begin Transaction...Commit Transaction),當然,必要時還可以使用RollBack Tran 回滾事務,即撤銷操作。
利用事務機制,對數據庫的操作要么全部執行,要么全部不執行,保證數據庫的一致性。需要使用事務的SQL語句通常是更新和刪除操作等。
end transaction T1
關於savepoint
用戶在事務(transaction)內可以聲明(declare)被稱為保存點(savepoint)
的標記。保存點將一個大事務划分為較小的片斷。
用戶可以使用保存點(savepoint)在事務(transaction)內的任意位置作標
記。之后用戶在對事務進行回滾操作(rolling back)時,就可以選擇從當前
執行位置回滾到事務內的任意一個保存點。例如用戶可以在一系列復雜的更
新(update)操作之間插入保存點,如果執行過程中一個語句出現錯誤,用
戶 可以回滾到錯誤之前的某個保存點,而不必重新提交所有的語句。
在開發應用程序時也同樣可以使用保存點(savepoint)。如果一個過程
(procedure)內包含多個函數(function),用戶可以在每個函數的開始位置
創建一個保存點。當一個函數失敗時, 就很容易將數據恢復到函數執行之前
的狀態,回滾(roll back)后可以修改參數重新調用函數,或執行相關的錯誤
處理。
當事務(transaction)被回滾(rollback)到某個保存點(savepoint)后,
Oracle將釋放由被回滾語句使用的鎖。其他等待被鎖資源的事務就可以繼續
執行。需要更新(update)被鎖數據行的事務也可以繼續執行。
將事務(transaction)回滾(roll back)到某個保存點(savepoint)的過程如
下:
1. Oracle 回滾指定保存點之后的語句
2. Oracle 保留指定的保存點,但其后創建的保存點都將被清除
3. Oracle 釋放此保存點后獲得的表級鎖(table lock)與行級鎖(row
lock),但之前的數據鎖依然保留。
被部分回滾的事務(transaction)依然處於活動狀態,可以繼續執行。
一個事務(transaction)在等待其他事務的過程中,進行回滾(roll back)到
某個保存點(savepoint)的操作不會釋放行級鎖(row lock)。為了避免事務
因為不能獲得鎖而被掛起,應在執行 UPDATE 或 DELETE 操作前使用 FOR
UPDATE ... NOWAIT 語句。(以上內容講述的是回滾保存點之前所獲得的
鎖。而在保存點之后獲得的行級鎖是會被釋放的,同時保存點之后執行的
SQL 語句也會被完全回滾)
☆事務的概念
事務指邏輯上的一組操作,組成這組操作的各個單元,要不全部成功,要不全部不成功。
例如:A——B轉帳,對應於如下兩條sql語句
update from account set money=money+100 where name=‘b’;
update from account set money=money-100 where name=‘a’;
☆數據庫開啟事務命令
start transaction 開啟事務
Rollback 回滾事務
Commit 提交事務
set transction isolation level 設置事務隔離級別
select @@tx_isolation 查詢當前事務隔離級別
☆事務的特性(ACID)
原子性(Atomicity)原子性是指事務是一個不可分割的工作單位,事務中的操作要么都發生,要么都不發生。
一致性(Consistency)事務必須使數據庫從一個一致性狀態變換到另外一個一致性狀態。
隔離性(Isolation)事務的隔離性是多個用戶並發訪問數據庫時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作數據所干擾,多個並發事務之間要相互隔離。
持久性(Durability)持久性是指一個事務一旦被提交,它對數據庫中數據的改變就是永久性的,接下來的其他操作和數據庫故障不應該對其有任何影響。
使用JDBC管理事務
當一個連接對象被創建時,默認情況下JDBC是自動提交事務:每次執行一個 SQL 語句時,如果執行成功,就會向數據庫自動提交,而不能回滾。如想多條SQL在同一事務中,可使用下列語句:
☆JDBC控制事務語句
Connection.setAutoCommit(false);
Connection.rollback();
Connection.commit();
☆演示銀行轉帳案例
在JDBC代碼中使如下轉帳操作在同一事務中執行。
update from account set money=money-100 where name=‘a’;
update from account set money=money+100 where name=‘b’;
☆設置事務回滾點
Savepoint sp = conn.setSavepoint();
Conn.rollback(sp);
Conn.commit(); //回滾后必須要提交
☆事務的隔離級別
多個線程開啟各自事務操作數據庫中數據時,數據庫系統要負責隔離操作,以保證各個線程在獲取數據時的准確性。
☆數據庫共定義了四種隔離級別:
Serializable(串行化):可避免臟讀、不可重復讀、虛讀情況的發生。
Repeatable read(重復讀):可避免臟讀、不可重復讀情況的發生。
Read committed(讀提交):可避免臟讀情況發生。
Read uncommitted(讀未提交):最低級別,以上情況均無法保證。
☆事務的隔離性
*臟讀:
指一個事務讀取了另外一個事務未提交的數據。
這是非常危險的,假設A向B轉帳100元,A在一台電腦上開啟事務執行如下2步操作,向B存入100元,並把自己的錢減少100元:
1.update account set money=money+100 while name=‘b’;
2.update account set money=money-100 while name=‘a’;
當第1步執行完,第2步還未執行,A未提交時,此時B查詢自己的帳戶就會發現自己多了100元錢,以為A轉了100元。如果A等B走后再回滾,B就會損失100元。
*不可重復讀:
在一個事物內讀取表中的某一行數據,多次讀取結果不同。
例如銀行想查詢A帳戶余額,第一次查詢A帳戶為200元,此時A向帳戶內存了100元,銀行此時又進行了一次查詢,此時A帳戶為300元了,銀行可能就會很困惑,不知道哪次查詢是准的。和臟讀的區別是,臟讀是讀取前一事務未提交的臟數據,不可重復讀是重新讀取了前一事務已提交的數據。
很多人認為這種情況就對了,無須困惑,當然是后面的為准。我們可以考慮這樣一種情況,比如銀行程序需要將查詢結果分別輸出到電腦屏幕和寫到文件中,結果在一個事務中針對輸出的目的地,進行的兩次查詢不一致,導致文件和屏幕中的結果不一致,銀行工作人員就不知道以哪個為准了。
*虛讀
是指在一個事務內讀取到了別的事務插入的數據,導致前后讀取不一致。
如丙存款100元未提交,這時銀行做報表統計account表中所有用戶的總額為2700元,然后丙提交了,這時銀行再統計發現帳戶為2800元了,造成虛讀同樣會使銀行不知所措,到底以哪個為准。