你真的搞懂MySQL的字符集了嗎?
搞懂到底什么是字符集,它和字符、編碼有什么關(guān)系?
MySQL的數(shù)據(jù)庫字符集、表字符集、字段字符集有什么關(guān)系?
MySQL的字符集轉(zhuǎn)換會有什么問題?
MySQL怎樣設(shè)置數(shù)據(jù)庫服務(wù)端和客戶端字符集?
MySQL怎樣設(shè)置數(shù)據(jù)庫字符集、表字符集、字段字符集?
一、基礎(chǔ)術(shù)語
字符:漢字,英文字母,標點符號,拉丁文等等。
編碼:將字符轉(zhuǎn)換成計算機存儲的格式,比如,A用65表示。
字符集 Character Set:等于字符+編碼,包含一組字符以及對應(yīng)的編碼方式。
二、字符集原理
不同的字符集,規(guī)定了不同的字符的編碼方式,是一組符號和編碼。
例如我們熟知的ASCII字符集,包括的字符有數(shù)字、大小寫字母、分號、換行之類的符號,編碼方式是用一個7bit表示一個字符,例如A的編碼是65,b的編碼是98。
ASCII(American Standard Code for Information Interchange,美國標準信息交換代碼)是基于拉丁字母的一套電腦編碼系統(tǒng),主要用于顯示現(xiàn)代英語和其他西歐語言,主要編碼表如下圖所示。

ASCII只規(guī)定了英文字母的編碼,非英文語言不能用ASCII編碼表示,為此,不同的國家,都為自己的語言做了編碼,比如,我們國家,就有GB2312編碼。
但每個國家之間的編碼不同,也存在著一些跨平臺的問題,為此,一些國際化標準組織,就制定了一些國際通用的編碼,最常用的就是UTF8了。ASCII只對英文符號和英文字母做了編碼,GB2312對英文符號,英文字母,漢字做了編碼,UTF8對世界上所有的語言文字做了編碼,所以,GB1212的字符包含了ASCII字符,UTF8包含了GB2312字符。
三、MySQL字符集
MySQL目前支持多字符集,并且,支持在不同的字符集之間轉(zhuǎn)換(便于移植和支持多語言)。
MySQL可以設(shè)置服務(wù)器級字符集、數(shù)據(jù)庫級字符集(圖A-1)、數(shù)據(jù)表級字符集(圖A-2)、表列級別字符集(圖A-3),實際上,最終使用字符集的地方是存儲字符的列。
其中服務(wù)器級字符集、數(shù)據(jù)庫級字符集、數(shù)據(jù)表級字符集都是為列的字符集做默認選項的。

圖A-1 數(shù)據(jù)庫級字符集

圖A-2 數(shù)據(jù)表級字符集

圖 A-3 數(shù)據(jù)表列級編碼
四、字符集的轉(zhuǎn)換問題
如果小字集轉(zhuǎn)換成大字符集,不會丟失數(shù)據(jù),但大字集,轉(zhuǎn)換成小字集,可能會丟失數(shù)據(jù)。
比如,UTF8里有的字符,GB2312不一定有,所以,從UTF8轉(zhuǎn)換到GB2312可能會丟失一些字符。
五、字符集設(shè)置
可以通過Navicat工具可視化的設(shè)置數(shù)據(jù)庫、表、字段的字符集,不再介紹,可參考上方的圖A1~A3,下面重點介紹通過文件配置和SQL語句進行字符集設(shè)置。
5.1數(shù)據(jù)庫服務(wù)端和客戶端字符集
1、先停止mysql服務(wù),然后修改mysql安裝目錄下的my.ini或my.cnf文件。
2、在[mysqld]標簽(沒有則新建)下增加:character-set-server=utf8
3、在[client]標簽(沒有則新建)下增加:default-character-set=utf8
4、啟動mysql服務(wù)即可
5、可通過show VARIABLES like '%char%';查看編碼設(shè)置,如圖A-4所示。

圖A-4 數(shù)據(jù)庫字符集設(shè)置
6、這里可以看到字符集有很多設(shè)置參數(shù),除了character_set_filesystem=binary以外,其他的都可以一致設(shè)置為utf8或utf8mb4。如果發(fā)現(xiàn)編碼不一致,就可以通過my.ini或my.cnf文件進行設(shè)置。
5.2數(shù)據(jù)庫字符集設(shè)置
數(shù)據(jù)庫可以在創(chuàng)建時指定字符集、或者修改字符集
-- 語法CREATE DATABASE [IF NOT EXISTS] <數(shù)據(jù)庫名>[[DEFAULT] CHARACTER SET <字符集名>][[DEFAULT] COLLATE <校對規(guī)則名>];-- 示例: 創(chuàng)建數(shù)據(jù)庫create database if not exists dbtest character set utf8;-- 示例:修改數(shù)據(jù)庫ALTER DATABASE dbtest CHARACTER SET 'utf8';
5.3數(shù)據(jù)表字符集設(shè)置
可以在創(chuàng)建表時指定默認字符集,也可以創(chuàng)建后修改表的字符集
-- 創(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;
5.4字段字符集設(shè)置
可以在創(chuàng)建表時直接指定字段的字符集,也可以在創(chuàng)建表之后修改字段的字符集。
-- 創(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 utf8mb4ALTER TABLE `dbtest`.`t_employee`MODIFY COLUMN `cert_no` varchar(20) CHARACTER SET utf8mb4 NULL DEFAULT NULL COMMENT '證件號' AFTER `cert_type`;
點“在看”變好看噢

