【MySQL基礎】如何選擇儲存引擎
引入
在介紹儲存引擎之前,先來回顧一下索引的相關知識。
索引是對資料庫表中一個或多個列的值進行排序的結構,建立索引有助於更快地獲取資訊。
mysql 有四種不同的索引型別:
- 主鍵索引 ( PRIMARY )
- 唯一索引 ( UNIQUE )
- 普通索引 ( INDEX )
- 全文索引(FULLTEXT , MYISAM 及 mysql 5.6 以上的 Innodb )
建立索引的目的是加快對錶中記錄的查詢或排序,索引也並非越多越好,因為建立索引是要付出代價的:增加了資料庫的儲存空間,在插入和修改資料時要花費較多的時間維護索引。
在設計表或索引時,常出現以下幾個問題:
- 少建索引或不建索引。這個問題最突出,建議建表時 DBA 可以一起協助把關。
- 索引濫用。濫用索引將導致寫請求變慢,拖慢整體資料庫的響應速度(5.5 以下的 mysql 只能用到一個索引)。
- 從不考慮聯合索引。實際上聯合索引的效率往往要比單列索引的效率更高。
- 非最優列選擇。低選擇性的欄位不適合建單列索引,如 status 型別的欄位。
什麼是儲存引擎?
MySQL資料庫表是用於儲存和組織資訊的資料結構,可以將表理解為由行和列組成的表格,類似於Excel的電子表格的形式。有的表簡單,有的表複雜,有的表根本不用來儲存任何長期的資料,有的表讀取時非常快,但是插入資料時去很差;
而我們在實際開發過程中,就可能需要各種各樣的表,不同的表,就意味著儲存不同型別的資料,資料的處理上也會存在著差異,
對於MySQL來說,它提供了很多種型別的儲存引擎,我們可以根據對資料處理的需求,選擇不同的儲存引擎,從而最大限度的利用MySQL強大的功能。
資料庫管理系統(DBMS)使用資料引擎進行建立、查詢、更新和刪除資料。不同的儲存引擎提供不同的儲存機制、索引技巧、鎖定水平等功能,使用不同的儲存引擎,還可以 獲得特定的功能。現在許多不同的資料庫管理系統都支援多種不同的資料引擎。MySQL的核心就是儲存引擎
儲存引擎的介紹
1.檢視儲存引擎
- mysql給開發者提供了查詢儲存引擎的功能,我使用的是MySQL5.5,使用命令SHOW ENGINES;可以檢視儲存引擎。如下圖:
分析:從圖中可以看出,MySQL支援多種儲存引擎,而預設的儲存引擎是InnoDB。
- 我還可以檢視當前表的儲存引擎,使用命令show create table student;檢視,如下圖
分析:從上圖可以看出student表的儲存引擎是InnoDB
2.MyISAM
(1)定義
MyISAM表是獨立於作業系統的,這說明可以輕鬆地將其從Windows伺服器移植到Linux伺服器;每當我們建立一個MyISAM引擎的表時,就會在本地磁碟上建立三個檔案,檔名就是表明。
MyISAM表無法處理事務,這就意味著有事務處理需求的表,不能使用MyISAM儲存引擎。
(2)MyISAM的表支援3中不同的儲存格式,分別是靜態(固定長度)表、動態表、壓縮表,其中,靜態表是預設的儲存格式。
靜態表中的欄位都是非變長欄位,這樣每個記錄都是固定長度的,
- 優點是儲存非常迅速,容易快取,出現故障容易修復;
- 缺點是佔用的空間通常比動態多。靜態表的資料在儲存時會按列的寬度定義補足空格,但是在應用訪問的時候並不會得到這些空格,這些空格在返回給應用之前已經去掉。
動態表中包含變長欄位,記錄不是固定長度的,
- 優點是佔用的空間相對較少,
- 缺點是頻繁的更新和刪除記錄會產生碎片,需要定期執行 OPTIMIZE TABLE語句或myisamchk -r命令來改善效能,在出現故障時恢復相對比較困難
壓縮表由myisam工具建立,佔據非常小的磁碟空間。因為每個記錄是被單獨壓縮的,所有隻有非常小的訪問開支
(3)特點
- 大檔案(達到63位檔案長度)在支援大檔案的檔案系統和作業系統上被支援
當把刪除和更新及插入操作混合使用的時候,動態尺寸的行產生更少碎片。這要通過合併相鄰被刪除的塊,以及若下一個塊被刪除,就擴充套件到下一塊自動完成
每個MyISAM表最大索引數是64,這可以通過重新編譯來改變。每個索引最大的列數是16
最大的鍵長度是1000位元組,這也可以通過編譯來改變,對於鍵長度超過250位元組的情況,一個超過1024位元組的鍵將被用上
BLOB和TEXT列可以被索引
NULL被允許在索引的列中,這個值佔每個鍵的0~1個位元組
所有數字鍵值以高位元組優先被儲存以允許一個更高的索引壓縮
每個MyISAM型別的表都有一個AUTO_INCREMENT的內部列,當INSERT和UPDATE操作的時候該列被更新,同時AUTO_INCREMENT列將被重新整理。所以說,MyISAM型別表的AUTO_INCREMENT列更新比InnoDB型別的AUTO_INCREMENT更快
可以把資料檔案和索引檔案放在不同目錄
每個字元列可以有不同的字符集
有VARCHAR的表可以固定或動態記錄長度
VARCHAR和CHAR列可以多達64KB
(4)適用場景
選擇密集型的表。MyISAM儲存引擎在篩選大量資料時非常迅速,這是它最突出的優點。
插入密集型的表。MyISAM的併發插入特性允許同時選擇和插入資料。例如:MyISAM儲存引擎很適合管理郵件或Web伺服器日誌資料。
3.InnoDB
(1)定義
InnoDB是一個健壯的事務型儲存引擎,這種儲存引擎已經被很多網際網路公司使用,為使用者操作非常大的資料儲存提供了一個強大的解決方案。
(2)特點
InnoDB是預設的儲存引擎。
InnoDB還引入了行級鎖定和外來鍵約束,
(3)適用場合
更新密集的表。InnoDB儲存引擎特別適合處理多重併發的更新請求。
事務:InnoDB儲存引擎是支援事務的標準MySQL儲存引擎。
自動災難恢復。與其它儲存引擎不同,InnoDB表能夠自動從災難中恢復。
外來鍵約束。MySQL支援外來鍵的儲存引擎只有InnoDB。
支援自動增加列AUTO_INCREMENT屬性。
4.MEMORY
(1)定義
使用MySQL Memory儲存引擎的出發點是速度。為得到最快的響應時間,採用的邏輯儲存介質是系統記憶體。
(2)特點
在記憶體中儲存表資料會提供很高的效能,但當mysqld守護程序崩潰時,所有的Memory資料都會丟失。獲得速度的同時也帶來了一些缺陷。
它要求儲存在Memory資料表裡的資料使用的是長度不變的格式,這意味著不能使用BLOB和TEXT這樣的長度可變的資料型別,VARCHAR是一種長度可變的型別,但因為它在MySQL內部當做長度固定不變的CHAR型別,所以可以使用。
Memory同時支援雜湊索引和B樹索引。B樹索引的優於雜湊索引的是,可以使用部分查詢和通配查詢,也可以使用<、>和>=等操作符方便資料探勘。雜湊索引進行“相等比較”非常快,但是對“範圍比較”的速度就慢多了,因此雜湊索引值適合使用在=和<>的操作符中,不適合在<或>操作符中,也同樣不適合用在order by子句中。
(3)使用場景
目標資料較小,而且被非常頻繁地訪問。在記憶體中存放資料,所以會造成記憶體的使用,可以通過引數max_heap_table_size控制Memory表的大小,設定此引數,就可以限制Memory表的最大大小。
如果資料是臨時的,而且要求必須立即可用,那麼就可以存放在記憶體表中。
儲存在Memory表中的資料如果突然丟失,不會對應用服務產生實質的負面影響。
5.MERGE
(1)定義
MERGE儲存引擎是一組MyISAM表的組合,這些MyISAM表結構必須完全相同,儘管其使用不如其它引擎突出,但是在某些情況下非常有用。
Merge表就是幾個相同MyISAM表的聚合器;
Merge表中並沒有資料,對Merge型別的表可以進行查詢、更新、刪除操作,這些操作實際上是對內部的MyISAM表進行操作。
(2)特點
MEMORY表的每個表可以有多達32個索引,每個索引16列,以及500位元組的最大鍵長度
MEMORY儲存引擎執行HASH和BTREE縮影
可以在一個MEMORY表中有非唯一鍵值
MEMORY表使用一個固定的記錄長度格式
MEMORY不支援BLOB或TEXT列
MEMORY支援AUTO_INCREMENT列和對可包含NULL值的列的索引
MEMORY表在所由客戶端之間共享(就像其他任何非TEMPORARY表)
MEMORY表記憶體被儲存在記憶體中,記憶體是MEMORY表和伺服器在查詢處理時的空閒中,建立的內部表共享
當不再需要MEMORY表的內容時,要釋放被MEMORY表使用的記憶體,應該執行DELETE FROM或TRUNCATE TABLE,或者刪除整個表(使用DROP TABLE)
(3)適用場景
對於伺服器日誌資訊,一般常用的儲存策略是將資料分成很多表,每個名稱與特定的時間端相關。
例如:可以用12個相同的表來儲存伺服器日誌資料,每個表用對應各個月份的名字來命名。當有必要基於所有12個日誌表的資料來生成報表,這意味著需要編寫並更新多表查詢,以反映這些表中的資訊。與其編寫這些可能出現錯誤的查詢,不如將這些表合併起來使用一條查詢,之後再刪除Merge表,而不影響原來的資料,刪除Merge表只是刪除Merge表的定義,對內部的表沒有任何影響。
6.ARCHIVE
Archive是歸檔的意思,
在歸檔之後很多的高階功能就不再支援了,僅僅支援最基本的插入和查詢兩種功能。
Archive在MySQL 5.5之後的版本支援索引。
Archive擁有很好的壓縮機制,它使用zlib壓縮庫,在記錄被請求時會實時壓縮,
Archive經常被用來當做倉庫使用。
四種儲存引擎的異同
功 能 | MYISAM | Memory | InnoDB | Archive |
---|---|---|---|---|
儲存限制 | 256TB | RAM | 64TB | None |
支援事物 | No | No | Yes | No |
支援B樹索引 | Yes | Yes | Yes | Yes |
支援全文索引 | Yes | No | No | No |
支援數索引 | Yes | Yes | Yes | No |
支援雜湊索引 | No | Yes | No | No |
支援資料快取 | No | N/A | Yes | No |
支援外來鍵 | No | No | Yes | No |
鎖機制 | 表鎖 | 表鎖 | 行鎖 | 表鎖 |
儲存引擎的適用場景
如果應用是以讀操作和插入操作為主,只有很少的更新和刪除操作,並且對事務的完整性,併發性要求不是很高,那麼選擇這個儲存引擎是非常適合的。MyISAM是在Web、資料倉庫和其他應用環境下最常使用的儲存引擎之一。
如果應用對事物的完整性有比較高的要求,在併發條件下要求資料的一致性, 資料操作除了插入和查詢以外,還能包括很多的更新、刪除操作,那麼InnoDB儲存引擎應該是比較合適的選擇。InnoDB儲存引擎除了有效地降低由類似計費系統或者財務系統等對資料準確性要求比較高的系統,InnoDB都是合適的選擇。
如果只是臨時存放資料,資料量不大,並且不需要較高的資料安全性,可以選擇將資料儲存在記憶體中的Memory引擎,MySQL中使用該引擎作為臨時表,存放查詢的中間結果
如果是資料倉儲等VLDB環境,適合使用MERGE
如果只有INSERT和SELECT操作,可以選擇Archive,Archive支援高併發的插入操作,但是本身不是事務安全的。Archive非常適合儲存歸檔資料,如記錄日誌資訊可以使用Archive
儲存引擎的實現方式
1.MyISAM
MyISAM引擎使用B+ Tree作為索引結構,葉節點存放的是資料記錄的地址。
MyISAM引擎的輔助索引(二級索引)和主索引在結構上沒有區別,只是輔助索引的key可以重複,葉節點上存放的也是資料記錄的地址。
MyISAM引擎的索引結構為B+Tree,其中B+Tree的資料域儲存的內容為實際資料的地址,也就是說它的索引和實際的資料是分開的,只不過是用索引指向了實際的資料,這種索引就是所謂的非聚集索引。
2.InnoDB
InnoDB中表資料本身就是按B+ Tree組織的一個索引結構,葉節點存放的就不是資料記錄的地址,而是完整的資料記錄。所以InnoDB這種儲存方式,又稱為聚集索引,使得按主鍵的搜尋十分高效,但二級索引搜尋需要檢索兩遍索引:首先二級索引獲得主鍵,然後用主鍵到主索引中檢索到資料記錄。
因為主鍵是InnoDB表記錄的”邏輯地址“,所以InnoDB要求表必須有主鍵,MyISAM可以沒有。
3.MySQL為什麼使用B+樹作為索引?
(1)為什麼不用hash表儲存?
B樹適合在磁碟等直接儲存裝置上組織動態查詢表,檔案的組織方式便是B樹或B+樹。他在查詢和動態操作方面效率很高。
但是hash表的效率更高,可是hash表第一存在雜湊衝突問題,這個必須解決;第二hash表的一般利用率僅為50%,這就會佔用大量的儲存空間而實際應用的空間卻不多。
B樹和hash表都很靈活適用於多表查詢和儲存,可是當儲存比例達到一定程度時hash表必須進行擴容才能維持之後的操作,而B樹不用。
(2)如何選擇資料結構?
一般來說,索引本身也很大,不可能全部儲存在記憶體中,因此索引往往以索引檔案的形式儲存的磁碟上。
索引查詢過程中就要產生磁碟I/O消耗,相對於記憶體存取,I/O存取的消耗要高几個數量級,
評價一個數據結構作為索引的優劣最重要的指標就是在查詢過程中磁碟I/O操作次數的漸進複雜度。換句話說,索引的結構組織要儘量減少查詢過程中磁碟I/O的存取次數。
4.聚集索引
聚集索引對於那些經常要搜尋範圍值的列特別有效。使用聚集索引找到包含第一個值的行後,便可以確保包含後續索引值的行在物理相鄰。
例如,如果應用程式執行 的一個查詢經常檢索某一日期範圍內的記錄,則使用聚集索引可以迅速找到包含開始日期的行,然後檢索表中所有相鄰的行,直到到達結束日期。這樣有助於提高此 類查詢的效能。同樣,如果對從表中檢索的資料進行排序時經常要用到某一列,則可以將該表在該列上聚集(物理排序),避免每次查詢該列時都進行排序,從而節 省成本。
本人才疏學淺,若有錯,請指出,謝謝!
如果你有更好的建議,可以留言我們一起討論,共同進步!
衷心的感謝您能耐心的讀完本篇博文!