MySQL-淺談存儲引擎

MySQL中的存儲引擎

1、前言

數據庫做爲存儲數據的倉庫,可能你們會想,關係型數據庫把咱們的數據一行一行地存儲不就完事了嗎?哪裏又冒出個存儲引擎呢?mysql

之因此有多個存儲引擎,是由於咱們對錶的使用場景並不老是相同的,有時候可能咱們須要頻繁的selectinsert操做,而有的時候可能須要頻繁的update 操做。這個時候,不一樣引擎的數據表table 就有着不一樣的性能了。sql

一、引擎之間的區別

  1. 引擎engine 不一樣,數據庫把數據data 保存至本地的方式(文件的結構)是不同的,物理結構影響着數據的操做。
  2. 其次,不一樣的引擎,所擁有的索引也是不一樣的。全部的引擎都擁有BTree 索引。
  3. 還有,不一樣的引擎,還意味着是否支持事務transaction 操做。目前,只有InnoDB 引擎支持事務操做。
引擎的說明對象

須要說明的是,引擎是針對數據表table 而言的,也就是說咱們討論的是一張數據表以何種引擎的方式來進行數據存儲。數據庫


2、引擎相關操做

一、查看數據庫所支持的引擎以及說明

咱們能夠查看MySQL數據庫支持的引擎以及相應的說明。安全

命令:show engines; 工具

在MySQL裏面,咱們主要會使用到的引擎有InnoDB (默認引擎)、MyISAMMRG_MYISAM (原名MERGE) 、MEMORY 。其餘引擎可能非專業DBA 接觸不到,因此接下來的存儲引擎將圍繞上面4個展開。性能

順便說一句,咱們平常絕大部分的都是InnoDBMyISAM 引擎。固然,也有一些非官方的引擎,以其高性能而流行,好比說:TokuDB ,它有多項性能指標吊打InnoDBspa

二、查看數據表table 所使用的引擎

命令:rest

show create table userinfo \G;  # \G格式化輸出

上面的命令,使用查看建表語句,能夠查看數據表使用的引擎,固然咱們默認的都是InnoDBcode

生成表時指定引擎

命令:對象

create table tb1(
...
...
)engine=MyISAM default charset=utf8;
修改表的引擎

命令:

alter table t1 engine=InnoDB;

3、詳細對比各個引擎之間的區別

特色 InnoDB MyISAM MRG_MYISAM(原MERGE) MEMORY
存儲大小限制 64TB 沒有
事務安全 支持
鎖機制 行鎖、表鎖 表鎖 表鎖 表鎖
BTree索引 支持 支持 支持 支持
Hash索引 支持
fulltext索引 支持
集羣索引 支持
數據可壓縮 支持
空間使用
內存使用
批量插入的速度
支持外鍵 支持

咱們說過,平常中使用最多的是InnoDBMyISAM 引擎,從上表能夠看出,這2者互有長處與短板。所以,咱們要根據業務場景來選擇合適的引擎。


4、各個引擎的介紹

一、InnoDB 引擎

InnoDB 引擎很重要的2項功能(也是獨有)是支持事務 以及支持外鍵

1.1 支持事務

事務的重要性不言而喻,金融上重要的轉帳、交易等操做,爲了應對突發事故如停電,須要對數據的操做具備原子性。==事務的具體內容,放置另外一篇章進行講解==。 這裏咱們須要知道,對於涉及到事務的數據表,咱們只能選擇InnoDB 引擎來存儲。

1.2 支持外鍵

外鍵是一種主從的對應關係。只有InnoDB 支持外鍵foreign key ,下面來說解相關的外鍵操做。

場景假設

如今假設咱們開了一個書店bookstore ,咱們的書源都是由書籍市場bookmarket 提供,因此咱們的書的bookname 應該做爲一個外鍵,參照bookmarket 的主鍵(bookname)。

模擬

下面咱們來生成上面2個表,並設置相應的主鍵與外鍵。

drop table if exists bookmarket;
    create table bookmarket(
    bookname varchar(50),
    price double,
    primary key(bookname)
);

drop table if exists bookstore;
    create table bookstore(
    id int primary key auto_increment,
    bookname varchar(50),
    price double,
    constraint `fk_bookname` foreign key(bookname) references bookmarket(bookname)
);

下面咱們來複習如下外鍵相關的知識:

  1. 若是咱們想在從表中插入數據,那麼data 中的外鍵列的值必須在主表中存在。換句話說,咱們想要銷售一本新書唐吉坷德,那麼在bookmarket中就必須有這本書,咱們是不能銷售沒有貨源的書的。
設置主表的DML操做->觸發從表操做

這個操做的名稱很差取,咱們理解仍是很好理解的。在對主表的數據進行CURD 中的刪除更新時,咱們的從表應該作出哪些相應的操做呢?

咱們能夠選擇的方案有3種:

  1. 從表外鍵數據存在的狀況下,主表不容許刪除和更新。RESTRICTNO ACTION ,這也是未指定時,默認的設置,即on update restrict on delete restrict
  2. 主表刪除和更新的時候,從表的數據也進行刪除和更新。CASCADE
  3. 主表刪除和更新的時候,從表的數據對應的列設置爲NULLSET NULL
模擬

咱們如今插入一些相關的數據。

insert bookmarket values('book_1',23.42),('book_2',22.2),('book_3',44.1);

insert bookstore values(null,'book_1',30),(null,'book_2',32.2);

而後,咱們以RESTRICT 爲例,先修改從表的外鍵。

alter table bookstore drop foreign key `fk_bookname`;

alter table bookstore add constraint `bookstore_fk_bookname` foreign key(bookname) references 
bookmarket(bookname) on delete restrict on update restrict;

而後,咱們試圖刪除主表的一行數據:

這裏提示,不能刪除數據,由於數據被外鍵所引用。順便一提,默認狀況下,外鍵會採用on delete restrict on update restrict 的方案。

值得一提的是,當咱們使用外鍵的時候,最合理的方式應該是on delete restrict on update cascade ,禁止刪除,更新同步。

忽視外鍵

有一個小技巧,那就是當咱們導入多個表的數據時,因爲外鍵的存在,咱們導入表的順序就有前後之分。那麼咱們能夠暫時關閉外鍵檢查,這樣就無所謂順序了。

set forign_key_checks=0;
...
...
set forign_key_checks=1;

1.3 存儲方式

該點水平不夠。

二、MyISAM 引擎

在5.5版本以前,MySQL的默認引擎就是這個,使用的也很普遍。它的優勢在於訪問速度快,適合常常進行selectinsert 操做的場景。缺點就是不支持事務外鍵

每一個MyISAM 表在物理上存儲3個文件,分別是:存儲表定義、存儲數據、存儲索引。

適用場景

適合常常須要進行selectinsert操做的表。

存儲格式

MyISAM 表支持3種存儲格式,分別是靜態表(默認)、動態表、壓縮表。

  1. 靜態表,優勢是存儲速度快,缺點是空間耗費大。並且插入的數據中,定長數據格式的數據列,其字符後面的空格會被刪除。
  2. 動態表,優勢是空間小,缺點是會產生垃圾碎片。
模擬

咱們建立一個MyISAM 表,有一個列設置爲定長數據。(如char),注意varchar是無效的。

drop table if exists isam_t;
    create table isam_t(
    id int,
    name char(12)
)engine=myisam charset=utf8;

接下來,咱們插入數據並驗證。

insert isam_t values(2,' tom '),(3,'  kim'),(4,' jol   ');
select id,name,length(name) from isam_t;

咱們能夠看出,name 後面的空格已經被去掉了。

三、MRG_MYISAM 引擎

望文生義,MRG_MYISAM 引擎就是將MyISAM 引擎進行合併。它是一組MyISAM 表的組合。它要求這些表的結構徹底相同,MRG_MYISAM 表自己沒有數據,它只是一個容器,操做的對象仍是內部的MyISAM 表。

很顯然,咱們能夠把它當作是一個分表的工具。前面的引擎對比中,咱們知道MyISAM 表的存儲大小是有限制的,有時候一張表存儲不下全部數據,那麼咱們分紅多張結構徹底相同的表進行分表存儲。這個時候,就是咱們MRG_MYISAM 表的用武之地了。咱們能夠將全部的分表聚合在一塊兒,這樣就可以對全部數據進行操做了。

3.1 表的CURD 操做

由於這張表只提供一個容器的功能,因此MRG_MYISAM 表的CURD 操做和傳統意義表的操做是不同的。

  1. create ,定義各個分表的聚合。
  2. selectupdate 都是操做其內部的分表。
  3. delete 只是刪除該表的定義,不影響內部的分表。
  4. insert ,須要指定數據插入的表,insert_method的可選值只能是firstlastnono 表示不能執行插入操做,默認也是no
模擬

咱們先生成2張MyISAM 表,而後生成一個MRG_MYISAM 表,包含前面2個分表。這裏咱們指定insert_methodlast

drop table if exists bill_2016;
    create table bill_2016(
    id int primary key,
    time date,
    cost double
)engine=myisam;

drop table if exists bill_2017;
    create table bill_2017(
    id int primary key,
    time date,
    cost double
)engine=myisam;

drop table if exists bill_merge;
    create table bill_merge(
    id int primary key,
    time date,
    cost double
)engine=merge union=(bill_2016,bill_2017) insert_method=last;

而後咱們往2張分表中插入數據。

insert bill_2016 values(1,'2016-1-2',22.4),(2,'2016-2-3',44.2);
insert bill_2017 values(100,'2017-4-2',55.2),(102,'2017-6-3',88);

select * from bill_2016;
select * from bill_2017;

咱們查看MRG_MYISAM 表的數據。

能夠發現,bill_merge 包含了2個分表的數據。

這時候咱們向bill_merge 插入數據,按照預期,數據應該被插入了第2張表,也就是bill_2017 中。

3.2 存儲結構

MRG_MYISAM 表在物理上生成2個文件,其一是存儲表定義,其二是包含組合表的信息和插入依據。

四、MEMORY 引擎

MEMORY 引擎使用內存中的數據來建立表,在物理上只對應一個文件。MEMORY 表的訪問速度很是快,由於它的數據是放在內存中的,若是服務一旦關掉,那麼表中的數據就會丟失。

適用場景

主要用於存儲內容變化不頻繁的代碼表,或者是做爲統計操做的中間結果表。相似於一箇中間數據存儲站,提供給其餘操做進行查詢。須要注意的是,該表的數據並不會寫入磁盤,因此數據的保存須要注意。

模擬

咱們使用bookmarket 表的數據,來生成咱們的MEMORY 表。

create table emp_memory engine=memory
select * from bookmarket;

咱們在生成索引的時候,能夠選擇Hash或者BTree 這2種。

create index idx_bookname using hash on emp_memory(bookname);
show index from emp_memory;

當咱們不須要MEMORY 表的時候,咱們應該刪除從而釋放內存。

能夠是delete from truncate tabledrop table 等。

相關文章
相關標籤/搜索