0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

Unicode和UTF-8、UTF-16到底有什么不同?

Linux愛好者 ? 來源:Linux開發(fā)那些事兒 ? 作者:LinuxThings ? 2021-06-11 16:14 ? 次閱讀

由于字符編碼不同,計(jì)算機(jī)在不同國家之間的交流變得很困難,經(jīng)常會出現(xiàn)亂碼的問題,比如:對于同一個二進(jìn)制數(shù)據(jù),不同的編碼會解析出不同的字符。

當(dāng)互聯(lián)網(wǎng)迅猛發(fā)展,地域限制打破之后,人們迫切的希望有一種統(tǒng)一的規(guī)則, 對所有國家和地區(qū)的字符進(jìn)行編碼,于是 Unicode 就出現(xiàn)了。

Unicode 簡介

Unicode 是國際標(biāo)準(zhǔn)字符集,它將世界各種語言的每個字符定義一個唯一的編碼,以滿足跨語言、跨平臺的文本信息轉(zhuǎn)換。

Unicode 字符集的編碼范圍是0x0000 - 0x10FFFF, 可以容納一百多萬個字符, 每個字符都有一個獨(dú)一無二的編碼,也即每個字符都有一個二進(jìn)制數(shù)值和它對應(yīng),這里的二進(jìn)制數(shù)值也叫碼點(diǎn), 比如:漢字"中"的 碼點(diǎn)是0x4E2D, 大寫字母A的碼點(diǎn)是0x41, 具體字符對應(yīng)的 Unicode 編碼可以查詢Unicode字符編碼表。

字符集和字符編碼

字符集是很多個字符的集合,例如 GB2312 是簡體中文的字符集,它收錄了六千多個常用的簡體漢字及一些符號,數(shù)字,拼音等字符

字符編碼是 字符集的一種實(shí)現(xiàn)方式,把字符集中的字符映射為特定的字節(jié)或字節(jié)序列,它是一種規(guī)則

比如:Unicode 只是字符集,UTF-8、UTF-16、UTF-32 才是真正的字符編碼規(guī)則

Unicode 字符存儲

Unicode 是一個符號集, 它只規(guī)定了每個符號的二進(jìn)制值,但是符號具體如何存儲它并沒有規(guī)定

前面提到, Unicode 字符集的編碼范圍是0x0000 - 0x10FFFF,因此需要 1 到 3 個字節(jié)來表示

那么,對于三個字節(jié)的 Unicode字符,計(jì)算機(jī)怎么知道它表示的是一個字符而不是三個字符呢 ?

如果所有字符都用三個字節(jié)表示,那么對于那些一個字節(jié)就能表示的字符來說,有兩個字節(jié)是無意義的,對于存儲來說,這是極大的浪費(fèi),假如 , 一個普通的文本, 大部分字符都只需一個字節(jié)就能表示,現(xiàn)在如果需要三個字節(jié)才能表示,文本的大小會大出三倍左右

因此,Unicode 出現(xiàn)了多種存儲方式,常見的有 UTF-8、UTF-16、UTF-32,它們分別用不同的二進(jìn)制格式來表示 Unicode 字符

UTF-8、UTF-16、UTF-32 中的 "UTF" 是 "Unicode Transformation Format" 的縮寫,意思是"Unicode 轉(zhuǎn)換格式",后面的數(shù) 字表明至少使用多少個比特位來存儲字符, 比如:UTF-8 最少需要8個比特位也就是一個字節(jié)來存儲,對應(yīng)的, UTF-16 和 UTF-32 分別需要最少 2 個字節(jié) 和 4 個字節(jié)來存儲

UTF-8 編碼

UTF-8: 是一種變長字符編碼,被定義為將碼點(diǎn)編碼為 1 至 4 個字節(jié),具體取決于碼點(diǎn)數(shù)值中有效二進(jìn)制位的數(shù)量

UTF-8 的編碼規(guī)則:

對于單字節(jié)的符號,字節(jié)的第一位設(shè)為0,后面 7 位為這個符號的 Unicode 碼。因此對于英語字母,UTF-8 編碼和 ASCII 碼是相同的, 所以 UTF-8 能兼容 ASCII 編碼,這也是互聯(lián)網(wǎng)普遍采用 UTF-8 的原因之一

對于n字節(jié)的符號(n > 1),第一個字節(jié)的前n位都設(shè)為1,第n + 1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒有提及的二進(jìn)制位,全部為這個符號的 Unicode 碼

下表是Unicode編碼對應(yīng)UTF-8需要的字節(jié)數(shù)量以及編碼格式

Unicode編碼范圍(16進(jìn)制) UTF-8編碼方式(二進(jìn)制)
000000 - 00007F 0xxxxxxxASCII碼
000080 - 0007FF 110xxxxx10xxxxxx
000800 - 00FFFF 1110xxxx10xxxxxx10xxxxxx
01 0000 - 10 FFFF 11110xxx10xxxxxx10xxxxxx10xxxxxx

表格中第一列是Unicode編碼的范圍,第二列是對應(yīng)UTF-8編碼方式,其中紅色的二進(jìn)制"1"和"0"是固定的前綴, 字母x表示可用編碼的二進(jìn)制位

根據(jù)上面表格,要解析 UTF-8 編碼就很簡單了,如果一個字節(jié)第一位是0,則這個字節(jié)就是一個單獨(dú)的字符,如果第一位是1,則連續(xù)有多少個1,就表示當(dāng)前字符占用多少個字節(jié)

下面以"中"字 為例來說明 UTF-8 的編碼,具體的步驟如下圖, 為了便于說明,圖中左邊加了1,2,3,4的步驟編號

pYYBAGDDHVmASHtDAADDy18oYWE750.jpg

首先查詢"中"字的 Unicode 碼0x4E2D, 轉(zhuǎn)成二進(jìn)制, 總共有 16 個二進(jìn)制位, 具體如上圖 步驟1 所示

通過前面的 Unicode 編碼和 UTF-8 編碼的表格知道,Unicode 碼0x4E2D對應(yīng)000800 - 00FFFF的范圍,所以,"中"字的 UTF-8 編碼 需要3個字節(jié),即格式是1110xxxx10xxxxxx10xxxxxx

然后從"中"字的最后一個二進(jìn)制位開始,按照從后向前的順序依次填入格式中的x字符,多出的二進(jìn)制補(bǔ)為0, 具體如上圖 步驟2、步驟3 所示

于是,就得到了"中"的 UTF-8 編碼是111001001011100010101101, 轉(zhuǎn)換成十六進(jìn)制就是0xE4B8AD, 具體如上圖 步驟4 所示

UTF-16 編碼

UTF-16 也是一種變長字符編碼, 這種編碼方式比較特殊, 它將字符編碼成 2 字節(jié) 或者 4 字節(jié)

具體的編碼規(guī)則如下:

對于 Unicode 碼小于0x10000的字符, 使用2個字節(jié)存儲,并且是直接存儲 Unicode 碼,不用進(jìn)行編碼轉(zhuǎn)換

對于 Unicode 碼在0x10000和0x10FFFF之間的字符,使用4個字節(jié)存儲,這4個字節(jié)分成前后兩部分,每個部分各兩個字節(jié),其中,前面兩個字節(jié)的前6位二進(jìn)制固定為110110,后面兩個字節(jié)的前 6 位二進(jìn)制固定為110111, 前后部分各剩余 10 位二進(jìn)制表示符號的 Unicode 碼 減去0x10000的結(jié)果

大于0x10FFFF的 Unicode 碼無法用 UTF-16 編碼

下表是Unicode編碼對應(yīng)UTF-16編碼格式

Unicode編碼范圍(16進(jìn)制) 具體Unicode碼(二進(jìn)制) UTF-16編碼方式(二進(jìn)制) 字節(jié)
0000 0000 - 0000 FFFF xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 2
0001 0000 - 0010 FFFF yy yyyyyyyy xx xxxxxxxx 110110yy yyyyyyyy110111xx xxxxxxxx 4

表格中第一列是Unicode編碼的范圍,第二列是 具體Unicode碼的二進(jìn)制 ( 第二行的第二列表示的是 Unicode 碼 減去0x10000后的二進(jìn)制 ) , 第三列是對應(yīng)UTF-16編碼方式,其中紅色的二進(jìn)制"1"和"0"是固定的前綴, 字母x和y表示可用編碼的二進(jìn)制位, 第四列表示 編碼占用的字節(jié)數(shù)

前面提到過,"中"字的 Unicode 碼是4E2D, 它小于0x10000,根據(jù)表格可知,它的 UTF-16 編碼占兩個字節(jié),并且和 Unicode 碼相同,所以"中"字的 UTF-16 編碼為4E2D

我從Unicode字符表網(wǎng)站找了一個老的南阿拉伯字母, 它的 Unicode 碼是:0x10A6F, 可以訪問https://unicode-table.com/cn/10A6F/查看字符的說明, Unicode 碼對應(yīng)的字符如下圖所示

poYBAGDDHVGAeIyfAABh4fE239A398.jpg

下面以這個 老的南阿拉伯字母的 Unicode 碼0x10A6F為例來說明 UTF-164字節(jié)的編碼,具體步驟如下,為了便于說明,圖中左邊加了1,2,3,4 、5的步驟編號

pYYBAGDDHUqAKliRAACwduskwHY587.jpg

首先把 Unicode 碼0x10A6F轉(zhuǎn)成二進(jìn)制, 對應(yīng)上圖的 步驟 1

然后把 Unicode 碼0x10A6F減去0x10000, 結(jié)果為0xA6F并把這個值轉(zhuǎn)成二進(jìn)制00 0000001010 01101111,對應(yīng)上圖的 步驟 2

然后 從二進(jìn)制00 0000001010 01101111的最后一個二進(jìn)制為開始,按照從后向前的順序依次填入格式中的x和y字符,多出的二進(jìn)制補(bǔ)為0, 對應(yīng)上圖的 步驟 3、 步驟 4

于是,就計(jì)算出了 Unicode 碼0x10A6F的 UTF-16 編碼是11011000 0000001011011110 01101111, 轉(zhuǎn)換成十六進(jìn)制就是0xD802DE6F, 對應(yīng)上圖的 步驟 5

UTF-32 編碼

UTF-32 是固定長度的編碼,始終占用 4 個字節(jié),足以容納所有的 Unicode 字符,所以直接存儲 Unicode 碼即可,不需要任何編碼轉(zhuǎn)換。雖然浪費(fèi)了空間,但提高了效率。

UTF-8、UTF-16、UTF-32 之間如何轉(zhuǎn)換

前面介紹過,UTF-8、UTF-16、UTF-32 是 Unicode 碼表示成不同的二進(jìn)制格式的編碼規(guī)則,同樣,通過這三種編碼的二進(jìn)制表示,也能獲得對應(yīng)的 Unicode 碼,有了字符的 Unicode 碼,按照上面介紹的 UTF-8、UTF-16、UTF-32 的編碼方法 就能轉(zhuǎn)換成任一種編碼了

UTF 字節(jié)序

最小編碼單元是多字節(jié)才會有字節(jié)序的問題存在,UTF-8 最小編碼單元是一字節(jié),所以 它是沒有字節(jié)序的問題,UTF-16 最小編碼單元是 2 個字節(jié),在解析一個 UTF-16 字符之前,需要知道每個編碼單元的字節(jié)序

比如:前面提到過,"中"字的 Unicode 碼是4E2D,"?"字符的 Unicode 碼是2D4E, 當(dāng)我們收到一個 UTF-16 字節(jié)流4E2D時,計(jì)算機(jī)如何識別它表示的是字符"中"還是 字符"?"呢 ?

所以,對于多字節(jié)的編碼單元,需要有一個標(biāo)記顯式的告訴計(jì)算機(jī),按照什么樣的順序解析字符,也就是字節(jié)序,字節(jié)序分為 大端字節(jié)序 和 小端字節(jié)序

小端字節(jié)序簡寫為 LE( Little-Endian ), 表示 低位字節(jié)在前,高位字節(jié)在后, 高位字節(jié)保存在內(nèi)存的高地址端,而低位字節(jié)保存在內(nèi)存的低地址端

大端字節(jié)序簡寫為 BE( Big-Endian ), 表示 高位字節(jié)在前,低位字節(jié)在后,高位字節(jié)保存在內(nèi)存的低地址端,低位字節(jié)保存在在內(nèi)存的高地址端

下面以0x4E2D為例來說明大端和小端,具體參見下圖:

poYBAGDDHUOAHvDhAABQAX9JQcg147.jpg

數(shù)據(jù)是從高位字節(jié)到低位字節(jié)顯示的,這也更符合人們閱讀數(shù)據(jù)的習(xí)慣,而內(nèi)存地址是從低地址向高地址增加

所以,字符0x4E2D數(shù)據(jù)的高位字節(jié)是4E,低位字節(jié)是2D

按照大端字節(jié)序的高位字節(jié)保存內(nèi)存低地址端的規(guī)則,4E保存到低內(nèi)存地址0x10001上,2D則保存到高內(nèi)存地址0x10002上

對于小端字節(jié)序,則正好相反,數(shù)據(jù)的高位字節(jié)保存到內(nèi)存的高地址端,低位字節(jié)保存到內(nèi)存低地址端的,所以4E保存到高內(nèi)存地址0x10002上,2D則保存到低內(nèi)存地址0x10001上

BOM

BOM 是 byte-order mark 的縮寫,是 "字節(jié)序標(biāo)記" 的意思, 它常被用來當(dāng)做標(biāo)識文件是以 UTF-8、UTF-16 或 UTF-32 編碼的標(biāo)記

在 Unicode 編碼中有一個叫做 "零寬度非換行空格" 的字符 ( ZERO WIDTH NO-BREAK SPACE ), 用字符FEFF來表示

對于 UTF-16 ,如果接收到以FEFF開頭的字節(jié)流, 就表明是大端字節(jié)序,如果接收到FFFE, 就表明字節(jié)流 是小端字節(jié)序

UTF-8 沒有字節(jié)序問題,上述字符只是用來標(biāo)識它是 UTF-8 文件,而不是用來說明字節(jié)順序的。"零寬度非換行空格" 字符 的 UTF-8 編碼是EF BB BF, 所以如果接收到以EF BB BF開頭的字節(jié)流,就知道這是UTF-8 文件

下面的表格列出了不同 UTF 格式的固定文件頭

UTF編碼 固定文件頭
UTF-8 EF BB BF
UTF-16LE FF FE
UTF-16BE FE FF
UTF-32LE FF FE 00 00
UTF-32BE 00 00 FE FF

根據(jù)上面的 固定文件頭,下面列出了"中"字在文件中的存儲 ( 包含文件頭 )

編碼 固定文件頭
Unicode 編碼 0X004E2D
UTF-8 EF BB BF4E 2D
UTF-16BE FE FF4E 2D
UTF-16LE FF FE2D 4E
UTF-32BE 00 00 FE FF00 00 4E 2D
UTF-32LE FF FE 00 002D 4E 00 00

常見的字符編碼的問題

Redis 中文key的顯示

有時候我們需要向redis中寫入含有中文的數(shù)據(jù),然后在查看數(shù)據(jù),但是會看到一些其他的字符,而不是我們寫入的中文

pYYBAGDDHTyAUA9FAAA9FlkDs7c977.jpg

上圖中,我們向redis 寫入了一個 "中" 字,通過 get 命令查看的時候無法顯示我們寫入的 "中" 字

這時候加一個 --raw 參數(shù),重新啟動 redis-cli 即可,也即 執(zhí)行 redis-cli --raw 命令啟動redis客戶端,具體的如下圖所示

poYBAGDDHTOADwqeAABSHh9Q28I081.jpg

MySQL 中的 utf8 和 utf8mb4

MySQL 中的 "utf8" 實(shí)際上不是真正的 UTF-8, "utf8" 只支持每個字符最多 3 個字節(jié), 對于超過 3 個字節(jié)的字符就會出錯, 而真正的 UTF-8 至少要支持 4 個字節(jié)

MySQL 中的 "utf8mb4" 才是真正的 UTF-8


下面以 test 表為例來說明, 表結(jié)構(gòu)如下:

mysql> show create table testG *************************** 1. row *************************** Table: test Create Table: CREATE TABLE `test` ( `name` char(32) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)

向test表分別插入"中"字 和 Unicode 碼為0x10A6F的字符,這個字符需要從https://unicode-table.com/cn/10A6F/直接復(fù)制到 MySQL 控制臺上,手工輸入會無效,具體的執(zhí)行結(jié)果如下圖:

pYYBAGDDHSuAZP0jAAC80Xc5gO4372.jpg

從上圖可以看出,插入"中"字 成功,插入0x10A6F字符失敗,錯誤提示無效的字符串,xF0X90XA9xAF正是0x10A6F字符的 UTF-8 編碼,占用4個字節(jié), 因?yàn)?MySQL 的 utf8 編碼最多只支持3個字節(jié),所以插入會失敗

把test表的字符集改成utf8mb4, 排序規(guī)則 改成utf8bm4_unicode_ci, 具體如下圖所示:

poYBAGDDHSSAMudtAAE2A0yDEDo599.jpg

字符集和排序方式修改之后,再次插入0x10A6F字符, 結(jié)果是成功的,具體執(zhí)行結(jié)果如下圖所示

poYBAGDDHR6AfRgyAAB3UflKJFw084.jpg

上圖中,set names utf8mb4是為了測試方便,臨時修改當(dāng)前會話的字符集,以便保持和 服務(wù)器一致,實(shí)際解決這個問題需要修改my.cnf配置中 服務(wù)器和客戶端的字符集

小結(jié)

本文從字符編碼的歷史介紹了 Unicode 出現(xiàn)的原因,接著介紹了 Unicode 字符集中 三種不同的編碼方式:UTF-8、UTF-16、UTF-32 以及它們的的編碼方法,緊接著介紹了 字節(jié)序、BOM ,最后講到了字符集在 MySQL 和 Redis 應(yīng)用中常見的問題以及解決方案 。

責(zé)任編輯:lq6

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 字符
    +關(guān)注

    關(guān)注

    0

    文章

    232

    瀏覽量

    25154
  • Unicode
    +關(guān)注

    關(guān)注

    0

    文章

    24

    瀏覽量

    12544
  • UTF-8
    +關(guān)注

    關(guān)注

    0

    文章

    13

    瀏覽量

    7840

原文標(biāo)題:Unicode、UTF-8、UTF-16,終于懂了

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    RTOS與Linux到底有什么區(qū)別

    很多做嵌入式開發(fā)的小伙伴都存在這樣的疑惑:RTOS與Linux到底有什么區(qū)別?
    的頭像 發(fā)表于 10-29 09:53 ?222次閱讀

    CMOS運(yùn)放的輸入阻抗到底有多高呢?

    都說CMOS運(yùn)放輸入阻抗高,到底有多高呢?可有一個量化指標(biāo)?
    發(fā)表于 09-06 06:59

    求助,這個電路U1A運(yùn)放同相端的R1電阻到底有什么作用???

    想問下這個電路U1A運(yùn)放同相端的R1電阻到底有什么作用啊?很郁悶。
    發(fā)表于 08-27 07:09

    打開文件為ANSI的文件,中文會顯示亂碼,為什么?

    打開文件為ANSI的文件,中文會顯示亂碼!如果文件是UTF-8的格式是正常的
    發(fā)表于 07-16 07:33

    ESP32設(shè)置中文藍(lán)牙設(shè)備名稱會異常顯示亂碼,原因是什么?

    ESP32 設(shè)置中文藍(lán)牙設(shè)備名稱會異常顯示亂碼,原因是什么? 這是因?yàn)榇藭r編輯器的中文編碼格式不是 UTF-8,需要把編輯器的編碼格式改成 UTF-8
    發(fā)表于 06-13 06:21

    EWSTM8-2201 or 3101安裝說明上有的說選“是”,有的說選“否”,二者到底有什么區(qū)別?對工程什么影響?

    the installation. ......... 安裝說明上有的說選“是”,有的說選“否”,二者到底有什么區(qū)別?對工程什么影響?
    發(fā)表于 04-28 08:08

    STemWin fatfs編碼格式?jīng)_突怎么解決?

    最近手上有一個項(xiàng)目,需要用到STemWin,fatfs和sd卡,由于STemWin顯示漢字用的XBF格式,xbf格式的漢字用的是UTF-8格式的;用fatfs創(chuàng)建以漢字為文件名的csv格式的文件
    發(fā)表于 04-12 08:12

    RTT使用unicode編碼,編譯不通過是為什么?

    1、我們?yōu)榱嗽O(shè)備兼容俄語,就需要使用到unicode編碼,將字符串保存文件保存為unicode編碼,但是編譯之后出現(xiàn)一大堆錯誤。 2、編譯器使用的是rtthread_studio. 3、我們的編譯器不支持unicode編碼嗎?
    發(fā)表于 03-27 08:01

    采用UTF8UTF16都無法使用中文SSID怎么解決?

    采用 UTF8UTF16都無法使用中文SSID 將wifi ssid設(shè)置為 \" test12 \",分別用了以下 3種 unicode編解碼格格式,測試情況分分如下: 1.格式一:UT
    發(fā)表于 02-29 06:36

    網(wǎng)線到底有多少種連接器

    我們在談?wù)摼W(wǎng)線的時候,聊得最多的,一定是它的連接器,它在連接過程中扮演著極為重要的角色。網(wǎng)線到底有多少種連接器?本期我們將從工業(yè)級使用出發(fā),來看看這根似乎普通的網(wǎng)線,在連接器上有多么努力。
    的頭像 發(fā)表于 01-26 10:06 ?550次閱讀

    如何解決Python爬蟲中文亂碼問題?Python爬蟲中文亂碼的解決方法

    決Python爬蟲中文亂碼問題。 一、了解字符編碼 在解決亂碼問題之前,我們首先需要了解一些基本的字符編碼知識。常見的字符編碼ASCII、UTF-8和GBK等。 1. ASCII:是一種用于表示英文字母、數(shù)字和常用符號的字符編碼,它使用一個字節(jié)(
    的頭像 發(fā)表于 01-12 15:11 ?2062次閱讀

    使用Solopace.Gem遠(yuǎn)程訪問內(nèi)網(wǎng)ERP-dolibarr

    default character set utf8mb4 collate utf8mb4_unicode_ci; grant all privileges on dolibarr_db.
    的頭像 發(fā)表于 12-25 11:45 ?692次閱讀
    使用Solopace.Gem遠(yuǎn)程訪問內(nèi)網(wǎng)ERP-dolibarr

    單片機(jī)也可以輕松玩轉(zhuǎn)UTF-8碼和TTF字體了

    要讓智能設(shè)備支持各國不同的文字,首先得有支持全球文字的編碼集,時下最出名的要數(shù)UTF-8碼了。
    的頭像 發(fā)表于 11-23 17:18 ?4019次閱讀
    單片機(jī)也可以輕松玩轉(zhuǎn)<b class='flag-5'>UTF-8</b>碼和TTF字體了

    為啥string和[]byte類型轉(zhuǎn)換需要一定的代價?

    簡單的來說字符串是一系列8位字節(jié)的集合,通常但不一定代表UTF-8編碼的文本。字符串可以為空,但不能為nil。而且字符串的值是不能改變的。
    的頭像 發(fā)表于 11-16 16:43 ?369次閱讀

    mysql8.0默認(rèn)字符集是什么

    MySQL 8.0 默認(rèn)字符集是 utf8mb4。 MySQL 8.0 是當(dāng)前最新的開源關(guān)系型數(shù)據(jù)庫管理系統(tǒng),由Oracle公司開發(fā)和維護(hù)。MySQL 8.0 默認(rèn)字符集是 utf8mb4,這個
    的頭像 發(fā)表于 11-16 14:48 ?1746次閱讀