大話MySQL數據庫引擎

數據庫

  1. 數據庫引擎

數據庫引擎是用於存儲、處理和保護數據的核心服務。利用數據庫引擎可控制訪問權限並快速處理事務,從而滿足企業內大多數需要處理大量數據的應用程序的要求。 使用數據庫引擎創建用於聯機事務處理或聯機分析處理數據的關係數據庫。這包括創建用於存儲數據的表和用於查看、管理和保護數據安全的數據庫對象(如索引、視圖和存儲過程)。

  1. MySql數據庫引擎類別

你能用的數據庫引擎取決於mysql在安裝的時候是如何被編譯的。要添加一個新的引擎,就必須重新編譯MYSQL。在缺省情況下,MYSQL支持三個引擎:ISAM、MYISAM和HEAP。另外兩種類型INNODBBERKLEY(BDB),也常常可以使用

  1. ISAM

ISAM是一個定義明確且歷經時間考驗的數據表格管理方法,它在設計之時就考慮到數據庫被查詢的次數要遠大於更新的次數。因此,ISAM執行讀取操作的速度很快,而且不佔用大量的內存和存儲資源。ISAM的兩個主要不足之處在於,它不支持事務處理,也不能夠容錯:如果你的硬盤崩潰了,那麼數據文件就無法恢復了。如果你正在把ISAM用在關鍵任務應用程序裏,那就必須經常備份你所有的實時數據,通過其複製特性,MYSQL能夠支持這樣的備份應用程序。

  1. MyISAM

MYISAM是MYSQL的ISAM擴展格式和缺省的數據庫引擎。除了提供ISAM裏所沒有的索引和字段管理的功能,MYISAM還使用一種表格鎖定的機制,來優化多個併發的讀寫操作。其代價是你需要經常運行OPTIMIZE TABLE命令,來恢復被更新機制所浪費的空間。MYISAM還有一些有用的擴展,例如用來修復數據庫文件的MYISAMCHK工具和用來恢復浪費空間的MYISAMPACK工具。

MYISAM強調了快速讀取操作,這可能就是爲什麼MYSQL受到了WEB開發如此青睞的主要原因:在WEB開發中你所進行的大量數據操作都是讀取操作。所以,大多數虛擬主機提供商和INTERNET平臺提供商只允許使用MYISAM格式。

  1. HEAP

HEAP允許只駐留在內存裏的臨時表格。駐留在內存裏讓HEAP要比ISAM和MYISAM都快,但是它所管理的數據是不穩定的,而且如果在關機之前沒有進行保存,那麼所有的數據都會丟失。在數據行被刪除的時候,HEAP也不會浪費大量的空間。HEAP表格在你需要使用SELECT表達式來選擇和操控數據的時候非常有用。要記住,在用完表格之後就刪除表格。

  1. INNODB

INNODB和BERKLEYDB(BDB)數據庫引擎都是造就MYSQL靈活性的技術的直接產品,這項技術就是MYSQL++ API。在使用MYSQL的時候,你所面對的每一個挑戰幾乎都源於ISAM和MYISAM數據庫引擎不支持事務處理也不支持外來鍵。儘管要比ISAM和MYISAM引擎慢很多,但是INNODB和BDB包括了對事務處理和外來鍵的支持,這兩點都是前兩個引擎所沒有的。如前所述,如果你的設計需要這些特性中的一者或者兩者,那你就要被迫使用後兩個引擎中的一個了。

  1. MyISAM和INNODB詳解
  1. InNoDB引擎

Innodb引擎提供了對數據庫ACID事務的支持,並且實現了SQL標準的四種隔離級別,關於數據庫事務與其隔離級別的內容請見數據庫事務與其隔離級別這篇文章。該引擎還提供了行級鎖和外鍵約束,它的設計目標是處理大容量數據庫系統,它本身其實就是基於MySQL後臺的完整數據庫系統,MySQL運行時Innodb會在內存中建立緩衝池,用於緩衝數據和索引。但是該引擎不支持FULLTEXT類型的索引,而且它沒有保存表的行數,當SELECT COUNT(*) FROM TABLE時需要掃描全表。當需要使用數據庫事務時,該引擎當然是首選。由於鎖的粒度更小,寫操作不會鎖定全表,所以在併發較高時,使用Innodb引擎會提升效率。但是使用行級鎖也不是絕對的,如果在執行一個SQL語句時MySQL不能確定要掃描的範圍,InnoDB表同樣會鎖全表。

名詞解析:

ACID

A  事務的原子性(Atomicity):指一個事務要麼全部執行,要麼不執行.也就是說一個事務不可能只執行了一半就停止了.比如你從取款機取錢,這個事務可以分成兩個步驟:1劃卡,2出錢.不可能劃了卡,而錢卻沒出來.這兩步必須同時完成.要麼就不完成.

C 事務的一致性(Consistency):指事務的運行並不改變數據庫中數據的一致性.例如,完整性約束了a+b=10,一個事務改變了a,那麼b也應該隨之改變.

I 獨立性(Isolation):事務的獨立性也有稱作隔離性,是指兩個以上的事務不會出現交錯執行的狀態.因爲這樣可能會導致數據不一致.

D 持久性(Durability):事務的持久性是指事務執行成功以後,該事務所對數據庫所作的更改便是持久的保存在數據庫之中,不會無緣無故的回滾.

  1. MyISAM引擎

MyIASM是MySQL默認的引擎,但是它沒有提供對數據庫事務的支持,也不支持行級鎖和外鍵,因此當INSERT(插入)或UPDATE(更新)數據時即寫操作需要鎖定整個表,效率便會低一些。不過和Innodb不同,MyIASM中存儲了表的行數,於是SELECT COUNT(*) FROM TABLE時只需要直接讀取已經保存好的值而不需要進行全表掃描。如果表的讀操作遠遠多於寫操作且不需要數據庫事務的支持,那麼MyIASM也是很好的選擇。

兩種引擎的選擇

大尺寸的數據集趨向於選擇InnoDB引擎,因爲它支持事務處理和故障恢復。數據庫的大小決定了故障恢復的時間長短,InnoDB可以利用事務日誌進行數據恢復,這會比較快。主鍵查詢在InnoDB引擎下也會相當快,不過需要注意的是如果主鍵太長也會導致性能問題,關於這個問題我會在下文中講到。大批的INSERT語句(在每個INSERT語句中寫入多行,批量插入)在MyISAM下會快一些,但是UPDATE語句在InnoDB下則會更快一些,尤其是在併發量大的時候。

 

Index——索引

索引(Index)是幫助MySQL高效獲取數據的數據結構。MyIASM和Innodb都使用了樹這種數據結構做爲索引。下面我接着講這兩種引擎使用的索引結構,講到這裏,首先應該談一下B-Tree和B+Tree。

 

 

MYISAM引擎的索引結構

MyISAM引擎的索引結構爲B+Tree,其中B+Tree的數據域存儲的內容爲實際數據的地址,也就是說它的索引和實際的數據是分開的,只不過是用索引指向了實際的數據,這種索引就是所謂的非聚集索引。如下圖所示:

這裏設表一共有三列,假設我們以Col1爲主鍵,則上圖是一個MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件僅僅保存數據記錄的地址。在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重複。如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示:

 

同樣也是一顆B+Tree,data域保存數據記錄的地址。因此,MyISAM中索引檢索的算法爲首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然後以data域的值爲地址,讀取相應數據記錄

 

 

Innodb引擎的索引結構

與MyISAM引擎的索引結構同樣也是B+Tree,但是Innodb的索引文件本身就是數據文件,即B+Tree的數據域存儲的就是實際的數據,這種索引就是聚集索引。這個索引的key就是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

並且和MyISAM不同,InnoDB的輔助索引數據域存儲的也是相應記錄主鍵的值而不是地址,所以當以輔助索引查找時,會先根據輔助索引找到主鍵,再根據主鍵索引找到實際的數據。所以Innodb不建議使用過長的主鍵,否則會使輔助索引變得過大。建議使用自增的字段作爲主鍵,這樣B+Tree的每一個結點都會被順序的填滿,而不會頻繁的分裂調整,會有效的提升插入數據的效率。

兩者區別:

第一個重大區別是InnoDB的數據文件本身就是索引文件。從上文知道,MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。而在InnoDB中,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引。

 

上圖是InnoDB主索引(同時也是數據文件)的示意圖,可以看到葉節點包含了完整的數據記錄。這種索引叫做聚集索引。因爲InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作爲主鍵,如果不存在這種列,則MySQL自動爲InnoDB表生成一個隱含字段作爲主鍵,這個字段長度爲6個字節,類型爲長整形。

第二個與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作爲data域。例如,下圖爲定義在Col3上的一個輔助索引:

這裏以英文字符的ASCII碼作爲比較準則。聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然後用主鍵到主索引中檢索獲得記錄。

瞭解不同存儲引擎的索引實現方式對於正確使用和優化索引都非常有幫助,例如知道了InnoDB的索引實現後,就很容易明白爲什麼不建議使用過長的字段作爲主鍵,因爲所有輔助索引都引用主索引,過長的主索引會令輔助索引變得過大。再例如,用非單調(可能是指“非遞增”的意思)的字段作爲主鍵在InnoDB中不是個好主意,因爲InnoDB數據文件本身是一顆B+Tree,非單調(可能是指“非遞增”的意思)的主鍵會造成在插入新記錄時數據文件爲了維持B+Tree的特性而頻繁的分裂調整,十分低效,而使用自增字段作爲主鍵則是一個很好的選擇。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章