1、MySQL存儲引擎:MySQL將數據用各類不一樣的技術存儲在文件中,這些技術中的每一種技術都使用不一樣的存儲機制、索引技巧、鎖定水平而且最終提供普遍的不一樣的功能和能力。這些不一樣的技術以及配套的相關功能在 mysql中被稱做存儲引擎(也稱做表類型)。建表時,選擇合適的存儲引擎很重要,若是到後期再更換將會很麻煩。存儲引擎是基於表的,而非數據庫。mysql
我的理解:存儲引擎是某張表存儲數據、如何爲存儲的數據創建索引和更新、查詢數據庫等技術的實現方法集合及約束。常見的存儲引擎以下圖:sql
這裏,先總結經常使用的三種存儲引擎:數據庫
1. MyISAM引擎:MyISAM引擎是MySQL默認的存儲引擎,MyISAM不支持事務和行級鎖,因此MyISAM引擎速度很快,性能優秀。MyISAM能夠對整張表加鎖,支持併發插入,支持全文索引。緩存
缺點:不支持事務和行級鎖,也不支持外鍵服務器
優勢:訪問速度快,對事務的完整性沒有要求或者以select、insert爲主的應用基本上均可以使用這個引擎來建立併發
MyISAM再磁盤上存儲成三個文件,其文件名都和表名相同,但擴展名分別是:.frm(存儲表定義),.MYD(存儲數據),.MYI(存儲索引),這種引擎又能夠分爲靜態MyISAM、動態MyISAM 和壓縮MyISAM三種:高併發
靜態MyISAM:若是數據表中的各數據列的長度都是預先固定好的,服務器將自動選擇這種表類型。由於數據表中每一條記錄所佔用的空間都是同樣的,因此這種表存取和更新的效率很是高。當數據受損時,恢復工做也比較容易作。工具
動態MyISAM:若是數據表中出現varchar、xxxtext或xxxBLOB字段時,服務器將自動選擇這種表類型。相對於靜態MyISAM,這種表存儲空間比較小,但因爲每條記錄的長度不一,因此屢次修改數據後,數據表中的數據就可能離散的存儲在內存中,進而致使執行效率降低。同時,內存中也可能會出現不少碎片。所以,這種類型的表要常常用optimize table 命令或優化工具來進行碎片整理。性能
壓縮MyISAM:以上說到的兩種類型的表均可以用myisamchk工具壓縮。這種類型的表進一步減少了佔用的存儲,可是這種表壓縮以後不能再被修改。另外,由於是壓縮數據,因此這種表在讀取的時候要先時行解壓縮。優化
可是,不論是何種MyISAM表,目前它都不支持事務,行級鎖和外鍵約束的功能。
(補充:鎖
頁級:引擎 BDB。
表級:引擎 MyISAM , 理解爲鎖住整個表,能夠同時讀,寫不行
行級:引擎 INNODB , 單獨的一行記錄加鎖
上述三種鎖的特性可大體概括以下:
1) 表級鎖:開銷小,加鎖快;不會出現死鎖;鎖定粒度大,發生鎖衝突的機率最高,併發度最低。
2) 行級鎖:開銷大,加鎖慢;會出現死鎖;鎖定粒度最小,發生鎖衝突的機率最低,併發度也最高。
3) 頁面鎖:開銷和加鎖時間界於表鎖和行鎖之間;會出現死鎖;鎖定粒度界於表鎖和行鎖之間,併發度通常。三種鎖各有各的特色,若僅從鎖的角度來講,表級鎖更適合於以查詢爲主,只有少許按索引條件更新數據的應用,如WEB應用;行級鎖更適合於有大量按索引條件併發更新少許不一樣數據,同時又有併發查詢的應用,如一些在線事務處理(OLTP)系統。
-->MySQL表級鎖有兩種模式:表共享讀鎖(Table Read Lock)和表獨佔寫鎖(Table Write Lock)。就是說對MyISAM表進行讀操做時,它不會阻塞其餘用戶對同一表的讀請求,但會阻塞 對同一表的寫操做;而對MyISAM表的寫操做,則會阻塞其餘用戶對同一表的讀和寫操做。當一個進程請求某個MyISAM表的讀鎖,同時另外一個進程也請求同一表的寫鎖時,一般寫進程優先得到鎖。-->InnoDB有兩種模式的行鎖:
1)共享鎖:容許一個事務去讀一行,阻止其餘事務得到相同數據集的排他鎖。
( Select * from table_name where ......lock in share mode)
2)排他鎖:容許得到排他鎖的事務更新數據,阻止其餘事務取得相同數據集的共享讀鎖和 排他寫鎖。(select * from table_name where.....for update)★ InnoDB行鎖是經過給索引項加鎖來實現的,因爲InnoDB預設是Row-Level Lock,因此只有「明確」的指定主鍵,MySQL纔會執行Row lock (只鎖住被選取的資料例) ,不然MySQL將會執行Table Lock (將整個資料表單給鎖住)。
★ 死鎖產生的根本緣由是兩個以上的進程都要求對方釋放資源,以致於進程都一直等待。在代碼上是由於兩個或者以上的事務都要求另外一個釋放資源。死鎖產生的四個必要條件:互斥條件、環路條件、請求保持、不可剝奪,缺一不可,相對應的只要破壞其中一種條件死鎖就不會產生。SELECT * FROM products WHERE id='3' FOR UPDATE; --row-level lock
SELECT * FROM products WHERE name='Mouse' FOR UPDATE; --table-level lock
)
2. InnoDB引擎:InnoDB是專爲事務設計的存儲引擎,支持事務,支持外鍵,擁有高併發處理能力。可是,InnoDB在建立索引和加載數據時,比MyISAM慢。
1.自動增加列:經過「alter table *** auto_increment = n」語句強制設置自動增加列的初始值,若是在使用以前從新啓動數據庫,則須要從新設置,不設置默認初始值爲1.對於InnoDB表來講自動增加列必須是索引。若是是組合索引,也必須是組合索引的第一列,可是對於MyISAM表,自動增加列能夠是組合索引的其餘列,這樣插入記錄後,自動增加列按照組合索引前面幾列進行排序後遞增的。
2.外鍵約束:MySQL支持外鍵的存儲引擎只有InnoDB,在建立外鍵的時候,要求父表必須有對應的索引,子表在建立外鍵的時候也會自動建立對應的索引。當某個表被其餘表建立的外鍵參照,那麼該表的對應索引或者主鍵禁止被刪除。在導入多個表的數據時,若是須要忽略表以前的導入順序,能夠暫時關閉外鍵的檢查,在處理LOAD DATA 和 ALTER TABLE操做的時候,能夠關閉外鍵約束來加快處理速度,「set foreign_key_checks = 0(1開)」。對於InnoDB類型的表,外鍵信息經過使用show table status命令顯示。
3.存儲方式:InnoDB存儲表和索引有如下兩種方式。①.使用共享表空間存儲,這種方式建立的表的表結構保存在.frm文件中,數據和索引保存在innodb_data_home_dir和innodb_data_file_path定義的表空間中,能夠是多個文件。②.使用多表空間存儲,這種方式建立的表的表結構仍然保存在.frm文件中,可是每一個表的數據和索引單獨保存在.ibd中。若是是分區表,則每一個分區對應單獨的.ibd文件,文件名是「表名+分區名」,能夠在建立分區的時候指定每一個分區的數據文件的位置,一次來將表的IO均勻的分佈在多個磁盤上。要使用多表空間的存儲方式,須要設置參數innodb_file_per_table,而且重啓服務才能生效,對於新建的表按照多表空間的方式建立,已經有的仍然使用共享表空間存儲。多表空間的數據文件沒有大小限制,不須要設置初始化大小,也不須要設置文件的最大限制、擴展大小等參數。對於使用多表空間特性的表,能夠比較方便地進行單表備份和恢復操做。
3. Memory引擎(採用哈希索引):內存表,Memory引擎將數據存儲在內存中,表結構不是存儲在內存中的,查詢時不須要執行磁盤I/O操做,因此要比MyISAM和InnoDB快不少倍,可是數據庫斷電或是重啓後,表中的數據將會丟失,表結構不會丟失.
★ 如何選擇存儲引擎:
在選擇存儲引擎時,應根據應用特色選擇合適的存儲引擎。對於複雜的應用系統,還能夠根據實際狀況選擇多種存儲引擎進行組合。
MyISAM:默認的Mysql插件式存儲引擎(5.5以前)。若是應用是以讀操做和插入操做爲主,只有少許的更新和刪除操做,而且對事務的完整性、併發性要求不是很高,那麼選擇這個存儲引擎很是合適。例如:Web、數據倉庫和其餘應用環境下最經常使用的存儲引擎之一。
InnoDB:用於處理事務應用程序,支持外鍵。若是應用對事務的完整性有較高的要求,在併發條件下要求數據的一致性,數據除了插入查詢以外,還包括不少的更新、刪除操做,那麼InnoDB存儲引擎應該是比較合適的。InnoDB存儲引擎除了有效的下降因爲刪除和更新致使的鎖定,還能夠確保事務的完整的提交和回滾,對於相似計費系統或者財務系統等對數據準確性要求比較高的系統,InnoDB都是合適的選擇。
MEMORY:將全部的數據保存在RAM中,在須要快速定位記錄和其餘相似數據的環境下,可提供極快的訪問,MEMORY的缺陷是對錶的大小有限制,太大的表沒法緩存在內存中,其次是要確保表的數據能夠恢復,數據庫異常終止後表中的數據數據是能夠恢復的。MEMORY表一般更新不太頻繁的小表,用以快速獲得訪問結果。
MERGE:用於將一系列的MyISAM表以邏輯方式組合在一塊兒,並做爲一個對象引用它們。有點突破了單個MyISAM表大小的限制,而且經過將不一樣的表分佈在多個磁盤上,能夠有效地改善MERGE表的訪問效率。這對於數據倉庫等VLDB(超大型數據庫)環境十分合適。
★ MySql中關於存儲引擎的操做:
1. 用show engines; 命令能夠顯示當前數據庫支持的存儲引擎狀況;
2. Show create table tablename; //顯示錶的建立語句;
3. show table status like ‘tablename’; //顯示錶的當前狀態值;
4. 建立數據庫表時設置存儲存儲引擎的基本語法是:
Create table tableName(
columnName(列名1) type(數據類型) attri(屬性設置),
columnName(列名2) type(數據類型) attri(屬性設置),
……..) engine = engineName
5. 修改存儲引擎,能夠用命令Alter table tableName engine =engineName
參考文章:
https://blog.csdn.net/Juwenzhe_HEBUT/article/details/77711832