字符集和排序规则
排序规则名称以与其关联的字符集的名称开头,通常后跟一个或多个表示其他排序规则特征的后缀。 例如,utf8 general ci 和 latin1瑞典 ci 分别是 utf8和 latin1字符集的排序规则。 二进制字符集有一个排序规则,也称为二进制,没有后缀。
特定于语言的排序规则包括语言名称。 例如,utf8土耳其 ci 和 utf8匈牙利 ci sort 字符用于 utf8字符集,分别使用土耳其和匈牙利的规则
排序规则后缀表示排序规则是区分大小写、区分重音、区分假名(或者它们的某种组合)还是二进制。 下表显示了用于表示这些特征的后缀
Suffix 后缀 Meaning 意义
_ai Accent-insensitive 口音不敏感
_as Accent-sensitive 口音敏感
_ci Case-insensitive 不区分大小写
_cs Case-sensitive 区分大小写
_bin Binary 二进制
对于不指定重音敏感性的非二进制排序规则名称,它由大小写敏感性确定。 如果排序名称不包含 ai 或 as,则名称中的 ci 意味着 ai,名称中的 cs 意味着 ai。 例如,latin1 general ci 显式地区分大小写和隐式地区分重音,latin1 general cs 显式地区分大小写和隐式地区分重音。
服务器字符集
Mysql 服务器有一个服务器字符集和一个服务器排序规则。 可以在服务器启动时在命令行上设置或在选项文件中设置,并在运行时进行更改。最初,服务器字符集和排序规则取决于启动 mysqld 时使用的选项。 可以对字符集使用 – character-set-server。 除此之外,还可以添加 – collation-server 进行排序。 如果没有指定字符集,就等于说 – character-set-server latin1。 如果您只指定一个字符集(例如,latin1) ,而没有指定排序规则,那么这就等于说 – character-set-server latin1 – collination-server latin1,因为 latin1是 latin1的默认排序规则。 因此,以下三个命令都具有相同的效果
mysqld
mysqld --character-set-server=latin1
mysqld --character-set-server=latin1 --collation-server=latin1_swedish_ci
数据库字符集和排序规则
每个数据库都有一个数据库字符集和数据库排序规则。 Create DATABASE 和 ALTER DATABASE 语句具有用于指定数据库字符集和排序规则的可选子句:
CREATE DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
ALTER DATABASE db_name
[[DEFAULT] CHARACTER SET charset_name]
[[DEFAULT] COLLATE collation_name]
可以使用关键字 SCHEMA 代替 DATABASE.Character SET 和 COLLATE 子句使得在同一个 MySQL 服务器上创建具有不同字符集和排序规则的数据库成为可能.
Mysql 以下列方式选择数据库字符集和数据库排序规则:
- 如果同时指定了 CHARACTER SET 字符集名称和 COLLATE 排序规则名称,则使用字符集字符集名称和排序规则名称。
- 如果在没有 COLLATE 的情况下指定 CHARACTER SET 字符集名称,则使用字符集字符集名称及其默认排序规则。 若要查看每个字符集的默认排序规则,请使用 SHOW CHARACTER SET 语句或查询 informationschemacharacter sets 表
- 如果指定的 COLLATE 排序规则名称没有使用 CHARACTER SET,则使用与排序规则名称和排序规则名称关联的字符集
- 否则(既未指定 CHARACTER SET 也未指定 COLLATE) ,将使用服务器字符集和服务器排序规则
可以根据字符集数据库和排序规则数据库系统变量的值确定默认数据库的字符集和排序规则。 每当缺省数据库发生更改时,服务器都会设置这些变量。 如果没有缺省数据库,则变量的值与相应的服务器级系统变量、字符集服务器和排序规则服务器的值相同
要查看给定数据库的默认字符集和排序规则:
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'db_name';
数据库字符集和排序影响服务器操作的这些方面:
- 对于 CREATE TABLE 语句,如果未指定表字符集和排序规则,则数据库字符集和排序规则将用作表定义的默认值。 若要重写此选项,请提供显式的 CHARACTER SET 和 COLLATE 表选项
- 对于不包含 CHARACTER SET 子句的 loaddata 语句,服务器使用字符集数据库系统变量指示的字符集来解释文件中的信息。 若要覆盖此操作,请提供一个显式的 CHARACTER SET 子句。
- 对于存储例程(过程和函数) ,数据库字符集和在例程创建时生效的排序规则被用作字符集和字符数据参数的排序规则,声明不包括 CHARACTER SET 或 COLLATE 属性。 若要重写此命令,请显式提供 CHARACTER SET 和 COLLATE
表的字符集和排序规则
每个表都有一个表字符集和一个表排序规则。 Create TABLE 和 ALTER TABLE 语句具有用于指定表字符集和排序规则的可选子句:
CREATE TABLE tbl_name (column_list)
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]]
ALTER TABLE tbl_name
[[DEFAULT] CHARACTER SET charset_name]
[COLLATE collation_name]
列字符集和排序规则:
每个“字符”列(即 CHAR、 VARCHAR、 TEXT 类型或任何同义词的列)都有一个列字符集和一个列排序规则。 Create TABLE 和 ALTER TABLE 的列定义语法有用于指定列字符集和排序规则的可选子句:
col_name {CHAR | VARCHAR | TEXT} (col_length)
[CHARACTER SET charset_name]
[COLLATE collation_name]
CREATE TABLE t1
(
col1 VARCHAR(5)
CHARACTER SET latin1
COLLATE latin1_german1_ci
);
ALTER TABLE t1 MODIFY
col1 VARCHAR(5)
CHARACTER SET latin1
COLLATE latin1_swedish_ci;
Mysql 以下列方式选择列字符集和排序规则:
- 如果同时指定了 CHARACTER SET 字符集名称和 COLLATE 排序规则名称,则使用字符集字符集名称和排序规则名称。
CREATE TABLE t1
(
col1 CHAR(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci
) CHARACTER SET latin1 COLLATE latin1_bin;
为该列指定了字符集和排序规则,因此将使用它们。 该列具有字符集 utf8和排序规则 utf8 unicode ci。 - 如果在没有 COLLATE 的情况下指定 CHARACTER SET 字符集名称,则使用字符集字符集名称及其默认排序规则。
CREATE TABLE t1
(
col1 CHAR(10) CHARACTER SET utf8
) CHARACTER SET latin1 COLLATE latin1_bin;
为该列指定了字符集,但没有指定排序规则。 该列具有字符集 utf8和默认的 utf8排序规则,即 utf8 general ci。 若要查看每个字符集的默认排序规则,请使用 SHOW CHARACTER SET 语句或查询 informationschemacharacter sets 表。 - 如果指定的 COLLATE 排序规则名称没有使用 CHARACTER SET,则使用与排序规则名称和排序规则名称关联的字符集。
CREATE TABLE t1
(
col1 CHAR(10) COLLATE utf8_polish_ci
) CHARACTER SET latin1 COLLATE latin1_bin;
为列指定了排序规则,但没有为字符集指定。 该列具有 collation utf8 polish ci,并且字符集是与 collation 关联的字符集 utf8。 - 否则(未指定 CHARACTER SET 或 COLLATE) ,将使用表字符集和排序规则。
CREATE TABLE t1
(
col1 CHAR(10)
) CHARACTER SET latin1 COLLATE latin1_bin;
没有为列指定字符集或排序规则,因此使用表默认值。 该列具有字符集 latin1和排序规则 latin1 bin。
与字符集有关的系统变量
服务器或当前数据库的属性
character_set_system
character_set_server 和collaction_server
character_set_database 和collaction_database
客户端与服务器之间通信
character_set_client
character_set_results
charcter_set_conneaction
charater_set_filesystem
Unicode支持
mysql 6.0之前 仅支持BMP(初级多语言方案)里面的字符是通过两种字符集方案进行解决的。
ucs2:对应着unicode ucs-2编码方案,使用两个字节表示一个字符,高位字节排列在前。这种字符集无法收录两个以上字节才能表示的字符。UCS是通用字符集的缩写
utf8:使用1-3个字节表示一个字符
mysql 6.0之后 支持BMP(初级多语言方案)里面的字符补充字符集收录了。
ucs2:对应着unicode ucs-2编码方案,使用两个字节表示一个字符,高位字节排列在前。这种字符集无法收录两个以上字节才能表示的字符。UCS是通用字符集的缩写新增utf6和utf32字符集类似于utf8,扩充了对补充字符集的支持,在utf16字符集里,Bmp字符任然暂用2个字节,补充字符暂用4个字节。在utf32所有字节暂用4个字节。
utf8:使用1-4个字节表示一个字符,以前的utf8可以用utf8mb3字符集显示。
mysql创建的数据表格式文件扩展名是.frm 每个数据表中只有一个相应的.frm文件。
关于字符集的一个问题:
对于有些字体写入数据库乱码的问题:
show variables like’character%’;
SHOW VARIABLES WHERE Variable_name LIKE ‘character%’ OR Variable_name LIKE ‘collation%’;
MySql 中文写入数据库乱码及Incorrect string value: ‘\xF0\x9F…’ for column ‘XXX’ at row 1
原因是MySQL里utf8 编码最多只能支持3个字节,而Emoji表情字符使用的 utf8 编码,很多都是4个字节,有些甚至是6个字节。
因为mysql的utf8 有缺陷是 残疾的 不兼容部分表情,他的utf8mb4才是正经的utf8
在mysql文档中查看:
utf8 3字节,utf8mb4 4字节
Utfmb4字符集具有以下特征:
Supports BMP and supplementary characters.支持 BMP 和补充字符。
Requires a maximum of four bytes per multibyte character.每个多字节字符最多需要四个字节。
utf8mb4 contrasts with the utf8mb3 character set, which supports only BMP characters and uses a maximum of three bytes per character:
Utf8mb4与 utf8mb3字符集对比,后者只支持 BMP 字符,每个字符最多使用三个字节:
对于补充字符,utf8mb4需要4个字节来存储它,而 utf8mb3根本不能存储字符。 当将 utf8mb3列转换为 utf8mb4时,您不必担心转换补充字符,因为将没有补充字符。
解决的方案有两种:
- 使用 utf8mb4 的 mysql 编码来容纳这些字符;
- 过滤掉这些特殊的表情字符