?數(shù)據(jù)庫(kù)存儲(chǔ)引擎,是不同的存儲(chǔ)技術(shù)將數(shù)據(jù)存儲(chǔ)在文件或者內(nèi)存當(dāng)中,這些存儲(chǔ)引擎當(dāng)中每種都會(huì)使用不同的技術(shù)來(lái)進(jìn)行數(shù)據(jù)的存儲(chǔ),索引技巧實(shí)現(xiàn),或者說(shuō)數(shù)據(jù)庫(kù)鎖的實(shí)現(xiàn),通過(guò)這些不同的技巧來(lái)最終達(dá)到一定的效果。
? ?主要來(lái)看下我們比較經(jīng)常使用的InnerDB
? ?InnerDB
? ? ? ?InnerDB是一個(gè)事務(wù)型的存儲(chǔ)引擎,主要是目的是大數(shù)據(jù)時(shí)提供高性能的數(shù)據(jù)服務(wù),在運(yùn)行時(shí)在內(nèi)存當(dāng)中建立緩沖池,用來(lái)緩沖數(shù)據(jù)和索引。
InnerDB的特點(diǎn):
1、支持事務(wù)處理、ACID事務(wù)特性
2、實(shí)現(xiàn)了SQL標(biāo)準(zhǔn)的四種隔離級(jí)別
3、支持行級(jí)鎖和外鍵約束
4、可以利用事務(wù)日志進(jìn)行數(shù)據(jù)恢復(fù)
5、不支持FullText類(lèi)型的索引,沒(méi)有保存數(shù)據(jù)庫(kù)行數(shù),計(jì)算count(*)需要全局掃描
6、支持自動(dòng)增加列屬性auto_increment
7、最后也是非常重要的一點(diǎn):InnerDB是為了處理大量數(shù)據(jù)時(shí)的最大性能設(shè)計(jì),其CPU效率可能是其他基于磁盤(pán)的關(guān)系型數(shù)據(jù)庫(kù)所不能匹敵的。
在以下兩點(diǎn)情況下必須使用InnerDB
1、可靠性高或者必須要求事務(wù)處理
2、表更新和查詢(xún)相當(dāng)?shù)念l繁,并且表鎖定的機(jī)會(huì)比較大的情況下,指定InnerDB存儲(chǔ)引擎。
InnerDB引擎的索引實(shí)現(xiàn):
? ?InnerDB引擎的索引結(jié)構(gòu)是B+樹(shù)的實(shí)現(xiàn)方式。InnerDB的索引文件存儲(chǔ)的包括數(shù)據(jù)文件,所以B+Tree樹(shù)當(dāng)中葉子節(jié)點(diǎn)中存儲(chǔ)的就是實(shí)際數(shù)據(jù),其實(shí)這種索引就是聚集索引。
? ?InnerDB的輔助索引存儲(chǔ)域存儲(chǔ)的也是記錄相應(yīng)主鍵的值不是地址,所以當(dāng)使用輔助索引查找時(shí),會(huì)先通過(guò)輔助索引找到主鍵,再根據(jù)主鍵索引找到實(shí)際的數(shù)據(jù)。InnerDB不建議使用過(guò)長(zhǎng)的主鍵,否則會(huì)使輔助索引變得很大。
? ?因?yàn)镮nnerDB的數(shù)據(jù)本身要按照主鍵進(jìn)行聚集,所以InnerDB必須要有主鍵,如果沒(méi)有顯示指定,InnerDB會(huì)自動(dòng)選擇可以唯一標(biāo)識(shí)的列作為主鍵,如果不存在這樣的列,InnerDB會(huì)隱式生成一個(gè)隱含字段,作為主鍵。
? ?InnerDB的輔助索引data域當(dāng)中存儲(chǔ)的值是主鍵的值而不是地址,InnerDB的輔助索引都是用主鍵作為data域。
? ?InnerDB引擎索引的查找步驟為:將主鍵組織到B+樹(shù)上,行數(shù)據(jù)存儲(chǔ)在B+樹(shù)的葉子節(jié)點(diǎn)上,如果使用主鍵檢索,會(huì)通過(guò)主鍵檢索到葉子節(jié)點(diǎn),然后獲得行數(shù)據(jù)。如果對(duì)name進(jìn)行檢索,會(huì)在輔助索引B+樹(shù)上檢索name,找到其葉子節(jié)點(diǎn),獲得相應(yīng)的主鍵,第二步使用主鍵在B+樹(shù)當(dāng)中再執(zhí)行一次檢索,最終到達(dá)葉子節(jié)點(diǎn),獲取整行數(shù)據(jù)。
MyISAM存儲(chǔ)引擎
? ? MyISAM是Mysql的默認(rèn)引擎,其目標(biāo)是快速讀取。
MyISAM引擎的特點(diǎn):
1、快速讀取,如果頻繁插入和更新的話,因?yàn)樯婕暗綌?shù)據(jù)全表鎖,效率并不高
2、保存了數(shù)據(jù)庫(kù)行數(shù),執(zhí)行count時(shí),不需要掃描全表;
3、不支持?jǐn)?shù)據(jù)庫(kù)事務(wù);
4、不支持行級(jí)鎖和外鍵;
5、不支持故障恢復(fù)。
6、支持全文檢索FullText,壓縮索引。
MyISAM建議使用場(chǎng)景:
1、做很多count計(jì)算的,(如果count計(jì)算后面有where還是會(huì)全表掃描)
2、插入和更新較少,查詢(xún)比較頻繁的
? ? ? MyISAM引擎在創(chuàng)建表的時(shí)候,會(huì)創(chuàng)建三個(gè)文件,.frm文件,存儲(chǔ)表的定義,.myd存儲(chǔ)數(shù)據(jù)庫(kù)數(shù)據(jù),.myi存儲(chǔ)數(shù)據(jù)索引。
? ? ?MyISAM的索引和數(shù)據(jù)是分開(kāi)的,并且索引是有壓縮的,所以存儲(chǔ)文件就會(huì)小很多,MyISAM應(yīng)對(duì)錯(cuò)誤碼導(dǎo)致的數(shù)據(jù)恢復(fù)的速度很快,MyISAM數(shù)據(jù)是以文件的形式保存的,所以在跨平臺(tái)當(dāng)中數(shù)據(jù)移動(dòng)很方便,
MyISAM索引實(shí)現(xiàn):
? ? MyISAM引擎當(dāng)中的索引也是采用B+樹(shù)的方式,MyISAM當(dāng)中節(jié)點(diǎn)的鍵值指向的地址,地址當(dāng)中存儲(chǔ)的數(shù)據(jù)
? ? B+樹(shù)當(dāng)中存儲(chǔ)的內(nèi)容為實(shí)際數(shù)據(jù)的地址,也就是索引和數(shù)據(jù)的存儲(chǔ)是分開(kāi)的,即非聚集索引的一種實(shí)現(xiàn)方式。MyISAM引擎中根據(jù)索引的搜查方式是,根究給定的條件基于索引查找,找到葉子節(jié)點(diǎn)當(dāng)中的數(shù)據(jù)地址,然后再根據(jù)數(shù)據(jù)地址查找到數(shù)據(jù)。
Mrg_MyISAM存儲(chǔ)引擎
? ?Mrg_MyISAM是一種水平分表的一種方式,Mrg_MyISAM是一組MyISAM引擎的組合,將多個(gè)MyISAM引擎聚合起來(lái),但是其內(nèi)部沒(méi)有數(shù)據(jù),數(shù)據(jù)保存在MyISAM引擎對(duì)應(yīng)的數(shù)據(jù)庫(kù)當(dāng)中,但是可以直接進(jìn)行查詢(xún),刪除更新操作。
? ?比如用戶(hù)表,我們有上億的用戶(hù),這個(gè)時(shí)候,對(duì)用戶(hù)表進(jìn)行水平切分,分成user1,user2,并且兩張表結(jié)構(gòu)完全相同,
//用戶(hù)表一
CREATE TABLE IF NOT EXISTS `user1` (?
`id` int(11) NOT NULL ,
`name` varchar(50) DEFAULT NULL,?
PRIMARY KEY (`id`)?
) ENGINE=MyISAM? DEFAULT CHARSET=utf8 ;?
//用戶(hù)表二
CREATE TABLE IF NOT EXISTS `user2` (?
`id` int(11) NOT NULL ,
`name` varchar(50) DEFAULT NULL,?
PRIMARY KEY (`id`)?
) ENGINE=MyISAM? DEFAULT CHARSET=utf8 ;?
//分別插入兩條測(cè)試數(shù)據(jù)先
INSERT INTO `user1` (`name`) VALUES('輔助');?
INSERT INTO `user2` (`name`) VALUES('JackFrost');
接下來(lái)我們創(chuàng)建一個(gè)Mrg_MyISAM存儲(chǔ)引擎的數(shù)據(jù)表
CREATE TABLE IF NOT EXISTS `alluser` (?
? `id` int(11) NOT NULL ,?
? `name` varchar(50) DEFAULT NULL,?
? PRIMARY KEY (`id`)
) ENGINE=MRG_MYISAM?
DEFAULT CHARSET=utf8
UNION=(user1,user2)? ;?
在查詢(xún)時(shí),只需要查詢(xún)主表,就可以把分表當(dāng)中的數(shù)據(jù)查詢(xún)出來(lái),但是如果插入的時(shí)候,會(huì)提示插入失敗,只有讀權(quán)限,可以修改總表的method權(quán)限,來(lái)執(zhí)行插入操作,同時(shí)也會(huì)指定插入主表時(shí),插入的是具體哪個(gè)分表
ALTER TABLE `test_engine`.`alluser` INSERT_METHOD = FIRST;
也可以設(shè)置成插入總表的時(shí)候,插入到最后的一個(gè)分表當(dāng)中
//就是插入總表的時(shí)候,其實(shí)也是插入到最后一個(gè)分表。
ALTER TABLE `test_engine`.`alluser` INSERT_METHOD = LAST;
在實(shí)際開(kāi)發(fā)當(dāng)中,我們需要有一個(gè)Mrg_MyISAM引擎的表來(lái)保存主鍵,然后我們根據(jù)路由策略來(lái)決定將數(shù)據(jù)保存到哪張表中。
Mrg_MyISAM使用場(chǎng)景:
1、適合插入和查詢(xún)比較高的系統(tǒng),有MyISAM是全表鎖,所以不適合更新比較頻繁的場(chǎng)景。
2、實(shí)際開(kāi)發(fā)當(dāng)中比較適合的就是日志管理,將不同月份的日志保存在不同的表當(dāng)中,然后使用工具壓縮,最后通過(guò)一張表查詢(xún)初出來(lái)。
Mrg_MyISAM使用時(shí)收到的限制:
1、主表必須使用Mrg_MyISAM引擎,子表必須使用MyISAM引擎。可能就會(huì)有部分限制,比如不支持事務(wù)和外鍵
2、主表不能使用MyISAM的特性,比如全文索引,可以為子表創(chuàng)建FullText類(lèi)型的索引,但是查詢(xún)的話只能通過(guò)主表查詢(xún)
3、如果修改主表的存儲(chǔ)引擎,那么主表和子表的映射關(guān)系就丟失了,會(huì)將子表中的數(shù)據(jù)拷貝到修改后的表中
4、主表和字表的主鍵都不能自動(dòng)增長(zhǎng)
5、子表之間不能存在唯一鍵約束,但是單個(gè)子表內(nèi)可以存在唯一鍵,所以通過(guò)主表可能查詢(xún)到重復(fù)的id
Memory存儲(chǔ)引擎
?Memory存儲(chǔ)引擎采用邏輯介質(zhì)是內(nèi)存,因此其訪問(wèn)速度會(huì)非??欤淠J(rèn)使用的是hash索引,一旦服務(wù)關(guān)掉,數(shù)據(jù)就會(huì)丟失。Memory存儲(chǔ)引擎要求存儲(chǔ)的數(shù)據(jù)是長(zhǎng)度不變的格式,比如blob和text類(lèi)型都不可以
適合的場(chǎng)景:
1、適合保存目標(biāo)數(shù)據(jù)比較小,并且頻繁進(jìn)行訪問(wèn)的,如果太大的話,容易造成內(nèi)存溢出,通過(guò)max_heap_table_size來(lái)設(shè)定表的大??;
2、存儲(chǔ)在Memory引擎的表中的數(shù)據(jù),如果丟失也沒(méi)有關(guān)系的
3、如果數(shù)據(jù)是臨時(shí)的,必須立刻用的到,那么可以存在內(nèi)存當(dāng)中。
? ?Memory存儲(chǔ)引擎支持hash索引和B樹(shù)索引,hash索引用來(lái)比較相等會(huì)比較快,范圍查找會(huì)比較慢,B樹(shù)索引可以部分查詢(xún)和通配查詢(xún),也可以使用<,>,= 等方便數(shù)據(jù)挖掘。
? Memory存儲(chǔ)引擎創(chuàng)建的表,最好是使用完之后,就刪除。
以上就是關(guān)于常用的數(shù)據(jù)庫(kù)引擎的記錄,如有錯(cuò)誤,歡迎指正~
參考:MySQL存儲(chǔ)引擎InnoDB和MyISAM區(qū)別及使用場(chǎng)景
? ? ? ? ??MySQL優(yōu)化系列(五)--數(shù)據(jù)庫(kù)存儲(chǔ)引擎(主要分析對(duì)比InnoDB和MyISAM以及講述Mrg_Myisam分表)