表類型(存儲引擎)的選擇
7.1 mysql存儲引擎概述
插件式存儲引擎是mysql數據庫最重要的特性之一,用戶可以根據應用的需要選擇ruhr存儲和索引數據,是否使用事務等。
InnoDB和BDB提供事務安全表,其他存儲引擎都是非事務安全表
創建新表時如果不指定存儲引擎,那么系統就會使用默認存儲引擎,mysql5.5之前的默認引擎時MyISAM,之后是InnoDB(關鍵字:ENGINE)
7.2 各種存儲引擎的特性
7.2.1 MyISAM
缺點:不支持事務,也不支持外鍵
優點:訪問速度快,對事務的完整性沒有要求或者以select、insert為主的應用基本上都可以使用這個引擎來創建
MyISAM再磁盤上存儲成三個文件,其文件名都和表名相同,但擴展名分別是:.frm(存儲表定義),.MYD(存儲數據),.MYI(存儲索引)
數據文件和索引文件可以放置在不同的目錄,平均分布IO,獲得更快的速度。通過(創建表時DATA DIRECTORY和INDEX DIRECTORY(需要時據對路徑,和訪問權限))
MyISAM類型的表可能會損壞,原因可能是多種多樣,check table ,repair table。
表損壞可能導致數據庫異常重新啟動,需要盡快修復並盡可能地確認損壞的原因。
MyISAM表嗨支持3中不同的存儲格式:1.靜態(固定長度)表 2.動態表 3.壓縮表
靜態表是默認的存儲格式。靜態表中的字段都是非變長字段,這樣每個記錄都是固定長度,這種存儲的優點是存儲非常迅速,容易緩存,出現故障容易恢復;缺點是占用的空間通常比動態表多。靜態表的數據再存儲時會按照列的寬度定義補足空格,但是在應用訪問的時候不會得到這些空格。但是需要特別注意的問題,如果需要保存的內容后面本來就有空格,那么在返回的時候也會被去掉。
動態表中包含變長的字段,記錄不是固定長度的。這樣優點是節省存儲空間,但是頻繁的更新和刪除記錄會產生碎片,需要定期執行optimize table 或 myisamchk-r命令來改善性能,並且在出現故障時恢復起來比較困難。
壓縮表由myisampack工具創建,占據非常小的磁盤空間,因為每個記錄是被單獨壓縮的,所以只有非常小的訪問開支。
7.2.2 InnoDB
InnoDB存儲引擎提供了具有提交、回滾和崩潰恢復能力的事務安全。但是對比MyISAM,處理效率差一些,並且會占用更多的磁盤空間以保留數據和索引。
1.自動增長列
如果插入的是空或者0,則實際插入的僵屍自動增長后的值。通過“alter table *** auto_increment = n”語句強制設置自動增長列的初始值,如果在使用之前重新啟動數據庫,則需要重新設置,不設置默認初始值為1.對於InnoDB表來說自動增長列必須是索引。如果是組合索引,也必須是組合索引的第一列,但是對於MyISAM表,自動增長列可以是組合索引的其他列,這樣插入記錄后,自動增長列按照組合索引前面幾列進行排序后遞增的。
2.外鍵約束
MySQL支持外鍵的存儲引擎只有InnoDB,在創建外鍵的時候,要求父表必須有對應的索引,字表在創建外鍵的時候也會自動創建對應的索引。
當某個表被其他表創建的外鍵參照,那么該表的對應索引或者主鍵禁止被刪除。
在導入多個表的數據時,如果需要忽略表之前的導入順序,可以暫時關閉外鍵的檢查,在處理LOAD DATA 和 ALTER TABLE操作的時候,可以關閉外鍵約束來加快處理速度,“set foreign_key_checks = 0(1開)”
對於InnoDB類型的表,外鍵信息通過使用show create table 或者 show table status命令顯示
3.存儲方式
InnoDB存儲表和索引有以下兩種方式。
使用共享表空間存儲,這種方式創建的表的表結構保存在.frm文件中,數據和索引保存在innodb_data_home_dir和innodb_data_file_path定義的表空間中,可以是多個文件。
使用多表空間存儲,這種方式創建的表的表結構仍然保存在.frm文件中,但是每個表的數據和索引單獨保存在.ibd中。如果是分區表,則每個分區對應單獨的.ibd文件,文件名是“表名+分區名”,可以在創建分區的時候指定每個分區的數據文件的位置,一次來將表的IO均勻的分布在多個磁盤上。要使用多表空間的存儲方式,需要設置參數innodb_file_per_table,並且重啟服務才能生效,對於新建的表按照多表空間的方式創建,已經有的仍然使用共享表空間存儲。多表空間的數據文件沒有大小限制,不需要設置初始化大小,也不需要設置文件的最大限制、擴展大小等參數。對於使用多表空間特性的表,可以比較方便地進行單表備份和恢復操作,
7.2.3 MEMORY
MEMORY存儲引擎使用存在於內存中的內容來創建表。每個MEMORY表只實際對應一個磁盤文件,格式是.frm。MEMORY類型的表訪問非常地快,因為它的數據是放在內存中的,並且默認使用HASH索引,但是一旦服務關閉,表中的數據就會丟掉。服務器需要足夠的內存來維持所有在同一時間使用的MEMORY表,當不再需要MEMORY表的內容是釋放資源。每個MEMORY表中可以放置的數據量的大小,收到max_heap_table_size系統變量的約束,這個系統變量的初始值是16MB,通過MAX_ROWS指定表的最大行。
MEMORY類型的存儲引擎主要用於那些內容變化不頻繁的代碼表,或者作為統計操作的中間結果表,便於高效地對中間結果進行分析並得到最終的統計結果。對存儲引擎為MEMORY的表進行更新操作要謹慎,因為數據沒有寫到磁盤中,所以一定要對下次重啟服務后如何獲得這些修改后的數據。
7.2.4 MERGE
MERGE存儲引擎是一組MyISAM表的組合,這些MyISAM表必須結構相同,MERGE表本生沒有數據結構,對MERGE類型可以進行查詢、更新、刪除操作,這些操作實際上是對內部的MyISAM表進行的
對MERGE類型表進行插入操作,是通過INSERT_METHOD子句定義插入的表,可以有3個不同的值,first、no、last。當不定義或者為no時,不能對表進行進行插入操作。
對MERGE表進行drop操作實際上只是刪除MERGE的定義,對內部的表沒有任何影響。
MERGE表在磁盤上保留兩個文件,.frm文件存儲表的定義,.MRG文件包含組合表的信息,包括MERGE表由哪些表組成、插入新的數據時的依據。可以通過修改.MRG文件來修改MERGE表,但是修改后要通過flush tables刷新
7.2.4 TokuDB
第三方常用的存儲引擎:列式存儲引擎infobright,高寫性能高壓縮的TokuDB
TokuDB是一個高性能、支持事務處理的Mysql和MariaDB的存儲引擎,具有高擴展性、高壓縮率、高效的寫入性能,支持大多數在線DDL操作。
特性:
使用Fractal樹索引保證高效的插入性能
優秀的壓縮特性,比InnoDB高近10倍
Hot Schema Changes特性支持在線創建索引和添加、刪除屬性列等DDL操作
使用Bulk Loader達到快速加載大量數據
提供主從延遲消除技術
支持ACID(指數據庫事務正確執行的四個基本要素的縮寫。包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability))和MVCC(多版本並發控制)
使用場景:
日志數據,因為日志通常插入頻繁且存儲量大
歷史數據,通常不會再有寫操作,可以利用TokuDB的高性能壓縮特性進行存儲
在線DDL比較頻繁的場景,使用TokuDB可以大大增加系統的可用性。
7.2 如何選擇合適的存儲引擎
在選擇存儲引擎時,應根據應用特點選擇合適的存儲引擎。對於復雜的應用系統,還可以根據實際情況選擇多種存儲引擎進行組合。
MyISAM:默認的Mysql插件式存儲引擎(5.5之前)。如果應用是以讀操作和插入操作為主,只有少量的更新和刪除操作,並且對事務的完整性、並發性要求不是很高,那么選擇這個存儲引擎非常合適。例如:Web、數據倉庫和其他應用環境下最常用的存儲引擎之一
InnoDB:用於處理事務應用程序,支持外鍵。如果應用對事務的完整性有較高的要求,在並發條件下要求數據的一致性,數據除了插入查詢之外,還包括很多的更新、刪除操作,那么InnoDB存儲引擎應該是比較合適的。InnoDB存儲引擎除了有效的降低由於刪除和更新導致的鎖定,還可以確保事務的完整的提交和回滾,對於類似計費系統或者財務系統等對數據准確性要求比較高的系統,InnoDB都是合適的選擇。
MEMORY:將所有的數據保存在RAM中,在需要快速定位記錄和其他類似數據的環境下,可提供幾塊的訪問,MEMORY的缺陷是對表的大小有限制,太大的表無法緩存在內存中,其次是要確保表的數據可以恢復,數據庫異常終止后表中的數據數據是可以恢復的。MEMORY表通常更新不太頻繁的小表,用以快速得到訪問結果。
MERGE:用於將一系列的MyISA表以邏輯方式組合在一起,並作為一個對象引用它們。有點突破了單個MyISAM表大小的限制,並且通過將不同的表分布在多個磁盤上,可以有效地改善MERGE表的訪問效率。這對於數據倉庫等VLDB(超大型數據庫)環境十分合適。