7.存儲引擎

1. 存儲引擎概述

和大多數(shù)的數(shù)據(jù)庫不同, MySQL中有一個存儲引擎的概念, 針對不同的存儲需求可以選擇最優(yōu)的存儲引擎。

存儲引擎就是存儲數(shù)據(jù),建立索引涕蚤,更新查詢數(shù)據(jù)等等技術(shù)的實現(xiàn)方式 。存儲引擎是基于表的,而不是基于庫的烹骨。所以存儲引擎也可被稱為表類型骇钦。

Oracle溃卡,SqlServer等數(shù)據(jù)庫只有一種存儲引擎。MySQL提供了插件式的存儲引擎架構(gòu)隧甚。所以MySQL存在多種存儲引擎拉宗,可以根據(jù)需要使用相應(yīng)引擎峦树,或者編寫存儲引擎辣辫。

MySQL5.0支持的存儲引擎包含 : InnoDB 、MyISAM 魁巩、BDB急灭、MEMORY、MERGE谷遂、EXAMPLE葬馋、NDB Cluster、ARCHIVE肾扰、CSV点楼、BLACKHOLE、FEDERATED等白对,其中InnoDB和BDB提供事務(wù)安全表掠廓,其他存儲引擎是非事務(wù)安全表。

可以通過指定 show engines 甩恼, 來查詢當(dāng)前數(shù)據(jù)庫支持的存儲引擎 :

image.png

創(chuàng)建新表時如果不指定存儲引擎蟀瞧,那么系統(tǒng)就會使用默認(rèn)的存儲引擎,MySQL5.5之前的默認(rèn)存儲引擎是MyISAM条摸,5.5之后就改為了InnoDB悦污。

查看Mysql數(shù)據(jù)庫默認(rèn)的存儲引擎 , 指令 :

show variables like '%storage_engine%' 钉蒲;
image.png

2. 各種存儲引擎特性

下面重點介紹幾種常用的存儲引擎切端, 并對比各個存儲引擎之間的區(qū)別, 如下表所示 :

特點 InnoDB MyISAM MEMORY MERGE NDB
存儲限制 64TB 沒有
事務(wù)安全 支持
鎖機制 行鎖(適合高并發(fā)) 表鎖 表鎖 表鎖 表鎖
B樹索引 支持 支持 支持 支持 支持
哈希索引 支持
全文索引 支持(5.6版本之后) 支持
集群索引 支持
數(shù)據(jù)索引 支持 支持 支持
索引緩存 支持 支持 支持 支持 支持
數(shù)據(jù)可壓縮 支持
空間使用 N/A
內(nèi)存使用 中等
批量插入速度
支持外鍵 支持

下面我們將重點介紹最長使用的兩種存儲引擎: InnoDB顷啼、MyISAM 踏枣, 另外兩種 MEMORY、MERGE 钙蒙, 了解即可茵瀑。

2.1 InnoDB

InnoDB存儲引擎是Mysql的默認(rèn)存儲引擎。InnoDB存儲引擎提供了具有提交躬厌、回滾马昨、崩潰恢復(fù)能力的事務(wù)安全。但是對比MyISAM的存儲引擎扛施,InnoDB寫的處理效率差一些鸿捧,并且會占用更多的磁盤空間以保留數(shù)據(jù)和索引。

InnoDB存儲引擎不同于其他存儲引擎的特點 :

1. 事務(wù)控制

create table goods_innodb
(
    id   int         NOT NULL AUTO_INCREMENT,
    name varchar(20) NOT NULL,
    primary key (id)
) ENGINE = innodb
  DEFAULT CHARSET = utf8; 
start transaction; 
insert into goods_innodb(id,name)values(null,'Meta20'); 
commit; 
image.png

測試疙渣,發(fā)現(xiàn)在InnoDB中是存在事務(wù)的 匙奴;

2. 外鍵約束

MySQL支持外鍵的存儲引擎只有InnoDB , 在創(chuàng)建外鍵的時候昌阿, 要求父表必須有對應(yīng)的索引 饥脑, 子表在創(chuàng)建外鍵的時候, 也會自動的創(chuàng)建對應(yīng)的索引懦冰。

下面兩張表中 灶轰, country_innodb是父表 , country_id為主鍵索引刷钢,city_innodb表是子表笋颤,country_id字段為外鍵,對應(yīng)于country_innodb表的主鍵country_id 内地。

create table country_innodb
(
    country_id   int          NOT NULL AUTO_INCREMENT,
    country_name varchar(100) NOT NULL,
    primary key (country_id)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

create table city_innodb
(
    city_id    int         NOT NULL AUTO_INCREMENT,
    city_name  varchar(50) NOT NULL,
    country_id int         NOT NULL,
    primary key (city_id),
    key idx_fk_country_id (country_id),
    CONSTRAINT `fk_city_country` FOREIGN KEY (country_id) REFERENCES
        country_innodb (country_id) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

insert into country_innodb
values (null, 'China'),
       (null, 'America'),
       (null, 'Japan');

insert into city_innodb
values (null, 'Xian', 1),
       (null, 'NewYork', 2),
       (null, 'BeiJing', 1); 

在創(chuàng)建索引時伴澄, 可以指定在刪除、更新父表時阱缓,對子表進行的相應(yīng)操作非凌,包括 RESTRICT、CASCADE荆针、SET NULL和 NO ACTION敞嗡。

RESTRICT和NO ACTION相同, 是指限制在子表有關(guān)聯(lián)記錄的情況下航背, 父表不能更新喉悴;

CASCADE表示父表在更新或者刪除時,更新或者刪除子表對應(yīng)的記錄玖媚;

SET NULL 則表示父表在更新或者刪除的時候箕肃,子表的對應(yīng)字段被SET NULL 。

針對上面創(chuàng)建的兩個表今魔, 子表的外鍵指定是ON DELETE RESTRICT ON UPDATE CASCADE 方式的勺像, 那么在主表刪除記錄的時候, 如果子表有對應(yīng)記錄错森, 則不允許刪除咏删, 主表在更新記錄的時候, 如果子表有對應(yīng)記錄问词, 則子表對應(yīng)更新 督函。

表中數(shù)據(jù)如下圖所示 :

image.png

外鍵信息可以使用如下兩種方式查看 :

show create table city_innodb ; 
image.png

刪除country_id為1 的country數(shù)據(jù):

delete from country_innodb where country_id = 1;
image.png

更新主表country表的字段 country_id :

update country_innodb set country_id = 100 where country_id = 1;
image.png

更新后, 子表的數(shù)據(jù)信息為 :

image.png

3. 存儲方式

InnoDB 存儲表和索引有以下兩種方式 :

①. 使用共享表空間存儲激挪, 這種方式創(chuàng)建的表的表結(jié)構(gòu)保存在.frm文件中辰狡, 數(shù)據(jù)和索引保存在innodb_data_home_dir 和 innodb_data_fifile_path定義的表空間中,可以是多個文件垄分。

②. 使用多表空間存儲宛篇, 這種方式創(chuàng)建的表的表結(jié)構(gòu)仍然存在 .frm 文件中,但是每個表的數(shù)據(jù)和索引單獨保存在.ibd 中薄湿。

image.png

2.2 MyISAM

MyISAM 不支持事務(wù)叫倍、也不支持外鍵偷卧,其優(yōu)勢是訪問的速度快,對事務(wù)的完整性沒有要求或者以SELECT吆倦、INSERT為主的應(yīng)用基本上都可以使用這個引擎來創(chuàng)建表 听诸。有以下兩個比較重要的特點:

1. 不支持事務(wù)

create table goods_myisam
(
    id   int         NOT NULL AUTO_INCREMENT,
    name varchar(20) NOT NULL,
    primary key (id)
) ENGINE = myisam
  DEFAULT CHARSET = utf8;
image.png

通過測試,我們發(fā)現(xiàn)蚕泽,在MyISAM存儲引擎中晌梨,是沒有事務(wù)控制的 ;

2. 文件存儲方式

每個MyISAM在磁盤上存儲成3個文件须妻,其文件名都和表名相同仔蝌,但拓展名分別是 :

.frm (存儲表定義);
.MYD(MYData , 存儲數(shù)據(jù))荒吏;
.MYI(MYIndex , 存儲索引)敛惊;

image.png

2.3 MEMORY

Memory存儲引擎將表的數(shù)據(jù)存放在內(nèi)存中。每個MEMORY表實際對應(yīng)一個磁盤文件绰更,格式是.frm 豆混,該文件中只存儲表的結(jié)構(gòu),而其數(shù)據(jù)文件动知,都是存儲在內(nèi)存中皿伺,這樣有利于數(shù)據(jù)的快速處理,提高整個表的效率盒粮。MEMORY類型的表訪問非常地快鸵鸥,因為他的數(shù)據(jù)是存放在內(nèi)存中的,并且默認(rèn)使用HASH索引 丹皱, 但是服務(wù)一旦關(guān)閉妒穴,表中的數(shù)據(jù)就會丟失。

2.4 MERGE

MERGE存儲引擎是一組MyISAM表的組合摊崭,這些MyISAM表必須結(jié)構(gòu)完全相同讼油,MERGE表本身并沒有存儲數(shù)據(jù),對MERGE類型的表可以進行查詢呢簸、更新矮台、刪除操作,這些操作實際上是對內(nèi)部的MyISAM表進行的根时。

對于MERGE類型表的插入操作瘦赫,是通過INSERT_METHOD子句定義插入的表,可以有3個不同的值蛤迎,使用FIRST 或LAST 值使得插入操作被相應(yīng)地作用在第一或者最后一個表上确虱,不定義這個子句或者定義為NO,表示不能對這個MERGE表執(zhí)行插入操作替裆。

可以對MERGE表進行DROP操作校辩,但是這個操作只是刪除MERGE表的定義窘问,對內(nèi)部的表是沒有任何影響的。

image.png

下面是一個創(chuàng)建和使用MERGE表的示例 :

1). 創(chuàng)建3個測試表 order_1990, order_1991, order_all , 其中order_all是前兩個表的MERGE表 :

create table order_1990
(
    order_id      int,
    order_money   double(10, 2),
    order_address varchar(50),
    primary key (order_id)
) engine = myisam
  default charset = utf8;

create table order_1991
(
    order_id      int,
    order_money   double(10, 2),
    order_address varchar(50),
    primary key (order_id)
) engine = myisam
  default charset = utf8;

create table order_all
(
    order_id      int,
    order_money   double(10, 2),
    order_address varchar(50),
    primary key (order_id)
) engine = merge
  union = (order_1990,order_1991)
  INSERT_METHOD = LAST
  default
      charset = utf8;                       
                       
                       

2). 分別向兩張表中插入記錄

insert into order_1990 values(1,100.0,'北京');
insert into order_1990 values(2,100.0,'上海');

insert into order_1991 values(10,200.0,'北京');
insert into order_1991 values(11,200.0,'上海');

3). 查詢3張表中的數(shù)據(jù)宜咒。

order_1990中的數(shù)據(jù) :

image.png

order_1991中的數(shù)據(jù) :

image.png

order_all中的數(shù)據(jù) :

image.png

4). 往order_all中插入一條記錄 惠赫,由于在MERGE表定義時,INSERT_METHOD 選擇的是LAST荧呐,那么插入的數(shù)據(jù)會想最后一張表中插入。

insert into order_all values(100,10000.0,'西安')纸镊;
image.png

3. 存儲引擎的選擇

在選擇存儲引擎時倍阐,應(yīng)該根據(jù)應(yīng)用系統(tǒng)的特點選擇合適的存儲引擎。對于復(fù)雜的應(yīng)用系統(tǒng)逗威,還可以根據(jù)實際情況選擇多種存儲引擎進行組合峰搪。以下是幾種常用的存儲引擎的使用環(huán)境。

  • InnoDB : 是Mysql的默認(rèn)存儲引擎凯旭,用于事務(wù)處理應(yīng)用程序概耻,支持外鍵。如果應(yīng)用對事務(wù)的完整性有比較高的要求罐呼,在并發(fā)條件下要求數(shù)據(jù)的一致性鞠柄,數(shù)據(jù)操作除了插入和查詢意外,還包含很多的更新嫉柴、刪除操作厌杜,那么InnoDB存儲引擎是比較合適的選擇。InnoDB存儲引擎除了有效的降低由于刪除和更新導(dǎo)致的鎖定计螺, 還可以確保事務(wù)的完整提交和回滾夯尽,對于類似于計費系統(tǒng)或者財務(wù)系統(tǒng)等對數(shù)據(jù)準(zhǔn)確性要求比較高的系統(tǒng),InnoDB是最合適的選擇登馒。
  • MyISAM : 如果應(yīng)用是以讀操作和插入操作為主匙握,只有很少的更新和刪除操作,并且對事務(wù)的完整性陈轿、并發(fā)性要求不是很高圈纺,那么選擇這個存儲引擎是非常合適的。
  • MEMORY:將所有數(shù)據(jù)保存在RAM中麦射,在需要快速定位記錄和其他類似數(shù)據(jù)環(huán)境下赠堵,可以提供幾塊的訪問。MEMORY的缺陷就是對表的大小有限制法褥,太大的表無法緩存在內(nèi)存中茫叭,其次是要確保表的數(shù)據(jù)可以恢復(fù),數(shù)據(jù)庫異常終止后表中的數(shù)據(jù)是可以恢復(fù)的半等。MEMORY表通常用于更新不太頻繁的小表揍愁,用以快速得到訪問結(jié)果呐萨。
  • MERGE:用于將一系列等同的MyISAM表以邏輯方式組合在一起,并作為一個對象引用他們莽囤。MERGE表的優(yōu)點在于可以突破對單個MyISAM表的大小限制谬擦,并且通過將不同的表分布在多個磁盤上,可以有效的改善MERGE表的訪問效率朽缎。這對于存儲諸如數(shù)據(jù)倉儲等VLDB環(huán)境十分合適惨远。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市话肖,隨后出現(xiàn)的幾起案子北秽,更是在濱河造成了極大的恐慌,老刑警劉巖最筒,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贺氓,死亡現(xiàn)場離奇詭異,居然都是意外死亡床蜘,警方通過查閱死者的電腦和手機辙培,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邢锯,“玉大人扬蕊,你說我怎么就攤上這事〉で妫” “怎么了厨相?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鸥鹉。 經(jīng)常有香客問我蛮穿,道長,這世上最難降的妖魔是什么毁渗? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任践磅,我火速辦了婚禮,結(jié)果婚禮上灸异,老公的妹妹穿的比我還像新娘府适。我一直安慰自己,他們只是感情好肺樟,可當(dāng)我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布檐春。 她就那樣靜靜地躺著,像睡著了一般么伯。 火紅的嫁衣襯著肌膚如雪疟暖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音俐巴,去河邊找鬼骨望。 笑死,一個胖子當(dāng)著我的面吹牛欣舵,可吹牛的內(nèi)容都是我干的擎鸠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缘圈,長吁一口氣:“原來是場噩夢啊……” “哼劣光!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起糟把,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绢涡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后糊饱,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體垂寥,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡颠黎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年另锋,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片狭归。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡夭坪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出过椎,到底是詐尸還是另有隱情室梅,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布疚宇,位于F島的核電站亡鼠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏敷待。R本人自食惡果不足惜间涵,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望榜揖。 院中可真熱鬧勾哩,春花似錦、人聲如沸举哟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妨猩。三九已至潜叛,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背钠导。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工震嫉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人牡属。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓票堵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親逮栅。 傳聞我的和親對象是個殘疾皇子悴势,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容