
MySql簡介
MySql邏輯架構
服務層:為用戶端做連接配接處理,授權和安全認證相關工作
核心層:查詢解析,分析,優化SQL語句,緩存結果等等
存儲引擎層:存儲和提取資料(索引使用)及事務的處理
存儲引擎
InnoDb
特點:MySQL5.7之前的版本不支援全文索引,5.7及以後的支援
支援行級鎖,鎖粒度小
支援ACID(事務完整性和異質性)
獨有的聚簇索引主鍵設計方式,可大發提升并發讀寫性能
支援外鍵,支援崩潰資料的自我修複
注意問題
a) 所有InnoDB資料表都建立一個和業務無關的自增數字型作為主鍵,對保證性能很有幫助;
b) 杜絕使用text/blob,确實需要使用的,盡可能拆分出去成一個獨立的表;
c) 時間建議使用 TIMESTAMP 類型存儲;
d) IPV4 位址建議用 INT UNSIGNED 類型存儲;
e) 性别等非是即非的邏輯,建議采用 TINYINT 存儲,而不是 CHAR(1);bool
f) 存儲較長文本内容時,建議采用JSON/BSON格式存儲;
MyIsam
特點:支援全文索引,
能夠對整張表進行加鎖,不支援行鎖,及鎖粒度較大。
缺點:不支援事物,及沒有rollback功能。
應用:日志系統,讀表的操作,沒有事物第并發的網站
隔離級别
Read Uncommitted(讀取未送出内容)
在該隔離級别,所有事務都可以看到其他未送出事務的執行結果。本隔離級别很少用于實際應用,因為它的性能也不比其他級别好多少。讀取未送出的資料,也被稱之為髒讀(Dirty Read)。
注意:讀取未送出内容會出現贓讀
Read Committed(讀取送出内容)
這是大多數資料庫系統的預設隔離級别(但不是MySQL預設的)。它滿足了隔離的簡單定義:一個事務隻能看見已經送出事務所做的改變。這種隔離級别 也支援所謂的不可重複讀(Nonrepeatable Read),因為同一事務的其他執行個體在該執行個體處理其間可能會有新的commit,是以同一select可能傳回不同結果。
Repeatable Read(可重讀)
這是MySQL的預設事務隔離級别,它確定同一事務的多個執行個體在并發讀取資料時,會看到同樣的資料行。不過理論上,這會導緻另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當使用者讀取某一範圍的資料行時,另一個事務又在該範圍内插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。
注意:可重讀會出現幻讀的情況
Serializable(可串行化)
這是最高的隔離級别,它通過強制事務排序,使之不可能互相沖突,進而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共享鎖。在這個級别,可能導緻大量的逾時現象和鎖競争。
索引實作
目前大部分資料庫系統及檔案系統都采用B-Tree或其變種B+Tree作為索引結構
B-Tree
B+Tree
帶有順序通路指針的B+Tree
一般在資料庫系統或檔案系統中使用的B+Tree結構都在經典B+Tree的基礎上進行了優化,增加了順序通路指針。
如圖所示,在B+Tree的每個葉子節點增加一個指向相鄰葉子節點的指針,就形成了帶有順序通路指針的B+Tree。做這個優化的目的是為了提高區間通路的性能,例如圖4中如果要查詢key為從18到49的所有資料記錄,當找到18後,隻需順着節點和指針順序周遊就可以一次性通路到所有資料節點,極大提到了區間查詢效率。
InnoDB索引實作
雖然InnoDB也使用B+Tree作為索引結構,但具體實作方式卻與MyISAM截然不同。
第一個重大差別是InnoDB的資料檔案本身就是索引檔案。從上文知道,MyISAM索引檔案和資料檔案是分離的,索引檔案僅儲存資料記錄的位址。而在InnoDB中,表資料檔案本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域儲存了完整的資料記錄。這個索引的key是資料表的主鍵,是以InnoDB表資料檔案本身就是主索引。
是InnoDB主索引(同時也是資料檔案)的示意圖,可以看到葉節點包含了完整的資料記錄。這種索引叫做聚集索引。因為InnoDB的資料檔案本身要按主鍵聚集,是以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一辨別資料記錄的列作為主鍵,如果不存在這種列,則MySQL自動為InnoDB表生成一個隐含字段作為主鍵,這個字段長度為6個位元組,類型為長整形。
第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是位址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域。例如,圖11為定義在Col3上的一個輔助索引:
圖11
這裡以英文字元的ASCII碼作為比較準則。聚集索引這種實作方式使得按主鍵的搜尋十分高效,但是輔助索引搜尋需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。
事務
MVCC實作
MVCC是通過在每行記錄後面儲存兩個隐藏的列來實作的。這兩個列,一個儲存了行的建立時間,一個儲存行的過期時間(或删除時間)。當然存儲的并不是實際的時間值,而是系統版本号(system version number)。每開始一個新的事務,系統版本号都會自動遞增。事務開始時刻的系統版本号會作為事務的版本号,用來和查詢到的每行記錄的版本号進行比較。
下面看一下在REPEATABLE READ隔離級别下,MVCC具體是如何操作的。SELECT
InnoDB會根據以下兩個條件檢查每行記錄:InnoDB隻查找版本早于目前事務版本的資料行(也就是,行的系統版本号小于或等于事務的系統版本号),這樣可以確定事務讀取的行,要麼是在事務開始前已經存在的,要麼是事務自身插入或者修改過的。
行的删除版本要麼未定義,要麼大于目前事務版本号。這可以確定事務讀取到的行,在事務開始之前未被删除。
隻有符合上述兩個條件的記錄,才能傳回作為查詢結果
INSERT
InnoDB為新插入的每一行儲存目前系統版本号作為行版本号。
DELETE
InnoDB為删除的每一行儲存目前系統版本号作為行删除辨別。
UPDATE
InnoDB為插入一行新記錄,儲存目前系統版本号作為行版本号,同時儲存目前系統版本号到原來的行作為行删除辨別。
儲存這兩個額外系統版本号,使大多數讀操作都可以不用加鎖。這樣設計使得讀資料操作很簡單,性能很好,并且也能保證隻會讀取到符合标準的行,不足之處是每行記錄都需要額外的存儲空間,需要做更多的行檢查工作,以及一些額外的維護工作
大部分内容摘自: