国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MySQL 字符集概念與原理及如何配置字符集 - 超詳細(xì)圖文詳解

這篇具有很好參考價值的文章主要介紹了MySQL 字符集概念與原理及如何配置字符集 - 超詳細(xì)圖文詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄

一、字符集概念

1、字符(Character)

2、字符編碼

3、字符集(Character set)

二、字符集原理

1、ASCII字符集

2、GB2312

3、GBK

4、GB18030

5、BIG5

6、Unicode 編碼

三、字符序

四、MySQL字符集 & 字符序

1、mysql 字符集

2、mysql 字符序

3、字符集與字符序的關(guān)系

五、MySQL 數(shù)據(jù)存儲字符集 | 數(shù)據(jù)庫內(nèi)部操作字符集

1. 字符集層級關(guān)系

2、如何設(shè)置字符集

2.1 服務(wù)器字符集設(shè)置

2.2 數(shù)據(jù)庫字符集設(shè)置

2.3?數(shù)據(jù)表字符集設(shè)置

2.4?字段字符集設(shè)置

3、多級的字符集 & 多種字符集的作用

六、MySQL 客戶端與服務(wù)端交互字符集 | 數(shù)據(jù)庫外部字符集

1、客戶端與服務(wù)端的交互

2、如何設(shè)置字符集


? ? 我們在使用 MySQL 的過程中,經(jīng)常會碰到諸如亂碼之類的問題。字符編碼與字符集密切相關(guān),MySQL 支持種類繁多的字符集類型,這些字符集到底如何影響 MySQL 數(shù)據(jù)存儲與數(shù)據(jù)傳輸?shù)哪??我們該如何選擇正確的字符集:character_set_client、character_set_connectioncharacter_set_results?那就通過這篇文章來幫你捋清個中細(xì)節(jié)和解除困擾吧!

本文依賴以下環(huán)境:

操作系統(tǒng):MAC OS 10.11.6

MySQL:Server version: 5.6.21 MySQL Community Server (GPL)

一、字符集概念

1、字符(Character)

字符是各種文字和符號的總稱,包括各國家文字、標(biāo)點符號、圖形符號、數(shù)字、??(emoji表情)等屬于字符的范疇。

2、字符編碼

計算機(jī)是通過 BIT 來存儲數(shù)據(jù)的,將人類可識別的字符轉(zhuǎn)換成計算機(jī)能夠存儲的形式,這個過程就是字符編碼。

3、字符集(Character set)

字符集是多個字符的集合,包含一組字符以及對應(yīng)的編碼方式。字符集種類較多,每個字符集包含的字符個數(shù)和編碼方式不同,常見字符集名稱:ASCII 字符集、GB2312 字符集、BIG5 字符集、 GB18030 字符集、Unicode 字符集等。

二、字符集原理

1、ASCII字符集

我們熟知的 ASCII 字符集是一種現(xiàn)代美國英語適用的字符集。包括的字符有數(shù)字、大小寫字母、分號、換行之類的符號,編碼方式是用一個 7bit 表示一個字符,例如A的編碼是 65,b 的編碼是 98。

ASCII(American Standard Code for Information Interchange,美國標(biāo)準(zhǔn)信息交換代碼)是基于拉丁字母的一套電腦編碼系統(tǒng),主要用于顯示現(xiàn)代英語和其他西歐語言,主要編碼表如下圖所示。

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

2、GB2312

GB2312 字符集是一種對漢字比較友好的字符集,共收錄 6700 多個漢字,基本涵蓋了絕大部分常用漢字。不過,GB2312 字符集不支持絕大部分的生僻字和繁體字。對于英語字符,GB2312 編碼和 ASCII 碼是相同的,1 字節(jié)編碼即可。對于非英字符,需要 2 字節(jié)編碼。

3、GBK

GBK 字符集可以看作是 GB2312 字符集的擴(kuò)展,兼容 GB2312 字符集,共收錄了 20000 多個漢字。GBK 中 K 是漢語拼音 Kuo Zhan(擴(kuò)展)中的 “Kuo” 的首字母。

4、GB18030

GB18030 完全兼容 GB2312 和 GBK 字符集,納入中國國內(nèi)少數(shù)民族的文字,且收錄了日韓漢字,是目前為止最全面的漢字字符集,共收錄漢字 70000 多個。

5、BIG5

BIG5 主要針對的是繁體中文,收錄了 13000 多個漢字。

6、Unicode 編碼

ASCII 只對英文符號和英文字母做了編碼,GB2312對英文符號,英文字母,漢字做了編碼。每個國家為了更加適合本國語言,都有一套自己的字符集。不同的字符集可以表示的字符范圍以及編碼規(guī)則存在差異。同一個編碼,對于不同的字符集來說就可能代表不同的字符:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

這就導(dǎo)致了一個非常嚴(yán)重的問題:使用錯誤的編碼方式查看一個包含字符的文件就會產(chǎn)生亂碼現(xiàn)象。就比如說你使用 UTF-8 編碼方式打開 GB2312 編碼格式的文件就會出現(xiàn)亂碼。示例:“?!边@個漢字 GB2312 編碼后的十六進(jìn)制數(shù)值為 “C5A3”,而 “C5A3” 用 UTF-8 解碼之后得到的卻是 “?”

為了解決不同語言編碼之間不兼容的問題,Unicode 出現(xiàn)了。Unicode 字符集致力于為全世界每一個語言的每一個字符都有統(tǒng)一且唯一的編碼,Unicode 字符序號的范圍是 0x000000 到0x10FFFF,可以容納 110 多萬個字符。UTF8、UTF16、UTF32 是 Unicode 編碼的不同實現(xiàn)方式:

  • UTF-8 使用 1 到 4 個字節(jié)為每個字符編碼, UTF-16 使用 2 或 4 個字節(jié)為每個字符編碼,UTF-32 固定位 4 個字節(jié)為每個字符編碼。
  • UTF-8 可以根據(jù)不同的符號自動選擇編碼的長短,像英文字符只需要 1 個字節(jié)就夠了,這一點 ASCII 字符集一樣 。因此,對于英語字符,UTF-8 編碼和 ASCII 碼是相同的。
  • UTF-32 的規(guī)則最簡單,不過缺陷也比較明顯,對于英文字母這類字符消耗的空間是 UTF-8 的 4 倍之多。
    ?

三、字符序

一個字符集中有多個字符,那么如何對其中的字符進(jìn)行排序呢?這就是字符序。簡單來說,字符序就是字符排序的規(guī)則集合。

一個字符集中有多個字符,那么如何對其中的字符進(jìn)行排序呢?這就是字符序。比如一個字符集有下面幾個字符以及字符編碼:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

我們可以直接按照 A > B > a > b 的規(guī)則來進(jìn)行排序,這就是這個簡單字符集的一個字符序。如果想讓小寫字母放在前面,比如 a > b > A > B,這又是一種字符序。如果還想加上大小寫無關(guān)或大小寫相關(guān),這就產(chǎn)生了不同的字符序。

四、MySQL字符集 & 字符序

接下來我們來看看 MySQL 的字符集與字符序。MySQL 目前支持多種字符集,支持在不同的字符集之間轉(zhuǎn)換(便于移植和支持多語言)。

1、mysql 字符集

通過命令: mysql -u[username]?-p[password]? 連接上MySQL后,用下面命令查詢MySQL 支持的字符集:

SHOW CHARACTER SET;

結(jié)果:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

指定條件查詢:?

SHOW CHARACTER SET LIKE 'utf%';

結(jié)果:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

字段含義:

  • Charset: 字符集的名稱;
  • Description:字符集的簡單描述;
  • Default collation:該字符集的默認(rèn)字符序;
  • Maxlen:該字符集中字符最大存儲長度。

2、mysql 字符序

每個字符集都對應(yīng)一個或多個字符序,可以通過下面的語句查看所有的字符序:

SHOW COLLATION;

結(jié)果(部分展示):

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

?指定條件查詢:

SHOW COLLATION WHERE Charset = 'utf8mb4';

結(jié)果:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

字段含義:?

  • Collation:字符序名稱;
  • Charset:該字符序關(guān)聯(lián)的字符集;
  • Id:字符序ID;
  • Default:該字符序是否是所關(guān)聯(lián)的字符集的默認(rèn)字符序。比armscii8_general_ci就是armscii8的默認(rèn)字符序,而armscii8_bin就不是;
  • Compiled:字符集是否已編譯到服務(wù)器中;
  • Sortlen:這與對以字符集表示的字符串進(jìn)行排序所需的內(nèi)存量有關(guān);
  • Pad_attribute:這表明了字符序在比較字符串時對末尾padding的處理。NO PAD表明在比較字符串時,末尾的padding也會考慮進(jìn)去,否則不考慮。

每個字符序都是以該字符序所關(guān)聯(lián)的字符集為前綴的,同時還有一些有規(guī)律的后綴:

  • bin:二進(jìn)制;
  • ci:大小寫不敏感;
  • cs:大小寫敏感;
  • ai:口音(Accent)不敏感;
  • as:口音敏感;
  • ks:假名(Kanatype)敏感。

同時有的字符序是面向某種語言的,也會在字符序名字中有所體現(xiàn),比如big5_chinese_ci。
?

3、字符集與字符序的關(guān)系

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

字符集與字符序的關(guān)系可以上面的圖來表示:

  • 每個字符集都有一個或多個字符序;
  • 每個字符集都有一個默認(rèn)的字符序;
  • 每個字符序都關(guān)聯(lián)一個且只有一個字符集;
  • 兩個不同的字符集沒有相同的字符序。

五、MySQL 數(shù)據(jù)存儲字符集 | 數(shù)據(jù)庫內(nèi)部操作字符集

1. 字符集層級關(guān)系

MySQL 是按層級來設(shè)定字符集與字符序的,MySQL 可以設(shè)置:服務(wù)器級字符集、數(shù)據(jù)庫級字符集、數(shù)據(jù)表級字符集、表列級別字符集。實際上,最終使用字符集的地方是存儲字符的列,它決定了數(shù)據(jù)庫中存儲的數(shù)據(jù)采用哪個字符集的編碼和字符序。

結(jié)構(gòu)圖:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

?層級圖:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

如上圖所示:

上一層級如果沒有指定字符集與字符序,就采用下一層級的字符集與字符序。也就是說:新建數(shù)據(jù)庫時沒有指定字符集,就默認(rèn)設(shè)置為服務(wù)器的字符集;如果新建數(shù)據(jù)表時沒有指定字符集,就默認(rèn)設(shè)置為數(shù)據(jù)庫的字符集;如果向數(shù)據(jù)表添加新列時沒有指定列的字符集,那么這些列就默認(rèn)設(shè)置為數(shù)據(jù)表的字符集。與字符集相同,如果不特別指定,字符序也采取了默認(rèn)值繼承的方式。

另一方面,直接改變這四個層次的編碼并不會改變它們各自所有下層對象的當(dāng)前編碼。比如修改 Server 級,那么所有已經(jīng)存在的數(shù)據(jù)庫、數(shù)據(jù)表、表、列的字符集都不會發(fā)生改變。同樣,修改某個字段的字符集,該字段下每一條現(xiàn)有記錄的字符仍然按原來的編碼存儲。

2、如何設(shè)置字符集

我們先來看下,MySQL 剛安裝完,MySQL 字符集的的初始字符集和字符序是什么?

查看字符集變量:

SHOW VARIABLES LIKE 'character_set\_%';

查看字符序變量:

SHOW VARIABLES LIKE '%collation%';

查詢結(jié)果:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

character_set_server:服務(wù)器的字符集是 latin1

collation_server: 服務(wù)器的字符序是 latin1_swedish_ci

character_set_database:數(shù)據(jù)庫的字符集是 latin1

collation_database:數(shù)據(jù)庫的字符序是 latin1_swedish_ci

從上圖可以看出,MySQL 服務(wù)器安裝后已經(jīng)初始化了服務(wù)器和數(shù)據(jù)庫的默認(rèn)字符集和字符序,那么,默認(rèn)的配置從何而來呢?

  1. 編譯MySQL 時,指定了一個默認(rèn)的字符集,這個字符集是 latin1,MySQL 8.0 以后默認(rèn)值應(yīng)是 utf8mb4;
  2. 安裝MySQL 時,可以在配置文件 (myconf | my.ini) 中指定一個默認(rèn)的的字符集,如果沒指定,這個值繼承自編譯時指定的;
  3. 啟動mysqld 時,可以在命令行參數(shù)中指定一個默認(rèn)的的字符集,如果沒指定,這個值繼承自配置文件中的配置,此時 character_set_server 被設(shè)定為這個默認(rèn)的字符集。

另外,我們在創(chuàng)建數(shù)據(jù)庫、表、添加字段時,都可以默認(rèn)采用上一級的字符集和字符序,也可以在創(chuàng)建時自行指定。

2.1 服務(wù)器字符集設(shè)置

通過 character_set_server 變量的設(shè)定字符集的幾個方式:

方式 1:在 my.cnf | my.ini 中配置

[mysqld]
character-set-server=utf8

方式 2:啟動時配置參數(shù)

mysqld --charater-set-server=utf8

方式 3:編譯時指定

[root@database-one ~]# cmake . -DDEFAULT_CHARSET=utf8

2.2 數(shù)據(jù)庫字符集設(shè)置

// -- 示例: 創(chuàng)建數(shù)據(jù)庫

create database if not exists dbtest character set utf8;

// -- 示例:修改數(shù)據(jù)庫

ALTER DATABASE dbtest CHARACTER SET 'utf8';

2.3?數(shù)據(jù)表字符集設(shè)置

// -- 創(chuàng)建表時:DEFAULT CHARSET=utf8mb4 設(shè)置字符集

CREATE TABLE `t_employee` (

  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '員工ID',

  `code` varchar(10) NOT NULL COMMENT '員工編碼',

  `name` varchar(10) NOT NULL COMMENT '員工姓名',

  `age` int(10) unsigned DEFAULT NULL COMMENT '年齡',

  `sex` int(10) unsigned DEFAULT NULL COMMENT '性別',

  `cert_type` int(10) unsigned DEFAULT NULL COMMENT '證件類型',

  `cert_no` varchar(20) DEFAULT NULL COMMENT '證件號',

  `birthday` date DEFAULT NULL COMMENT '生日',

  `income_date` date DEFAULT NULL COMMENT '入職日期',

  PRIMARY KEY (`id`),

  UNIQUE KEY `code` (`code`),

  UNIQUE KEY `cert_type` (`cert_type`,`cert_no`)

) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 COMMENT='員工表';



// -- 修改表的字符集

ALTER TABLE `dbtest`.`t_employee` CHARACTER SET = utf8mb4;

2.4?字段字符集設(shè)置

// -- 創(chuàng)建表時:CHARACTER SET utf8mb4指定字段字符集

CREATE TABLE `t_employee` (

  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '員工ID',

  `code` varchar(10) NOT NULL COMMENT '員工編碼',

  `name` varchar(10) NOT NULL COMMENT '員工姓名',

  `age` int(10) unsigned DEFAULT NULL COMMENT '年齡',

  `sex` int(10) unsigned DEFAULT NULL COMMENT '性別',

  `cert_type` int(10) unsigned DEFAULT NULL COMMENT '證件類型',

  `cert_no` varchar(20) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '證件號',

  `birthday` date DEFAULT NULL COMMENT '生日',

  `income_date` date DEFAULT NULL COMMENT '入職日期',

  PRIMARY KEY (`id`),

  UNIQUE KEY `code` (`code`),

  UNIQUE KEY `cert_type` (`cert_type`,`cert_no`)

) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COMMENT='員工表';



// -- 修改字段的字符集:CHARACTER SET utf8mb4

ALTER TABLE `dbtest`.`t_employee` 

MODIFY COLUMN `cert_no` varchar(20) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '證件號' AFTER `cert_type`;

3、多級的字符集 & 多種字符集的作用

多級繼承的字符集與字符序:可以方便快捷的設(shè)置下一層級的字符集和字符序,比如一個數(shù)據(jù)庫下面有很多張表,只需要將數(shù)據(jù)庫的字符集設(shè)置為 UTF8,所有表創(chuàng)建時就指定了默認(rèn)的字符集。

MySQL 早期只支持有限數(shù)量字符集,后來不斷的擴(kuò)展,例如從早期的 latin 1 到?UTF8(閹割版本的utf8,?MySQL 較早的版本為了節(jié)省存儲空間,只三個字節(jié))完全夠用了,后面出現(xiàn)了 EMOJI?表情符號、復(fù)雜的漢字、繁體字等需要 4 個字節(jié)存儲,就不能滿足要求了,于是有 mysql 的 utf8mb4 字符集。

MySQL 支持在同一個服務(wù)器的數(shù)據(jù)庫設(shè)置不同的字符集,同一個數(shù)據(jù)庫下的不同表也可以設(shè)定不同的字符集,同一個表的不同字段也可以設(shè)定不同的字符集,都是為了方便業(yè)務(wù)的移植和擴(kuò)展。(例如以前一個業(yè)務(wù)只覆蓋了歐洲英文國家,采用 ladin 1字符集就足夠了,但是后來有擴(kuò)展到中國,于是需要將字符集擴(kuò)展到 UTF8;之前全部字段(nickname)采用UTF8字符集,但是發(fā)現(xiàn)有些用戶的昵稱?EMOJI 表情符號,導(dǎo)致注冊失敗,于是將?nickname 字段的字符集修改為 utf8mb4)。

六、MySQL 客戶端與服務(wù)端交互字符集 | 數(shù)據(jù)庫外部字符集

1、客戶端與服務(wù)端的交互

上面 4 種級別的字符集都是用于數(shù)據(jù)保存的,屬于「數(shù)據(jù)庫內(nèi)部操作字符集」。另外,客戶端和服務(wù)器之間的交互也受到其它「數(shù)據(jù)庫外部字符集」的影響。

MySQL 采用?C/S 架構(gòu),所以它有服務(wù)端和客戶端(如:MySQL自帶的客戶端、Navicat for MySQL等), 如果兩端分布在不同的的主機(jī)上,那么兩端通常需要通過 TCP/IP 獲其他協(xié)議建立連接,然后實現(xiàn)通信或數(shù)據(jù)傳輸。跟 HTTP 協(xié)議有點異曲同工,HTTP 發(fā)起請求時會在 Header 里附上客戶端“信息體”采用的字符集,MySQL 兩端也需要提前溝通好通信采用的字符集,否則服務(wù)器端不知道客戶端要的是什么,客戶端也不知道服務(wù)端給的是什么,也就是雞同鴨講,亂碼就會出現(xiàn)了。

MySQL提供了 character_set_client、character_set_connectioncharacter_set_results 三個變量來輔助客戶端與服務(wù)端的通信。

  • character_set_client:服務(wù)器會將請求(如:一條 SQL 查詢語句)的字節(jié)序列當(dāng)作采用?character_set_client?字符集進(jìn)行編碼的字節(jié)序列。
  • character_set_connection:連接數(shù)據(jù)庫時的字符集。
  • character_set_results:數(shù)據(jù)庫給客戶端返回時使用的字符集。

每次客戶端在連接服務(wù)器時,都會將客戶端默認(rèn)的字符集」與用戶名、密碼等信息一起發(fā)給服務(wù)器,服務(wù)器根據(jù)發(fā)過來的信息,統(tǒng)一把這三個系統(tǒng)變量設(shè)定好。

客戶端默認(rèn)的字符集」與客戶端所在的操作系統(tǒng)環(huán)境變量有關(guān),如果在 Unix 或 Linux 上,你設(shè)置了?LANG?或?LC_ALL?這樣的環(huán)境變量,那么 MySQL 的客戶端程序會默認(rèn)檢查應(yīng)該使用哪一個字符集。例如:如果將?LC_ALL?設(shè)置為?en_US.UTF-8?,那么?mysql?客戶端將默認(rèn)使用?UTF8 字符集?。

用 local 命令查看系統(tǒng)環(huán)境的字符集:UTF8

shitao-2:~ shitao$ locale
LANG="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_CTYPE="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_ALL=

基于筆者的操作系統(tǒng)環(huán)境,現(xiàn)在我們通過命令來查看這三個變量的賦值:

SHOW VARIABLES LIKE 'character_set\_%';

結(jié)果如下:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

可以看到這三個變量都被設(shè)置成了 UTF8?字符集?,F(xiàn)在我們來看下客戶端發(fā)起的一次請求,這三個變量是如何起作用的。

流程圖:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

(1)mysql Server 收到請求時將請求數(shù)據(jù)從 character_set_client 字符集轉(zhuǎn)換為?character_set_connection 字符集;
(2)進(jìn)行內(nèi)部操作前將請求數(shù)據(jù)從 character_set_connection 字符集轉(zhuǎn)換為內(nèi)部操作字符集,步驟如下
  ? A. 使用每個數(shù)據(jù)字段的字符集設(shè)定值;
  ? B. 若上述值不存在,則使用對應(yīng)數(shù)據(jù)表的字符集設(shè)定值;
  ? C. 若上述值不存在,則使用對應(yīng)數(shù)據(jù)庫的字符集設(shè)定值;
  ? D. 若上述值不存在,則使用 character_set_server 設(shè)定值。
(3)最后將操作結(jié)果從內(nèi)部操作字符集轉(zhuǎn)換為 character_set_results 字符集。


為什么不直接將?character_set_client?字符集轉(zhuǎn)為內(nèi)部操作字符集?,中間 character_set_connection 轉(zhuǎn)換步驟的是否是多余的呢?其作用機(jī)制可以參考:Mysql中character_set_client、connection和results

為了加深理解,我們做兩個小測試:

測試一:在數(shù)據(jù)集庫里新建表 tb_example, 表和字段的字符集都默認(rèn)是 utf8, 插入數(shù)據(jù)如下:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

?輸入一條查詢語句:?

select id from tb_example where name = "牛";

正常返回查詢結(jié)果:

+------+

| id ? |

+------+

| 1001 |

+------+

現(xiàn)在我們在客戶端執(zhí)行下列語句:

set character_set_client=gbk;

然后再次執(zhí)行上面相同的查詢語句,卻返回為空

mysql> select id from example where name = "牛";
Empty set (0.03 sec)

分析:因為服務(wù)端?character_set_client 被設(shè)置為 GBK 后,服務(wù)器會將請求的字節(jié)序列(UTF8)當(dāng)作用?GBK?編碼的字節(jié)序列。 例如:“牛”的 UTF8編碼是 E7899B,這個編碼在GBK里對應(yīng)的就是其他字符了,所以導(dǎo)致查詢的結(jié)果為空。

測試二:現(xiàn)在恢復(fù)到測試一之前的情況,輸入下面的語句

set character_set_resuluts=gbk;

執(zhí)行下面的查詢語句:

select * from example where name = "牛";

返回結(jié)果:

+------+------+

| id ? | name |

+------+------+

| 1001 | ?? ? |

+------+------+

分析:可以看到存入數(shù)據(jù)庫里的字符“?!保║TF8編碼),卻按照 character_set_resuluts 指定的字符集(GBK編碼)返回給客戶端,字符的內(nèi)容就錯亂了。

另外,這三個變量其實是有作用域的(global | session),每一次創(chuàng)建新的連接,就為這三個變量創(chuàng)建了一個會話作用域 session ,剛才針對 character_set_client 和?character_set_resulut 的設(shè)置都這是針對當(dāng)前 session 起作用的。關(guān)閉后或重新打開新的連接,這三個變量都會恢復(fù)到最初的設(shè)置。

讓我們通過命令查看全局變量,與之前查詢命令相比,添加了?global 修飾符:

SHOW global VARIABLES LIKE 'character_set\_%';

結(jié)果:

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

可以觀察到,這三個字符集全局變量(global)與 會話變量(session),并不相同,那么這全局變量有什么作用呢?可以參考 <mysql 8.0 版本>:MySQL 官網(wǎng)的解釋

數(shù)據(jù)庫字符集,數(shù)據(jù)庫,mysql,數(shù)據(jù)庫

如上圖所示:以?character_set_client 為例,服務(wù)端是根據(jù)客戶端的請求來設(shè)定該值的(如:前面所說客戶端默認(rèn)字符集 + 后面將會提到的其他三種設(shè)置方式),如果服務(wù)端沒有辦法獲取到客戶端的請求字符集,或者客戶端設(shè)置的字符集服務(wù)端不支持,那么將采用全局變量里這三個變量的值,在 mysql 8.0 版本,這三個值的默認(rèn)值為? utf8mb4,? 在筆者這里查詢到這三個全局變量字符集是?Ladin 1,也可以推斷上圖的 default_value 應(yīng)該是 Ladin 1。

2、如何設(shè)置字符集

如果你不想采用系統(tǒng)環(huán)境變量的默認(rèn)字符集,也可以采用其他方式來進(jìn)行設(shè)置:

方式 1:在 MySQL 配置文件 my.cnf | my.ini 中設(shè)置

如果客戶端程序支持?--default-character-set?選項,你可以使用該選項。你可以將下列選項加入配置文件中,這樣在每次建立和服務(wù)端的連接后,就會進(jìn)行默認(rèn)的字符集設(shè)置:

[client]
default-character-set=utf8

方式 2:在建立連接后,在客戶端輸入下列語句

SET NAMES utf8;

方式 3:部分編程語言的驅(qū)動提供了接口來實現(xiàn)類似的功能

對于 Java,你可以通過為連接數(shù)據(jù)庫的 URL 指定?characterEncoding?屬性來進(jìn)行客戶端所使用字符集的指定,例如:

jdbc:mysql://localhost:3306/mydatabase?useUnicode=true&characterEncoding=utf8

以上三種方式等效于在客戶端與服務(wù)器連接后,同時執(zhí)行以下三條命令,將三個變量統(tǒng)一設(shè)置為相同的字符集:

SET character_set_client=utf8;

SET?character_set_connection=utf8;

SET?character_set_results=utf8;

備注:這里的?character_set_client 有一定的迷惑性,其實它是客戶端與服務(wù)端建立連接時候,雙方約定的結(jié)果,也就是說,服務(wù)端會按 character_set_client 設(shè)置的字符集來接收客戶端發(fā)來的 SQL 語句,但是并不能保證客戶端一定就會按約定的字符集發(fā)送信息。

就像我們上面的「測試一」,在建立連接后,手動將 character_set_client 的字符集由 UTF8?改成了 GBK 字符集, 客戶端仍然按 UTF8 字符集發(fā)送消息,就會造成對接時字符集錯亂,導(dǎo)致查詢結(jié)果為空。

同理,在「測試二」手動修改了?character_set_results 的值也造成了接受返回數(shù)據(jù)顯示為亂碼。所以我們采取上面 3 種方式來配置字符集變量的時候,一定要確保客戶端環(huán)境實際采用的字符集與?character_set_client 和?character_set_results 完全一致。

參考:

MySQL配置文件my.ini詳解

你真的搞懂MySQL的字符集了嗎?

MySQL字符集的不同級別和效果

深入理解MySQL字符集及校對規(guī)則(一)

MySQL的字符編碼體系(一)——數(shù)據(jù)存儲編碼

MySQL-解析客戶端SQL執(zhí)行字符集參數(shù)設(shè)置

MySQL中的字符集與字符序文章來源地址http://www.zghlxwxcb.cn/news/detail-758200.html

到了這里,關(guān)于MySQL 字符集概念與原理及如何配置字符集 - 超詳細(xì)圖文詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【MySQL】——數(shù)據(jù)類型及字符集

    【MySQL】——數(shù)據(jù)類型及字符集

    ??個人專欄: ?? 算法設(shè)計與分析:算法設(shè)計與分析_IT閆的博客-CSDN博客 ??Java基礎(chǔ):Java基礎(chǔ)_IT閆的博客-CSDN博客 ??c語言:c語言_IT閆的博客-CSDN博客 ??MySQL:數(shù)據(jù)結(jié)構(gòu)_IT閆的博客-CSDN博客 ??數(shù)據(jù)結(jié)構(gòu):??????數(shù)據(jù)結(jié)構(gòu)_IT閆的博客-CSDN博客 ??C++:C++_IT閆的博客-CSDN博

    2024年02月03日
    瀏覽(25)
  • MySQL——命令行客戶端的字符集問題

    MySQL——命令行客戶端的字符集問題

    ? 原因:服務(wù)器端認(rèn)為你的客戶端的字符集是 utf-8 ,而實際上你的客戶端的字符集是 GBK 。 ? ? 查看所有字符集: SHOW VARIABLES LIKE \\\'character_set_%\\\'; ? 解決方案,設(shè)置當(dāng)前連接的客戶端字符集 “SET NAMES GBK;”

    2024年02月09日
    瀏覽(23)
  • 【MySQL】關(guān)于數(shù)據(jù)庫字符編碼以及字符集排序相關(guān)知識

    通過設(shè)置表的字符集和排序規(guī)則,解決MySQL查詢時不區(qū)分字母大小寫、插入時不支持特殊字符的問題。 關(guān)于MySQL查詢時不區(qū)分字母大小寫、插入時不支持特殊字符的問題,只有修改表的字符集和排序規(guī)則才能根治,而且事半功倍。utf8mb4支持的最低mysql版本為5.5.3+,若不是,請

    2024年02月12日
    瀏覽(37)
  • 第3章 【MySQL】字符集和比較規(guī)則

    第3章 【MySQL】字符集和比較規(guī)則

    如何存儲字符串?需要建立字符與二進(jìn)制數(shù)據(jù)的映射關(guān)系。建立這個關(guān)系需要: 1.把哪些字符映射成二進(jìn)制數(shù)據(jù)? 2.怎么映射? 將一個字符映射成一個二進(jìn)制數(shù)據(jù)的過程也叫做 編碼 ,將一個二進(jìn)制數(shù)據(jù)映射到一個字符的過程叫做 解碼 。 人們抽象出一個 字符集 的概念來描

    2024年02月09日
    瀏覽(19)
  • mysql 字符集、比較規(guī)則, 比較規(guī)則底層邏輯

    mysql 字符集、比較規(guī)則, 比較規(guī)則底層邏輯

    字符集的級別 show variables like ‘%charecter%’; character_set_server 服務(wù)器級別 一般在 5.7: C:ProgramDataMySQLMySQL Server 5.7my.ini 8.0: C:ProgramDataMySQLMySQL Server 5.7my.ini Linux 系列 vim /etc/my.cnf character_set_server=xxx # 設(shè)定默認(rèn)字符集 collation_server=xxx_chinese_ci # 對應(yīng)的默認(rèn)的比較規(guī)則 charac

    2024年02月11日
    瀏覽(26)
  • 數(shù)據(jù)庫 --- mysql(03)-- mysql字符集、表操作(01)

    數(shù)據(jù)庫 --- mysql(03)-- mysql字符集、表操作(01)

    (1)簡介: MySQL字符集 包括 字符集(CHARACTER) 和 校對規(guī)則(COLLATION) 兩個概念: 字符集(CHARACTER) 是一套編碼 校對規(guī)則(COLLATION) 是在字符集內(nèi)用于比較字符的一套規(guī)則。 (2)命令: 1 查看字符集 2 修改默認(rèn)字符集 附:utf8和utf8mb4的區(qū)別 MySQL在5.5.3之后增加了這個u

    2024年02月16日
    瀏覽(21)
  • MySQL數(shù)據(jù)庫——MySQL字符集和校對規(guī)則詳解

    MySQL數(shù)據(jù)庫——MySQL字符集和校對規(guī)則詳解

    在講解字符集和校對規(guī)則之前,我們先來簡單了解一下字符、字符集和字符編碼。 字符(Character) 是計算機(jī)中字母、數(shù)字、符號的統(tǒng)稱,一個字符可以是一個中文漢字、一個英文字母、一個阿拉伯?dāng)?shù)字、一個標(biāo)點符號等。 計算機(jī)是以二進(jìn)制的形式來存儲數(shù)據(jù)的。平時我們在

    2024年02月05日
    瀏覽(20)
  • 修改mysql默認(rèn)字符集的兩種方法

    修改mysql默認(rèn)字符集的兩種方法

    下面微點閱讀小編就為大家介紹兩種修改mysql默認(rèn)字符集的方法。需要的朋友可以過來參考下 (1) 最簡單的修改方法,就是修改mysql的my.ini文件中的字符集鍵值 , 如 default-character-set = utf8 ?? character_set_server = utf8 修改完后,重啟mysql的服務(wù),service mysql restart 使用 mysql SHOW VARI

    2024年02月06日
    瀏覽(17)
  • Mysql 創(chuàng)建數(shù)據(jù)庫字符集與排序規(guī)則

    新版本數(shù)據(jù)庫默認(rèn)編碼格式是? utf8mb4 , utf8mb4 ?比? utf8 ?多了? emoji ?編碼支持,建議普通表使用? utf8 ?如果這個表需要支持? emoji ?就使用? utf8mb4 ,也可以全部用? utf8mb4 , utf8mb4 完全向下兼容 utf8 。 字符集 當(dāng)數(shù)據(jù)庫需要適應(yīng)不同的語言就需要有不同的字符集,如果不指

    2024年02月07日
    瀏覽(21)
  • mysql進(jìn)階-修改linux服務(wù)器中MySQL的字符集

    mysql進(jìn)階-修改linux服務(wù)器中MySQL的字符集

    linux 中 mysql8 默認(rèn)的字符集是 latin1 ,在插入中文時會報錯,所以一般在配置好mysql時需要修改字符集為 utf8 【又叫utfmb3,一般開發(fā)夠用,一個字符用3個字節(jié)表示】或者 utfmb4 【一個字符用4個字節(jié)表示,如果存儲emoji表情,必須用utfmb4】 1366 - Incorrect string value: xE4 xBA xBA(xE7 x94 x

    2024年02月14日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包