文章目录
1.字符集
从本质上来说,计算机只能识别二进制代码,所以不管是计算程序还是处理的数据,最终都会转换成二进制代码,计算机才能够认识。为了计算机不只能够用于计算,也能够处理文字信息,人们想出了给每个文字符号编码以便于计算机识别处理的方法,这便是字符集的由来。简单来说字符集就是一套文字符号及其编码、比较规则的集和。
常见的编码
- GB2312-80:全称《信息交换用汉字编码字符集 基本集》,于 1980 年发布。根据 ISO/IEC 2022 提供的字符编码扩充规范,形成双字节编码的字符集。收录了 6763 个常用汉字和 682个非汉字图形符号。
- GBK:全称《汉字内码扩展规范》1.0 版,发布于 1995 年。GBK 在 GB2312 内码系统的基础上进行了扩充,收录了 GB13000.1-1993 的全部 20902 个 CJK 统一汉字,包括 GB2312 的全部 6763 个汉字。此外,它增补编码了 52 个汉字,13 个汉字结构符(在 ISO/IEC 10646.1: 2000
中称为表意文字描述符)和一些常用部首与汉字部件。在 GBK 的内码系统中,GB2312 汉字所在码位保持不便,这样,保证了 GBK 对 GB2312 的完全兼容。同时,GBK 内码与 GB13000.1代码一一对应,为 GBK 向 GB13000.1 的转换提供了解决办法。有意思的是 GBK 并不是一个
强制性的国家标准,只是一个行业指导规范,并没有强制力,但由于得到了 Microsoft Windows 95 的支持而大为流行。 - BIG5:
ASCII字符集
ASCII编码在1960年代初期由美国标准化组织ANSI发布,后来进一步变成了国际标准ISO-646。
采用7位编码,定义了包括英文大小写字母、阿拉伯数字和标点符号,以及33个控制符号等。
Unicode编码
为了统一字符编码,国际标准化组织ISO的成员国于1984年发起制定新的国际字符标准,来容纳全世界各地的各种语言文字和符号,这个标准最终称为USC,标准编号则定位ISO-10646。USC采用4字节32位编码,因此简称USC-4。具体的编码规则为将代码空间划分为组(group)、面(plane)、行(row)和格(ceil);第一个字节代表组(group),第二个字节代表面(plane),第三个字节代表行(row),第四个字节代表格(ceil),并规定字符编码的第32位必须为0,且每个面的最后两个码位FFFEH和FFFFH保留不用,因此共有128个群组(0~0x7F),每个群组有256个面(00~0xFF),每个字面有256行(00~0xFF),每行包括256格(0~0xFF),共有258-128个字面,每个字面有256*256-2个码位,合计65534*32768个码位。
2.选择合适的字符集
MySQL支持多种字符集,同一台服务器、同一各数据库、同一各数据库、甚至同一张表的不同字段都可以指定不同的字符集
查看所有的字符集
show character set;
--+----------+---------------------------------+---------------------+--------+
--| Charset | Description | Default collation | Maxlen |
--+----------+---------------------------------+---------------------+--------+
--| big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 |
--| dec8 | DEC West European | dec8_swedish_ci | 1 |
--| cp850 | DOS West European | cp850_general_ci | 1 |
--| hp8 | HP West European | hp8_english_ci | 1 |
--| koi8r | KOI8-R Relcom Russian | koi8r_general_ci | 1 |
--| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
--| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
--| swe7 | 7bit Swedish | swe7_swedish_ci | 1 |
--| ascii | US ASCII | ascii_general_ci | 1 |
--| ujis | EUC-JP Japanese | ujis_japanese_ci | 3 |
--| sjis | Shift-JIS Japanese | sjis_japanese_ci | 2 |
--| hebrew | ISO 8859-8 Hebrew | hebrew_general_ci | 1 |
--| tis620 | TIS620 Thai | tis620_thai_ci | 1 |
--| euckr | EUC-KR Korean | euckr_korean_ci | 2 |
--| koi8u | KOI8-U Ukrainian | koi8u_general_ci | 1 |
--| gb2312 | GB2312 Simplified Chinese | gb2312_chinese_ci | 2 |
--| greek | ISO 8859-7 Greek | greek_general_ci | 1 |
--| cp1250 | Windows Central European | cp1250_general_ci | 1 |
--| gbk | GBK Simplified Chinese | gbk_chinese_ci | 2 |
--| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
--| armscii8 | ARMSCII-8 Armenian | armscii8_general_ci | 1 |
--| utf8 | UTF-8 Unicode | utf8_general_ci | 3 |
--| ucs2 | UCS-2 Unicode | ucs2_general_ci | 2 |
--| cp866 | DOS Russian | cp866_general_ci | 1 |
--| keybcs2 | DOS Kamenicky Czech-Slovak | keybcs2_general_ci | 1 |
--| macce | Mac Central European | macce_general_ci | 1 |
--| macroman | Mac West European | macroman_general_ci | 1 |
--| cp852 | DOS Central European | cp852_general_ci | 1 |
--| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
--| utf8mb4 | UTF-8 Unicode | utf8mb4_general_ci | 4 |
--| cp1251 | Windows Cyrillic | cp1251_general_ci | 1 |
--| utf16 | UTF-16 Unicode | utf16_general_ci | 4 |
--| utf16le | UTF-16LE Unicode | utf16le_general_ci | 4 |
--| cp1256 | Windows Arabic | cp1256_general_ci | 1 |
--| cp1257 | Windows Baltic | cp1257_general_ci | 1 |
--| utf32 | UTF-32 Unicode | utf32_general_ci | 4 |
--| binary | Binary pseudo charset | binary | 1 |
--| geostd8 | GEOSTD8 Georgian | geostd8_general_ci | 1 |
--| cp932 | SJIS for Windows Japanese | cp932_japanese_ci | 2 |
--| eucjpms | UJIS for Windows Japanese | eucjpms_japanese_ci | 3 |
--| gb18030 | China National Standard GB18030 | gb18030_chinese_ci | 4 |
--+----------+---------------------------------+---------------------+--------+
--41 rows in set (0.00 sec)
查看支持的字符集和默认的校对规则
desc information_schema.character_sets;
--+----------------------+-------------+------+-----+---------+-------+
--| Field | Type | Null | Key | Default | Extra |
--+----------------------+-------------+------+-----+---------+-------+
--| CHARACTER_SET_NAME | varchar(32) | NO | | | |
--| DEFAULT_COLLATE_NAME | varchar(32) | NO | | | |
--| DESCRIPTION | varchar(60) | NO | | | |
--| MAXLEN | bigint(3) | NO | | 0 | |
--+----------------------+-------------+------+-----+---------+-------+
--4 rows in set (0.01 sec)
MySQL的字符集包括字符集(character)和校对规则(collation)两个概念。字符集是用来定义MySQL存储字符串的方式,校对规则则是定义了字符串的比较方式。字符串和校对规则是一对多的关系,MySQL支持30多种字符集和70多种校对规则。
每个字符集至少对应一个校对规则,可以用show collation like ‘****’命令来查看相关字符集的校对规则。
show collation like 'gbk%';
--+----------------+---------+----+---------+----------+---------+
--| Collation | Charset | Id | Default | Compiled | Sortlen |
--+----------------+---------+----+---------+----------+---------+
--| gbk_chinese_ci | gbk | 28 | Yes | Yes | 1 |
--| gbk_bin | gbk | 87 | | Yes | 1 |
--+----------------+---------+----+---------+----------+---------+
--2 rows in set (0.00 sec)
校对规则命名约定
以其相关的字符集命名开始,通常包括一个语言名,并且以_ci(大小写不敏感),_cs(大小写敏感)或_bin(二元,即比较基于字符编码的值而与language无关)结束。
MySQL字符集设置
MySQL的字符集和校对规则有4个级别的默认设置:服务器级别、数据库级别、表级别和字段级别。他们分别在不同的位置设置,作用也不同。
1.服务器字符集和校对规则
服务器字符集和校对,在MySQL服务启动的时候确定。
#1.在MySQL启动的时候设置:
[mysqld]
default-character-set=gbk
#2.在启动选项中指定
mysqld --default-character-set=gbk
#3.在编译的时候指定
。/configure --with-charset=gbk
如果没有特别的指定服务器字符集,默认使用latin1作为服务器字符集。如果只指定了字符集,没有指定校对规则,那么使用该字符集默认的校对规则,要过要使用该字符集非默认的校对规则,则需要在指定字符集的同时指定校对规则 。
可以使用 show variables like ‘character_set_server’;
命令查询当前服务器的字符集和校对规则。
show variables like 'character_set_server';
--+----------------------+-------+
--| Variable_name | Value |
--+----------------------+-------+
--| character_set_server | utf8 |
--+----------------------+-------+
--1 row in set, 1 warning (0.00 sec)
show variables like 'collation_server';
--+------------------+-----------------+
--| Variable_name | Value |
--+------------------+-----------------+
--| collation_server | utf8_general_ci |
--+------------------+-----------------+
--1 row in set, 1 warning (0.00 sec)
2.数据库字符集和校对规则
数据库的字符集和校对规则在创建数据库的时候指定,也可以在创建完数据库口通过 alter database
命令进行修改。如果数据库中已经存在数据,修改字符集并不能将已有数据按照新的字符集进行存放,所以不能通过修改字符集直接修改数据的内容。
设置数据库字符集的规则是:
- 如果指定了字符集和校对规则,则使用指定的字符集和校对规则;
- 如果指定了字符集没有指定校对规则,则使用指定字符集默认的校对规则。
- 如果没有指定字符集和校对规则,则使用服务器的字符集和校对规则作为数据库的字符集和校对规则。
推荐在创建数据库的时候指定字符集和默认校对规则,避免受到默认值的影响。
要查看当前数据的字符集可以使用 show variables like ’character_set_database‘
,查看当前数据库的校对规则使用 show variables like 'collation_database'
show variables like 'character_set_database';
--+------------------------+-------+
--| Variable_name | Value |
--+------------------------+-------+
--| character_set_database | utf8 |
--+------------------------+-------+
--1 row in set, 1 warning (0.00 sec)
show variables like 'collation_database';
--+--------------------+-----------------+
--| Variable_name | Value |
--+--------------------+-----------------+
--| collation_database | utf8_general_ci |
--+--------------------+-----------------+
--1 row in set, 1 warning (0.00 sec)
3.表字符集和校对规则
表的字符集和校对规则在创建表的时候指定,可以通过 alter table
命令进行修改,同样,如果表中已有记录,修改字符集对原有的数据不做影响,不会将原有数据按照新的字符集进行存放,表的字段任然使用原来的字符集。
设置表的字符集的规则和设置数据库的字符集规则基本类似:
- 如果指定了表的字符集和校对规则,则使用指定的字符集和校对规则。
- 如果只指定字符集而没有指定校对规则,则使用该字符集默认的校对规则。
- 如果既没有指定字符集也没有指定校对规则,则使用数据库的字符集和校对规则作为表的字符集和校对规则。
推荐在创建表的时候指定字符集和校对规则,彼岸受到默认值的影响。
要想显示的查看表指定的字符集和校对规则,可以使用 show create table
命令查看
show create table blog \G;
--*************************** 1. row ***************************
-- Table: blog
--Create Table: CREATE TABLE `blog` (
-- `id` int(11) DEFAULT NULL,
-- `context` text,
-- KEY `idx_blog` (`context`(100))
--) ENGINE=InnoDB DEFAULT CHARSET=utf8
--1 row in set (0.05 sec)
--ERROR:
--No query specified
4. 列字符集和校对规则
MySQL可以设置列级别的字符集和校对规则,主要是针对相同表的不同字段要使用不同的字符集的情况,一般遇到这种情况的机率比较小,MySQL只是为我们提供了一种灵活设置的手段。
列的字符集和校对规则可以在创建时指定,或者在修改表时调整,如果在创建表时没有指定列的字符集和校对规则,则默认使用表的字符集和较对规则。
5.连接字符集和校对规则
以上的四种方式只是指定了数据咋保存时候的字符集和校对规则,对于实际的应用访问来说,还存在客户端和服务器之间交互的字符集和校对规则的设置。
对于客户端和服务器之间的交互操作,MySQL提供了3个不同的参数:character-set-client、character-set-collection、character-set-results,依次代表客户端、连接和返回结果的字符集,通常情况下,这三个字符集应该是相同的,才可以确保用户输入的数据可以正确的读出,特别是对于中文字符,这三种字符集的不同会导致数据不能够正确的读出。
- 通常情况下这三个参数不会分别来设置,可以通过
SET NAMES ***
来设置这三个参数的值。通过这个方法设置的字符需要在每次重新连接时重新设置字符集和校对规则。 - 另外一种方法时在my.cnf(windows系统为my.ini)文件中修改以下语句
[mysql]
default-character-set=utf8
这样设置后,服务器启动后,默认都是通过utf8字符集来建立连接。
字符集的修改步骤
如果在应用开始阶段没有正确的设置字符集,在运行一段时间后才发现存在不满足要求需要调整,而又不想丢弃这些数据,那么就需要进行字符集的修改,字符集不能直接通过’alter database character set ***'
或 alter table tablename character set ***
来修改,这两个命令对不会修改已存在的表或记录的字符集。已有记录的字符集调整需要先将数据导出,经过适当的修改重新导入后才能生效。
以下例子是将latin1的字符集数据库修改为utf8字符集数据库的过程
- 导出表结构
mysqldump -uroot -p --default-character-set=utf8 -d test2 > createtab.sql
--其中--default-character-set表示以什么字符集连接,-d表示只导出表结构
- 手动修改create.table中的字符集为新的字符集
CREATE TABLE `user` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=UTF8;
- 确保记录不在更新,导出所有记录
mysqldump -uroot -p --quick --no-create-info --extended-insert --default-character-set=latin1 test2 > data.sql
# --quick 用于转储大的表,他强制mysqldump从服务器一次一行检索表中的行而不是检索所有行,并在输出前将他们缓存到内存中.
# --extended-insert :使用包括几个VALUES列表的多行insert语法,这样使转储的文件更小,重载文件时可以加速插入.
# --no-create-info :不写重新创建每个转储表的create table语句.
# --default-character-set : 按原有的字符集导出所有数据,这样导出的文件中文都是可见的,不会保存成乱码.
- 打开data.sql,将set names latin1改为set names utf8
/*!40101 SET NAMES UTF8 */;
- 使用新的字符集创建新的数据库
create database test3 default charset utf8;
- 导入建表sql
source createtab.sql
- 导入数据
source data.sql
- 查看数据
select * from user;
--+----+-----------+----------+
--| id | username | password |
--+----+-----------+----------+
--| 1 | 张三 | sdccdcdc |
--| 2 | 而不敢 | sdccdcdc |
--| 3 | 而不敢 | sdccdcdc |
--| 4 | 李四 | scdscdsc |
--| 5 | 的事实 | csdscds |
--+----+-----------+----------+
--5 rows in set (0.00 sec)