事務的概念來自於兩個獨立的需求:併發數據庫訪問,系統錯誤恢復。數據庫
一個事務是能夠被看做一個單元的一系列SQL語句的集合。併發
atomacity 原子性 :事務必須是原子工做單元;對於其數據修改,要麼全都執行,要麼全都不執行。一般,與某個事務關聯的操做具備共同的目標,而且是相互依賴的。若是系統只執行這些操做的一個子集,則可能會破壞事務的整體目標。原子性消除了系統處理操做子集的可能性。性能
consistency 一致性:事務將數據庫從一種一致狀態轉變爲下一種一致狀態。也就是說,事務在完成時,必須使全部的數據都保持一致狀態(各類 constraint 不被破壞)。優化
isolation 隔離性:由併發事務所做的修改必須與任何其它併發事務所做的修改隔離。事務查看數據時數據所處的狀態,要麼是另外一併發事務修改它以前的狀態,要麼是另外一事務修改它以後的狀態,事務不會查看中間狀態的數據。換句話說,一個事務的影響在該事務提交前對其餘事務都不可見。atom
durability 持久性:事務完成以後,它對於系統的影響是永久性的。該修改即便出現致命的系統故障也將一直保持。排序
若是不對數據庫進行併發控制,可能會產生異常狀況:索引
髒讀(Dirty Read)事務
當一個事務讀取另外一個事務還沒有提交的修改時,產生髒讀。ci
一個事務開始讀取了某行數據,可是另一個事務已經更新了此數據但沒有可以及時提交。這是至關危險的,由於極可能全部的操做都被回滾,也就是說讀取出的數據實際上是錯誤的。資源
非重複讀(Nonrepeatable Read)
一個事務對同一行數據重複讀取兩次,可是卻獲得了不一樣的結果。同一查詢在同一事務中屢次進行,因爲其餘提交事務所作的修改或刪除,每次返回不一樣的結果集,此時發生非重複讀。
幻像讀(Phantom Reads)
事務在操做過程當中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據(這裏並不要求兩次查詢的SQL語句相同)。這是由於在兩次查詢過程當中有另一個事務插入數據形成的。
當對某行執行插入或刪除操做,而該行屬於某個事務正在讀取的行的範圍時,會發生幻像讀問題。
丟失修改(Lost Update)
第一類:當兩個事務更新相同的數據源,若是第一個事務被提交,第二個卻被撤銷,那麼連同第一個事務作的更新也被撤銷。
第二類:有兩個併發事務同時讀取同一行數據,而後其中一個對它進行修改提交,而另外一個也進行了修改提交。這就會形成第一次寫操做失效。
爲了兼顧併發效率和異常控制,在標準SQL規範中,定義了4個事務隔離級別,( Oracle 和 SQL Server 對標準隔離級別有不一樣的實現 )
未提交讀(Read Uncommitted)
直譯就是讀未提交,意思就是即便一個更新語句沒有提交,可是別的事務能夠讀到這個改變。
Read Uncommitted容許髒讀。
已提交讀(Read Committed)
直譯就是讀提交,意思就是語句提交之後,即執行了 Commit之後別的事務就能讀到這個改變,只能讀取到已經提交的數據。Oracle等多數數據庫默認都是該級別。
Read Commited 不容許髒讀,但會出現非重複讀。
可重複讀(Repeatable Read):
直譯就是能夠重複讀,這是說在同一個事務裏面前後執行同一個查詢語句的時候,獲得的結果是同樣的。
Repeatable Read 不容許髒讀,不容許非重複讀,可是會出現幻象讀。
串行讀(Serializable)
直譯就是序列化,意思是說這個事務執行的時候不容許別的事務併發執行。徹底串行化的讀,每次讀都須要得到表級共享鎖,讀寫相互都會阻塞。
Serializable 不容許不一致現象的出現。
共享鎖(S鎖)
用於只讀操做(SELECT),鎖定共享的資源。共享鎖不會阻止其餘用戶讀,可是阻止其餘的用戶寫和修改。
更新鎖(U鎖)
用於可更新的資源中。防止當多個會話在讀取、鎖定以及隨後可能進行的資源更新時發生常見形式的死鎖。
獨佔鎖(X鎖,也叫排他鎖)
一次只能有一個獨佔鎖用在一個資源上,而且阻止其餘全部的鎖包括共享縮。寫是獨佔鎖,能夠有效的防止「髒讀」。
Read Uncommited 若是一個事務已經開始寫數據,則另一個數據則不容許同時進行寫操做,但容許其餘事務讀此行數據。該隔離級別能夠經過「排他寫鎖」實現。
Read Committed 讀取數據的事務容許其餘事務繼續訪問該行數據,可是未提交的寫事務將會禁止其餘事務訪問該行。能夠經過「瞬間共享讀鎖」和「排他寫鎖」實現。
Repeatable Read 讀取數據的事務將會禁止寫事務(但容許讀事務),寫事務則禁止任何其餘事務。能夠經過「共享讀鎖」和「排他寫鎖」實現。
Serializable 讀加共享鎖,寫加排他鎖,讀寫互斥。
數據庫建立索引可以大大提升系統的性能。
經過建立惟一性的索引,能夠保證數據庫表中每一行數據的惟一性。
能夠大大加快數據的檢索速度,這也是建立索引的最主要的緣由。
能夠加速表和表之間的鏈接,特別是在實現數據的參考完整性方面特別有意義。
在使用分組和排序子句進行數據檢索時,一樣能夠顯著的減小查詢中分組和排序的時間。
經過使用索引,能夠在查詢的過程當中,使用優化隱藏器,提升系統的性能。
增長索引也有許多不利的方面。
建立索引和維護索引須要消耗時間,這種時間隨着數量的增長而增長。
索引須要佔物理空間,除了數據表佔據數據空間以外,每個索引還要佔必定的物理空間,若是要創建聚簇索引,那麼須要額空間就會更大。
當對錶中的數據進行增長,刪除和修改的時候,索引也要動態的維護,這樣就下降了數據的維護速度。
應該對以下的列創建索引
在做爲主鍵的列上,強制該列的惟一性和組織表中數據的排列結構。
在常常用在鏈接的列上,這些列主要是一些外鍵,能夠加快鏈接的速度。
在常常須要根據範圍進行搜索的列上建立索引,由於索引已經排序,其指定的範圍是連續的。
在常常須要排序的列上建立索引,由於索引已經排序,這樣查詢能夠利用索引的排序,加快排序查詢時間。
在常用在where子句中的列上面建立索引,加快條件的判斷速度。
有些列不該該建立索引
在查詢中不多使用或者做爲參考的列不該該建立索引。
對於那些只有不多數據值的列也不該該增長索引(好比性別,結果集的數據行佔了表中數據行的很大比例,即須要在表中搜索的數據行的比例很大。增長索引,並不能明顯加快檢索速度)。
對於那些定義爲text,image和bit數據類型的列不該該增長索引。這是由於,這些列的數據量要麼至關大,要麼取值不多。
當修改性能遠遠大於檢索性能時,不該該建立索引,由於修改性能和檢索性能是矛盾的。
建立索引的方法:直接建立和間接建立(在表中定義主鍵約束或者惟一性約束時,同時也建立了索引)。
索引的特徵:
惟一性索引保證在索引列中的所有數據是惟一的,不會包含冗餘數據。
複合索引就是一個索引建立在兩個列或者多個列上。能夠減小在一個表中所建立的索引數量。