7.Mysql数据库表引擎与字符集
7.Mysql數據庫表引擎與字符集
1.服務器處理客戶端請求
其實不論客戶端進程和服務器進程是采用哪種方式進行通信,最后實現的效果都是:客戶端進程向服務器進程發送
一段文本(MySQL語句),服務器進程處理后再向客戶端進程發送一段文本(處理結果)。那服務器進程對客戶
端進程發送的請求做了什么處理,才能產生最后的處理結果呢?客戶端可以向服務器發送增刪改查各類請求,我們
這里以比較復雜的查詢請求為例來畫個圖展示一下大致的過程:
雖然查詢緩存有時可以提升系統性能,但也不得不因維護這塊緩存而造成一些開銷,比如每次都要去查詢緩
存中檢索,查詢請求處理完需要更新查詢緩存,維護該查詢緩存對應的內存區域。從MySQL 5.7.20開始,不
推薦使用查詢緩存,并在MySQL 8.0中刪除。
2.存儲引擎
MySQL?服務器把數據的存儲和提取操作都封裝到了一個叫?存儲引擎?的模塊里。我們知道?表?是由一行一行的記錄組成的,但這只是一個邏輯上的概念,物理上如何表示記錄,怎么從表中讀取數據,怎么把數據寫入具體的物理存儲器上,這都是?存儲引擎?負責的事情。為了實現不同的功能,?MySQL?提供了各式各樣的?存儲引擎?,不同?存儲引擎?管理的表具體的存儲結構可能不同,采用的存取算法也可能不同。
存儲引擎以前叫做?表處理器?,它的功能就是接收上層傳下來的指令,然后對表中的數據進行提取或寫入操作。
為了管理方便,人們把?連接管理?、?查詢緩存?、?語法解析?、?查詢優化?這些并不涉及真實數據存儲的功能劃分為MySQL server?的功能,把真實存取數據的功能劃分為?存儲引擎?的功能。各種不同的存儲引擎向上邊的?MySQLserver?層提供統一的調用接口(也就是存儲引擎API),包含了幾十個底層函數,像"讀取索引第一條內容"、"讀取索引下一條內容"、"插入記錄"等等。
所以在?MySQL server?完成了查詢優化后,只需按照生成的執行計劃調用底層存儲引擎提供的API,獲取到數據后返回給客戶端就好了。
MySQL?支持非常多種存儲引擎:
ARCHIVE?用于數據存檔(行被插入后不能再修改)
BLACKHOLE?丟棄寫操作,讀操作會返回空內容
CSV?在存儲數據時,以逗號分隔各個數據項
FEDERATED?用來訪問遠程表
InnoDB?具備外鍵支持功能的事務存儲引擎
MEMORY?置于內存的表
MERGE?用來管理多個MyISAM表構成的表集合
MyISAM?主要的非事務處理存儲引擎
NDB?MySQL集群專用存儲引擎
3.MyISAM和InnoDB表引擎的區別
1)?事務支持
MyISAM不支持事務,而InnoDB支持。
事務:訪問并更新數據庫中數據的執行單元。事物操作中,要么都執行要么都不執行
2)?存儲結構
MyISAM:每個MyISAM在磁盤上存儲成三個文件。
- .frm文件存儲表結構。
- .MYD文件存儲數據。
- .MYI文件存儲索引。
InnoDB:主要分為兩種文件進行存儲
- .frm?存儲表結構
- .ibd?存儲數據和索引?(也可能是多個.ibd文件,或者是獨立的表空間文件)
3)?表鎖差異
MyISAM:只支持表級鎖,用戶在操作myisam表時,select,update,delete,insert語句都會給表自動加鎖,如果加鎖以后的表滿足insert并發的情況下,可以在表的尾部插入新的數據。
?InnoDB:支持事務和行級鎖,是innodb的最大特色。
行鎖大幅度提高了多用戶并發操作的新能。但是InnoDB的行鎖,只是在WHERE的主鍵是有效的,非主鍵的WHERE都會鎖全表的。
4)?表主鍵
MyISAM:允許沒有任何索引和主鍵的表存在,索引都是保存行的地址。?InnoDB:如果沒有設定主鍵或者非空唯一索引,就會自動生成一個6字節的主鍵(用戶不可見),數據是主索引的一部分,附加索引保存的是主索引的值。
InnoDB的主鍵范圍更大,最大是MyISAM的2倍。
5)?表的具體行數
MyISAM:保存有表的總行數,如果select count() from table;會直接取出出該值。?InnoDB:沒有保存表的總行數
(只能遍歷),如果使用select count() from table;就會遍歷整個表,消耗相當大,但是在加了wehre條件后,
myisam和innodb處理的方式都一樣。
6) CURD操作
MyISAM:如果執行大量的SELECT,MyISAM是更好的選擇。?InnoDB:如果你的數據執行大量的INSERT或UPDATE,出于性能方面的考慮,應該使用InnoDB表。DELETE?從性能上InnoDB更優,但DELETE FROM table時,InnoDB不會重新建立表,而是一行一行的刪除,在innodb上如果要清空保存有大量數據的表,最好使用truncate table這個命令。
7)?外鍵
MyISAM:不支持?InnoDB:支持
8)?查詢效率
MyISAM相對簡單,所以在效率上要優于InnoDB,小型應用可以考慮使用MyISAM。
推薦考慮使用InnoDB來替代MyISAM引擎,原因是InnoDB自身很多良好的特點,比如事務支持、存儲?過程、視圖、行級鎖定等等,在并發很多的情況下,相信InnoDB的表現肯定要比MyISAM強很多。
另外,任何一種表都不是萬能的,只用恰當的針對業務類型來選擇合適的表類型,才能最大的發揮MySQL的性能優勢。如果不是很復雜的Web應用,非關鍵應用,還是可以繼續考慮MyISAM的,這個具體情況可以自己斟酌。
9)MyISAM和InnoDB兩者的應用場景
MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。如果應用中需要執行大量的SELECT查詢,那么MyISAM是更好的選擇。?InnoDB用于事務處理應用程序,具有眾多特性,包括ACID事務支持。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多用戶并發操作的性能。現在默認使用InnoDB。
4.了解一下字符集和亂碼
字符集簡介
我們知道在計算機中只能存儲二進制數據,那該怎么存儲字符串呢?當然是建立字符與二進制數據的映射關系了,
建立這個關系最起碼要搞清楚兩件事兒:
1.?你要把哪些字符映射成二進制數據?
也就是界定清楚字符范圍。
2.?怎么映射?
將一個字符映射成一個二進制數據的過程也叫做?編碼?,將一個二進制數據映射到一個字符的過程叫做?解碼?。人們抽象出一個?字符集?的概念來描述某個字符范圍的編碼規則
我們看一下一些常用字符集的情況:
ASCII?字符集
共收錄128個字符,包括空格、標點符號、數字、大小寫字母和一些不可見字符。由于總共才128個字符,所以可以使用1個字節來進行編碼,我們看一些字符的編碼方式:
- 'L' -> 01001100(十六進制:0x4C,十進制:76)
- 'M' -> 01001101(十六進制:0x4D,十進制:77)
ISO 8859-1?字符集
共收錄256個字符,是在?ASCII?字符集的基礎上又擴充了128個西歐常用字符(包括德法兩國的字母),也可以使用1個字節來進行編碼。這個字符集也有一個別名?latin1?。
GB2312?字符集
收錄了漢字以及拉丁字母、希臘字母、日文平假名及片假名字母、俄語西里爾字母。其中收錄漢字6763個,其他文字符號682個。同時這種字符集又兼容?ASCII?字符集,所以在編碼方式上顯得有些奇怪:
- 如果該字符在?ASCII?字符集中,則采用1字節編碼。
- 否則采用2字節編碼。
這種表示一個字符需要的字節數可能不同的編碼方式稱為?變長編碼方式?。比方說字符串?'愛u'?,其
中?'愛'?需要用2個字節進行編碼,編碼后的十六進制表示為?0xCED2?,?'u'?需要用1個字節進行編碼,編碼后的十六進制表示為?0x75?,所以拼合起來就是?0xCED275?。
小貼士:?我們怎么區分某個字節代表一個單獨的字符還是代表某個字符的一部分呢?別忘了?ASCII?字符集只收錄128個字符,使用0~127就可以表示全部字符,所以如果某個字節是在0~127之內的,就意味著一個字節代表一個單獨的字符,否則就是兩個字節代表一個單獨的字符。
GBK?字符集
GBK?字符集只是在收錄字符范圍上對?GB2312?字符集作了擴充,編碼方式上兼容?GB2312?。
utf8?字符集
收錄地球上能想到的所有字符,而且還在不斷擴充。這種字符集兼容?ASCII?字符集,采用變長編碼方式,編碼一個字符需要使用1~4個字節,比方說這樣:
- 'L' -> 01001100(十六進制:0x4C)
- '啊' -> 111001011001010110001010(十六進制:0xE5958A)
小貼士:?其實準確的說,utf8只是Unicode字符集的一種編碼方案,Unicode字符集可以采用utf8、
utf16、utf32這幾種編碼方案,utf8使用1~4個字節編碼一個字符,utf16使用2個或4個字節編碼一個字符,utf32使用4個字節編碼一個字符。更詳細的Unicode和其編碼方案的知識不是本書的重點,大家上網查查哈~?MySQL中并不區分字符集和編碼方案的概念,所以后邊嘮叨的時候把utf8、utf16、utf32 都當作一種字符集對待。
對于同一個字符,不同字符集也可能有不同的編碼方式。比如對于漢字?'我'?來說,?ASCII?字符集中根本沒有收錄這個字符,?utf8?和?gb2312?字符集對漢字?我?的編碼方式如下:
- utf8編碼:111001101000100010010001 (3個字節,十六進制表示是:0xE68891)
- gb2312編碼:1100111011010010 (2個字節,十六進制表示是:0xCED2)
5.MySQL中的utf8和utf8mb4
我們上邊說?utf8?字符集表示一個字符需要使用1~4個字節,但是我們常用的一些字符使用1~3個字節就可以表示了。而在?MySQL?中字符集表示一個字符所用最大字節長度在某些方面會影響系統的存儲和性能,所以設計?MySQL的大叔偷偷的定義了兩個概念:
- utf8mb3?:閹割過的?utf8?字符集,只使用1~3個字節表示字符。
- utf8mb4?:正宗的?utf8?字符集,使用1~4個字節表示字符。
有一點需要大家十分的注意,在?MySQL?中?utf8?是?utf8mb3?的別名,所以之后在?MySQL?中提到?utf8?就意味著使用1~3個字節來表示一個字符,如果大家有使用4字節編碼一個字符的情況,比如存儲一些emoji表情啥的,那請使用?utf8mb4?。
字符集的查看
MySQL?支持好多好多種字符集,查看當前?MySQL?中支持的字符集可以用下邊這個語句:
show?charset;
總結
以上是生活随笔為你收集整理的7.Mysql数据库表引擎与字符集的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP之MVC项目实战(三)
- 下一篇: 利用工厂模式实现怪物系统