3. 存儲引擎
經歷千辛萬苦,MySQL終于算出了最終的執(zhí)行計劃,然后就可以直接執(zhí)行了嗎?
好吧。。。依然還不可以。
我們知道,表是由一行一行的記錄組成的,但這只是邏輯上的概念,或者說只是看上去是這樣而已。
3.1 什么是存儲引擎
到底該把數據存儲在什么位置,是內存還是磁盤?怎么從表里讀取數據,以及怎么把數據寫入具體的表中,這都是存儲引擎
負責的事情。
好吧,看到這里或許你還不知道存儲引擎到底是什么。畢竟存儲引擎這個名字聽起來太玄乎了,它的前身叫做表處理器,是不是就接地氣了許多呢?
3.2 為什么需要存儲引擎
因為存儲的需求不同。
試想一下:
- 如果一張表,需要很高的訪問速度,而不需要考慮持久化的問題,是不是最好把數據放在內存呢?
- 如果一張表,是用來做歷史數據存檔的,不需要修改,也不需要索引,那是不是要支持數據的壓縮?
- 如果一張表用在讀寫并發(fā)很多的業(yè)務中,是不是要支持讀寫互不干擾,而且要保證比較高的數據一致性呢?
大家應該明白了,為什么要支持這么多的存儲引擎,因為一種存儲引擎不能提供所有的特性。
存儲引擎是計算機抽象的典型代表,它的功能就是接受上層指令,然后對表中數據進行讀取和寫入,而這些操作對上層完全是屏蔽的。你甚至可以查閱MySQL文檔定義自己的存儲引擎,只要對外實現同樣的接口就可以了。
存儲引擎就是MySQL對數據進行讀寫的插件而已,可以根據不同目的隨意更換(插拔)
3.3 存儲引擎怎么用
3.3.1 創(chuàng)建表的時候指定存儲引擎
在創(chuàng)建表的時候可以指定當前表的存儲引擎,如果沒有指定,默認的存儲引擎為InnoDB
,如果想顯式指定存儲引擎,可以這樣
CREATE TABLE `t_user_innodb` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=innodb DEFAULT CHARSET=utf8mb4;
3.3.2 修改表的存儲引擎
ALTER TABLE 表名 ENGINE = 存儲引擎名稱;
3.4 存儲引擎底層區(qū)別
下面我們分別創(chuàng)建3張設置了不同存儲引擎的表, t_user_innodb 、 t_user_myisam 、t_user_memory我們看一下不同存儲引擎在底層存儲方面的差異,首先找到MySQL的數據存儲目錄
mysql> show variables like 'datadir';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
進入到目標目錄之后,找到當前數據庫對應的目錄(MySQL會為一個數據庫創(chuàng)建一個同名的目錄),數據庫中表的存儲結構如下不同的存儲引擎存放數據的方式不一樣,產生的文件數量和格式也不一樣,InnoDB文件包含2個,MEMORY文件包含1個,MYISAM文件包含3個。
3.5 常見存儲引擎比較
首先我們查看一下當前MySQL服務器支持的存儲引擎都有哪一些。
mysql> SHOW ENGINES;
+--------------------+---------+--------------+------+------------+
| Engine | Support | Transactions | XA | Savepoints |
+--------------------+---------+--------------+------+------------+
| InnoDB | DEFAULT | YES | YES | YES |
| MRG_MYISAM | YES | NO | NO | NO |
| MEMORY | YES | NO | NO | NO |
| BLACKHOLE | YES | NO | NO | NO |
| MyISAM | YES | NO | NO | NO |
| CSV | YES | NO | NO | NO |
| ARCHIVE | YES | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | NO | NO | NO |
| FEDERATED | NO | NULL | NULL | NULL |
+--------------------+---------+--------------+------+------------+
其中,
- Support表示該存儲引擎是否可用;
- DEFAULT表示當前MySQL服務器默認的存儲引擎;
- Transactions表示該存儲引擎是否支持事務;
- XA表示該存儲引擎是否支持分布式事務;
- Savepoints表示該存儲引擎是否支持事務的部分回滾。
3.5.1 MylSAM
應用范圍比較小,表級鎖定限制了讀/寫的性能,因此在Web和數據倉庫配置中,通常用于只讀或以讀為主的工作。
特點:
- 支持表級別的鎖(插入和更新會鎖表),不支持事務;
- 擁有較高的插入(insert)和查詢(select)速度;
- 存儲了表的行數(count速度更快)。
怎么快速向數據庫插入100萬條數據?
可以先用MylSAM插入數據,然后修改存儲引擎為InnoDB。
3.5.2 InnoDB
MySQL 5.7及更新版中的默認存儲引擎。InnoDB是一個事務安全(與ACID兼容)的MySQL 存儲引擎,它具有提交、回滾和崩潰恢復功能來保護用戶數據。InnoDB行級鎖(不升級為更粗粒度的鎖)和Oracle風格的一致非鎖讀提高了多用戶并發(fā)性。InnoDB將用戶數據存儲在聚集索引中,以減少基于主鍵的常見查詢的I/O。為了保持數據完整性,InnoDB還支持外鍵引用完整性約束。
特點:
- 支持事務,支持外鍵,因此數據的完整性、一致性更高;
- 支持行級別的鎖和表級別的鎖;
- 支持讀寫并發(fā),寫不阻塞讀(MVCC);
- 特殊的索引存放方式,可以減少IO,提升査詢效率。
番外:InnoDB本來是InnobaseOy公司開發(fā)的,它和MySQL AB公司合作開源了InnoDB的代碼。但是沒想到MySQL的競爭對手Oracle把InnobaseOy收購了。后來08年Sun公司(開發(fā)Java語言的Sun)收購了MySQL AB,09年Sun公司又被Oracle收購了,所以MySQL和 InnoDB又是一家了。有人覺得MySQL越來越像Oracle,其實也是這個原因。
3.5.3 Memory
將所有數據存儲在RAM中,以便快速訪問。這個引擎以前被稱為堆引擎。
特點:
- 把數據放在內存里面,讀寫的速度很快,但是數據庫重啟或者崩潰,數據會全部消失;
- 只適合做臨時表。
3.5.4 CSV
它的表實際上是帶有逗號分隔值的文本文件。csv表允許以CSV格式導入或轉儲數據, 以便與讀寫相同格式的腳本和應用程序交換數據。因為CSV表沒有索引,所以通常在正常操作期間將數據保存在InnoDB表中,只在導入或導出階段使用csv表。
特點:
- 不允許空行,不支持索引;
- 格式通用,可以直接編輯,適合在不同數據庫之間導入導出。
3.5.5 Archive
專用與存檔,空間經過壓縮,用于存儲和檢索大量很少引用的信息。
特點:
- 不支持索引;
- 不支持update、delete。
3.6 如何選擇存儲引擎
- 如果對數據一致性要求比較高,需要事務支持,可以選擇InnoDB。
- 如果數據查詢多更新少,對查詢性能要求比較高,可以選擇MyISAM。
- 如果需要一個用于查詢的臨時表,可以選擇Memory。
如果所有的存儲引擎都不能滿足你的需求,并且技術能力足夠,可以根據官網內部手冊用C語言開發(fā)一個存儲引擎:https://dev.mvsql.com/doc/internals/en/custom-engine.html
-
服務器
+關注
關注
12文章
9206瀏覽量
85562 -
TCP
+關注
關注
8文章
1362瀏覽量
79119 -
MySQL
+關注
關注
1文章
816瀏覽量
26613
發(fā)布評論請先 登錄
相關推薦
評論