數據庫設計三大範式及事務

數據庫三大範式

爲了創建冗餘較小、結構合理的數據庫,設計數據庫時必須遵循必定的規則。在關係型數據庫中這種規則就稱爲範式。範式是符合某一種設計要求的總結。要想設計一個結構合理的關係型數據庫,必須知足必定的範式。javascript

                 

在實際開發中最爲常見的設計範式有三個:java

1.第一範式(確保每列保持原子性)sql

第一範式是最基本的範式。若是數據庫表中的全部字段值都是不可分解的原子值,就說明該數據庫表知足了第一範式。數據庫

第一範式的合理遵循須要根據系統的實際需求來定。好比某些數據庫系統中須要用到地址這個屬性,原本直接將地址屬性設計成一個數據庫表的字段就行。可是若是系統常常會訪問地址屬性中的城市部分,那麼就非要將地址這個屬性從新拆分爲省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一部分操做的時候將很是方便。這樣設計纔算知足了數據庫的第一範式,以下表所示。併發

 

 

上表所示的用戶信息遵循了第一範式的要求,這樣在對用戶使用城市進行分類的時候就很是方便,也提升了數據庫的性能。數據庫設計

                

2.第二範式(確保表中的每列都和主鍵相關)ide

第二範式在第一範式的基礎之上更進一層。第二範式須要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能保存一種數據,不能夠把多種數據保存在同一張數據庫表中。函數

好比要設計一個訂單信息表,由於訂單中可能會有多種商品,因此要將訂單編號和商品編號做爲數據庫表的聯合主鍵,以下表所示。工具

 訂單信息表性能

 

 

 

這樣就產生一個問題:這個表中是以訂單編號和商品編號做爲聯合主鍵。這樣在該表中商品名稱、單位、商品價格等信息不與該表的主鍵相關,而僅僅是與商品編號相關。因此在這裏違反了第二範式的設計原則。

而若是把這個訂單信息表進行拆分,把商品信息分離到另外一個表中,把訂單項目表也分離到另外一個表中,就很是完美了。以下所示。

 

 

這樣設計,在很大程度上減少了數據庫的冗餘。若是要獲取訂單的商品信息,使用商品編號到商品信息表中查詢便可。

                 

3.第三範式(確保每列都和主鍵列直接相關,而不是間接相關)

第三範式須要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關

好比在設計一個訂單數據表的時候,能夠將客戶編號做爲一個外鍵和訂單表創建相應的關係。而不能夠在訂單表中添加關於客戶其它信息(好比姓名、所屬公司等)的字段。以下面這兩個表所示的設計就是一個知足第三範式的數據庫表。

 

 

這樣在查詢訂單信息的時候,就可使用客戶編號來引用客戶信息表中的記錄,也沒必要在訂單信息表中屢次輸入客戶信息的內容,減少了數據冗餘。

 

 

E-R

 E-R圖爲實體-聯繫(Entity-Relation)圖,提供了表示實體型、屬性和聯繫的方法,用來描述現實世界的概念模型。
  構成E-R圖的基本要素是實體型、屬性和聯繫,其表示方法爲:
  · 實體型(Entity):用矩形表示,矩形框內寫明實體名;好比學生張三丰、學生李尋歡都是實體。
  · 屬性(Attribute):用橢圓形表示,並用無向邊將其與相應的實體鏈接起來;好比學生的姓名、學號、性別、都是屬性。

  · 聯繫(Relationship):用菱形表示,菱形框內寫明聯繫名,並用無向邊分別與有關實體鏈接起來,同時在無向邊旁標上聯繫的類型(1 : 11 : nm : 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元了,形成虛讀一樣會使銀行不知所措,到底以哪一個爲準。

相關文章
相關標籤/搜索