溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mysql是怎樣兼容各種字符集的

發布時間:2020-05-19 15:12:17 來源:網絡 閱讀:379 作者:三月 欄目:編程語言

下面一起來了解下Mysql是怎樣兼容各種字符集的,相信大家看完肯定會受益匪淺,文字在精不在多,希望Mysql是怎樣兼容各種字符集的這篇短內容是你想要的。

過一下字符集

Unicode 作為現在通用的字符集,通常采用兩個字節表示一個字符,帶來的副作用就是,原本采用 ASCII 字符集只需要一個字節的,卻變成了 2 個字節,造成了空間浪費,而 UTF-8 編碼規則,將 Unicode 編碼成 1~4 個字節,ASCII 字符集繼續保持了 1 個字節空間,而中文編碼成了三個字節,如下圖。

Mysql是怎樣兼容各種字符集的

對存儲帶來了什么影響

先說明下 Mysql 中存在兩種字符集 utf8 和 utf8mb4,以下例子均以 Mysql 的 utf8(1~3個字節)為例。

采用 utf8 編碼的確很不錯,但是也帶來了一個問題,例如我在 Mysql 中定義了一個定長字符類型 char(5):

nametypelength
titlechar5

所謂定長字符類型代表我要給 title 分配 5 個字符大小的空間,可是 utf8 每個字符可能是 1~3 個字節,我該分配多少空間合適呢?

理論上為了兼容,最好應該采用 utf8 的最大 3 個字節進行分配,也就是 5*3 = 15 個字節的空間,這樣我不管以后怎么修改這個字段的值,空間都能完美滿足需求,但是如果此時存儲的都是英文,比如 5 個 I,就會足足浪費 10 個字節的空間,如果這列以后都存英文,那么至少會浪費 2/3 的空間。

Mysql是怎樣兼容各種字符集的

在 Mysql5.0 之前的行格式設計中,也就是 Redundant 行格式,char(5) 的確就如上面設計占用了 15 個字節空間,隨著版本的迭代,后續出來的 Compact,Dynamic,Compressed 行格式都采用了另一種設計。

在對于 utf8 這類變長編碼規則的 char 類型,采用同 varchar 類型一樣的存儲方式,就是在前面用一個或兩個字節表示該列實際占用的字節數,對應到上圖存儲 5 個 I 的例子,就是 05(實際占用字節數)+5 個存儲 I 的字節空間。

當然,更極端點,我只存儲了一個 I,這時 char(5) 就會使用 utf8 的最小字節數 1*5(char定義的字符長度)的大小作為最小分配空間,空出的 4 個字節空間用空格字符填充,也就是說,對于 title 來說,至少會分配 5 個字節空間。

Mysql是怎樣兼容各種字符集的

上面只是對列為 char(5) 的數據進行說明,在真實數據庫表中,會存在多列 varchar 或 char 類型,由上可知變長編碼規則的 char 也是按 varchar 處理的,所以這些列的實際占用字節數都會逆序存放在行格式首部,被稱為變長字段長度列表,而每列的數據,則是順序存放在列值中,如下圖,至于變長字段長度列表和 Null 值列表為什么是逆序的,大家有興趣可以去想想。

Mysql是怎樣兼容各種字符集的

帶來的更新問題

采用上面的設計,在大部分情況下能省下了很多空間,也提升了查詢效率,但是也帶來了另一個問題,那就是更新,用兩個例子說明下:

將 title 從 1個 I 更新為 5 個 I

這個很好處理,因為 char(5) 最低會分配 5 個字節空間,更改為 5 個 I,不會產生任何影響,直接更新就好。

將 title 從 5 個 I 更改為 5 個我

5 個我 = 5 * 3 = 15 個字節空間,而實際記錄只有 5 個字節空間,空間不足以支撐更新,這時候的更新只能將原數據的整行記錄刪除,然后再新分配合適空間供其使用,看似也沒什么,但是這種刪 + 增實際會對頁產生很多變更,這么多變更又要保證它的事務性,也就是記錄 redo , undo 日志,還是挺復雜和麻煩的。

Mysql的字符集轉換機制

一個請求從客戶端到 Mysql云服務器,再到表,再返回給客戶端,中間是經過多層字符集轉換的,主要包括下面4層:

轉換配置說明例子
character_set_client客戶端請求所用字符集utf8
character_set_connection服務器將 character_set_client 轉碼為 character_set_connectiongbk
表、列字符集將 character_set_connection 轉碼為表、列定義的字符集,反之亦然ascii
character_set_results返回客戶端字符集utf8

假設我們查詢 title 列,并且 Mysql 各種變量以及列字符集采用上面表格的例子,那么轉換如下:

select title from title_demo where title = 'IIIIII'

Mysql是怎樣兼容各種字符集的

當然,實際開發中,我們都會統一均采用 utf8 ,這樣就有效避免了各層字符集轉換帶來的性能影響。

看完Mysql是怎樣兼容各種字符集的這篇文章后,很多讀者朋友肯定會想要了解更多的相關內容,如需獲取更多的行業信息,可以關注我們的行業資訊欄目。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女