當前位置 博文首頁 > 信息技術智庫:7.Mysql數據庫表引擎與字符集

    信息技術智庫:7.Mysql數據庫表引擎與字符集

    作者:[db:作者] 時間:2021-09-13 18:56

    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.MyISAMInnoDB表引擎的區別

    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的,這個具體情況可以自己斟酌。

    9MyISAMInnoDB兩者的應用場景

    MyISAM管理非事務表。它提供高速存儲和檢索,以及全文搜索能力。如果應用中需要執行大量的SELECT查詢,那么MyISAM是更好的選擇。?InnoDB用于事務處理應用程序,具有眾多特性,包括ACID事務支持。如果應用中需要執行大量的INSERT或UPDATE操作,則應該使用InnoDB,這樣可以提高多用戶并發操作的性能,F在默認使用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中的utf8utf8mb4

    我們上邊說?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;

    cs
    下一篇:沒有了
zxbackspace的博客:Visual Studio Code 編輯后同步至 GitHub zxbackspace的博客:Python實現定時在微信群發送消息 zxbackspace的博客:Linux-UOS系統使用命令安裝Java hallobike的博客:從單幅圖像學習生成模型,可應用于多種圖像處 hallobike的博客:win10+tomcat 8的安裝和環境配置 hallobike的博客:Win10系統 Visual Studio 2015+openCV3.4.1安 hallobike的博客:win10系統下調通SeetaFace1.0人臉識別引擎 hallobike的博客:win10系統下Qt和VS環境配置問題 hallobike的博客:SeetaFace6人臉識別算法 hallobike的博客:人臉識別的介紹 hallobike的博客:win10系統下基于SeetaFace2.0的人臉識別系統的 hallobike的博客:神經網絡和深度學習的介紹 hallobike的博客:第三屆全國高校綠色計算系列大賽-任務挑戰組預 hallobike的博客:Python中PyTorch環境配置 hallobike的博客:數據結構課設(C++版) hallobike的博客:Win10下Tesseract-OCR安裝 hallobike的博客:使用OpenCV進行圖像全景拼接 hallobike的博客:讀COMPUTING MACHINERY AND INTELLIGENCE有感 hallobike的博客:利用OpenCV實現圖像修復 hallobike的博客:基于自適應顯著性的圖像分割 hallobike的博客:TensorFlow2.0簡介和線性回歸 hallobike的博客:邏輯回歸與交叉熵 hallobike的博客:梯度下降和多層感知器 hallobike的博客:多分類情況使用softmax函數激活 hallobike的博客:優化函數、學習速率、反向傳播 hallobike的博客:Dropout與過擬合抑制、函數式API hallobike的博客:使用遺傳算法計算函數最大值(C++代碼) hallobike的博客:python中使用matplotlib.pyplot畫函數圖像 hallobike的博客:網絡優化、超參數選擇、過擬合處理 hallobike的博客:使用tf.data數據轉換來訓練MNIST數據集 hallobike的博客:卷積深網絡CNN簡介 hallobike的博客:TensorFlow2.0的Eager模式 hallobike的博客:TensorFlow2.0批標準化 hallobike的博客:深度學習中常見的圖像處理任務 hallobike的博客:TensorFlow2.0中圖運算模式和GPU調用規則 hallobike的博客:圖像語義分割 hallobike的博客:語義分割網絡――FCN hallobike的博客:中藥槲皮素-AKT1與木犀草素IL6/VEGFA直接結合 hallobike的博客:Meat quality evaluation based on computer v hallobike的博客:京東開源FaceX-Zoo,一站式人臉識別研究平臺 hallobike的博客:目標檢測與分類API(TensorFlow官方) hallobike的博客:深度學習圖像處理相關文獻 hallobike的博客:圖像分類中的深度學習網絡匯總 hallobike的博客:一文看懂網絡中間層特征矩陣和卷積層參數 hallobike的博客:python移動文件到新的文件夾并重命名 hallobike的博客:解決OpenCV讀取視頻結束后報錯的問題 貓耳山在天邊:《Linux命令行與shell腳本編程大全》(第三版)讀 英雄哪里出來:??13萬字《C語言動漫對話教程(入門篇)》??(建議收 lyndon:CPU 上下文切換 lyndon:printf()、printk()、消息級別、日志級別 .net平臺的rabbitmq使用封裝demo詳解 C++類的特種函數生成機制詳解 Python調用百度AI實現圖片上表格識別功能 node自定義安裝更改npm全局模塊默認安裝路徑的步驟 帶你用C語言實現strtok和字符串分割函數 靜態網頁和靜態網頁性能比較 網頁標題優化原則和描述優化原則 php 怎么設置cookie記住密碼 php設置時區無效怎么辦 php __autoload 失效怎么辦 有關PHP調試的小技巧,看看吧! 從0開始:教你微信小店怎么開! 成本5元竟然賣50元 微信朋友圈賣面膜真黑啊 HashMap原理及put方法與get方法的調用過程 基于IDEA 的遠程調試 Weblogic的操作過程 UTC時間、GMT時間、本地時間、Unix時間戳的具體使用 如何利用SwiftUI實現可縮放的圖片預覽器 網站怎么利用內容更新雙重境界快速提高網站權重? php顯示繁體亂碼怎么辦 php不能開啟php_curl怎么辦
A级免费视频