MySQL中的字符集和校验规则
MySQL Server支持多种字符集,包括几种Unicode字符集。要显示可用的字符集,请使用INFORMATION_SCHEMA
CHARACTER_SETS
表或SHOW CHARACTER SET
语句。以下是部分清单。有关更多完整信息,
mysql>SHOW CHARACTER SET ; +---------- +--------------------------------- +--------------------- +-------- + | Charset | Description | Default collation | Maxlen | +---------- +--------------------------------- +--------------------- +-------- + | big5 | Big5 Traditional Chinese | big5_chinese_ci | 2 | | binary | Binary pseudo charset | binary | 1 | ... | latin1 | cp1252 West European | latin1_swedish_ci | 1 | ... | ucs2 | UCS -2 Unicode | ucs2_general_ci | 2 | ... | utf8 | UTF -8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF -8 Unicode | utf8mb4_0900_ai_ci | 4 | ...
默认情况下,该SHOW CHARACTER SET
语句显示所有可用的字符集。它带有一个可选的LIKE
或WHERE
子句,用于指示要匹配的字符集名称。下面的示例显示了一些Unicode字符集(基于Unicode转换格式的字符集):
mysql>SHOW CHARACTER SET LIKE 'utf%'; +--------- +------------------ +-------------------- +-------- + | Charset | Description | Default collation | Maxlen | +--------- +------------------ +-------------------- +-------- + | utf16 | UTF -16 Unicode | utf16_general_ci | 4 | | utf16le | UTF -16LE Unicode | utf16le_general_ci | 4 | | utf32 | UTF -32 Unicode | utf32_general_ci | 4 | | utf8 | UTF -8 Unicode | utf8_general_ci | 3 | | utf8mb4 | UTF -8 Unicode | utf8mb4_0900_ai_ci | 4 | +--------- +------------------ +-------------------- +-------- +
给定的字符集始终至少具有一个校验规则,大多数字符集具有多个校验规则。要列出字符集的显示归类,请使用INFORMATION_SCHEMA
COLLATIONS
表或SHOW COLLATION
语句。
默认情况下,该SHOW COLLATION
语句显示所有可用的校验规则。它带有一个可选的LIKE
或WHERE
子句,用于指示要显示的校验规则名称。例如,要参见默认字符集的校验规则utf8mb4
,请使用以下语句:
mysql>SHOW COLLATION WHERE Charset = 'utf8mb4'; +---------------------------- +--------- +----- +--------- +---------- +--------- +--------------- + | Collation | Charset | Id | Default | Compiled | Sortlen | Pad_attribute | +---------------------------- +--------- +----- +--------- +---------- +--------- +--------------- + | utf8mb4_0900_ai_ci | utf8mb4 | 255 | Yes | Yes | 0 | NO PAD | | utf8mb4_0900_as_ci | utf8mb4 | 305 | | Yes | 0 | NO PAD | | utf8mb4_0900_as_cs | utf8mb4 | 278 | | Yes | 0 | NO PAD | | utf8mb4_0900_bin | utf8mb4 | 309 | | Yes | 1 | NO PAD | | utf8mb4_bin | utf8mb4 | 46 | | Yes | 1 | PAD SPACE | | utf8mb4_croatian_ci | utf8mb4 | 245 | | Yes | 8 | PAD SPACE | | utf8mb4_cs_0900_ai_ci | utf8mb4 | 266 | | Yes | 0 | NO PAD | | utf8mb4_cs_0900_as_cs | utf8mb4 | 289 | | Yes | 0 | NO PAD | | utf8mb4_czech_ci | utf8mb4 | 234 | | Yes | 8 | PAD SPACE | | utf8mb4_danish_ci | utf8mb4 | 235 | | Yes | 8 | PAD SPACE | | utf8mb4_da_0900_ai_ci | utf8mb4 | 267 | | Yes | 0 | NO PAD | | utf8mb4_da_0900_as_cs | utf8mb4 | 290 | | Yes | 0 | NO PAD | | utf8mb4_de_pb_0900_ai_ci | utf8mb4 | 256 | | Yes | 0 | NO PAD | | utf8mb4_de_pb_0900_as_cs | utf8mb4 | 279 | | Yes | 0 | NO PAD | | utf8mb4_eo_0900_ai_ci | utf8mb4 | 273 | | Yes | 0 | NO PAD | | utf8mb4_eo_0900_as_cs | utf8mb4 | 296 | | Yes | 0 | NO PAD | | utf8mb4_esperanto_ci | utf8mb4 | 241 | | Yes | 8 | PAD SPACE | | utf8mb4_estonian_ci | utf8mb4 | 230 | | Yes | 8 | PAD SPACE | | utf8mb4_es_0900_ai_ci | utf8mb4 | 263 | | Yes | 0 | NO PAD | | utf8mb4_es_0900_as_cs | utf8mb4 | 286 | | Yes | 0 | NO PAD | | utf8mb4_es_trad_0900_ai_ci | utf8mb4 | 270 | | Yes | 0 | NO PAD | | utf8mb4_es_trad_0900_as_cs | utf8mb4 | 293 | | Yes | 0 | NO PAD | | utf8mb4_et_0900_ai_ci | utf8mb4 | 262 | | Yes | 0 | NO PAD | | utf8mb4_et_0900_as_cs | utf8mb4 | 285 | | Yes | 0 | NO PAD | | utf8mb4_general_ci | utf8mb4 | 45 | | Yes | 1 | PAD SPACE | | utf8mb4_german2_ci | utf8mb4 | 244 | | Yes | 8 | PAD SPACE | | utf8mb4_hr_0900_ai_ci | utf8mb4 | 275 | | Yes | 0 | NO PAD | | utf8mb4_hr_0900_as_cs | utf8mb4 | 298 | | Yes | 0 | NO PAD | | utf8mb4_hungarian_ci | utf8mb4 | 242 | | Yes | 8 | PAD SPACE | | utf8mb4_hu_0900_ai_ci | utf8mb4 | 274 | | Yes | 0 | NO PAD | | utf8mb4_hu_0900_as_cs | utf8mb4 | 297 | | Yes | 0 | NO PAD | | utf8mb4_icelandic_ci | utf8mb4 | 225 | | Yes | 8 | PAD SPACE | | utf8mb4_is_0900_ai_ci | utf8mb4 | 257 | | Yes | 0 | NO PAD | | utf8mb4_is_0900_as_cs | utf8mb4 | 280 | | Yes | 0 | NO PAD | | utf8mb4_ja_0900_as_cs | utf8mb4 | 303 | | Yes | 0 | NO PAD | | utf8mb4_ja_0900_as_cs_ks | utf8mb4 | 304 | | Yes | 24 | NO PAD | | utf8mb4_latvian_ci | utf8mb4 | 226 | | Yes | 8 | PAD SPACE | | utf8mb4_la_0900_ai_ci | utf8mb4 | 271 | | Yes | 0 | NO PAD | | utf8mb4_la_0900_as_cs | utf8mb4 | 294 | | Yes | 0 | NO PAD | | utf8mb4_lithuanian_ci | utf8mb4 | 236 | | Yes | 8 | PAD SPACE | | utf8mb4_lt_0900_ai_ci | utf8mb4 | 268 | | Yes | 0 | NO PAD | | utf8mb4_lt_0900_as_cs | utf8mb4 | 291 | | Yes | 0 | NO PAD | | utf8mb4_lv_0900_ai_ci | utf8mb4 | 258 | | Yes | 0 | NO PAD | | utf8mb4_lv_0900_as_cs | utf8mb4 | 281 | | Yes | 0 | NO PAD | | utf8mb4_persian_ci | utf8mb4 | 240 | | Yes | 8 | PAD SPACE | | utf8mb4_pl_0900_ai_ci | utf8mb4 | 261 | | Yes | 0 | NO PAD | | utf8mb4_pl_0900_as_cs | utf8mb4 | 284 | | Yes | 0 | NO PAD | | utf8mb4_polish_ci | utf8mb4 | 229 | | Yes | 8 | PAD SPACE | | utf8mb4_romanian_ci | utf8mb4 | 227 | | Yes | 8 | PAD SPACE | | utf8mb4_roman_ci | utf8mb4 | 239 | | Yes | 8 | PAD SPACE | | utf8mb4_ro_0900_ai_ci | utf8mb4 | 259 | | Yes | 0 | NO PAD | | utf8mb4_ro_0900_as_cs | utf8mb4 | 282 | | Yes | 0 | NO PAD | | utf8mb4_ru_0900_ai_ci | utf8mb4 | 306 | | Yes | 0 | NO PAD | | utf8mb4_ru_0900_as_cs | utf8mb4 | 307 | | Yes | 0 | NO PAD | | utf8mb4_sinhala_ci | utf8mb4 | 243 | | Yes | 8 | PAD SPACE | | utf8mb4_sk_0900_ai_ci | utf8mb4 | 269 | | Yes | 0 | NO PAD | | utf8mb4_sk_0900_as_cs | utf8mb4 | 292 | | Yes | 0 | NO PAD | | utf8mb4_slovak_ci | utf8mb4 | 237 | | Yes | 8 | PAD SPACE | | utf8mb4_slovenian_ci | utf8mb4 | 228 | | Yes | 8 | PAD SPACE | | utf8mb4_sl_0900_ai_ci | utf8mb4 | 260 | | Yes | 0 | NO PAD | | utf8mb4_sl_0900_as_cs | utf8mb4 | 283 | | Yes | 0 | NO PAD | | utf8mb4_spanish2_ci | utf8mb4 | 238 | | Yes | 8 | PAD SPACE | | utf8mb4_spanish_ci | utf8mb4 | 231 | | Yes | 8 | PAD SPACE | | utf8mb4_sv_0900_ai_ci | utf8mb4 | 264 | | Yes | 0 | NO PAD | | utf8mb4_sv_0900_as_cs | utf8mb4 | 287 | | Yes | 0 | NO PAD | | utf8mb4_swedish_ci | utf8mb4 | 232 | | Yes | 8 | PAD SPACE | | utf8mb4_tr_0900_ai_ci | utf8mb4 | 265 | | Yes | 0 | NO PAD | | utf8mb4_tr_0900_as_cs | utf8mb4 | 288 | | Yes | 0 | NO PAD | | utf8mb4_turkish_ci | utf8mb4 | 233 | | Yes | 8 | PAD SPACE | | utf8mb4_unicode_520_ci | utf8mb4 | 246 | | Yes | 8 | PAD SPACE | | utf8mb4_unicode_ci | utf8mb4 | 224 | | Yes | 8 | PAD SPACE | | utf8mb4_vietnamese_ci | utf8mb4 | 247 | | Yes | 8 | PAD SPACE | | utf8mb4_vi_0900_ai_ci | utf8mb4 | 277 | | Yes | 0 | NO PAD | | utf8mb4_vi_0900_as_cs | utf8mb4 | 300 | | Yes | 0 | NO PAD | | utf8mb4_zh_0900_as_cs | utf8mb4 | 308 | | Yes | 0 | NO PAD | +---------------------------- +--------- +----- +--------- +---------- +--------- +--------------- +
有关这些归类的更多信息,请参见“ Unicode字符集”。
归类具有以下一般特征:
- 两种不同的字符集不能具有相同的校验规则。
- 每个字符集都有一个默认的校验规则。例如,对于默认校验规则
utf8mb4
和latin1
是utf8mb4_0900_ai_ci
和latin1_swedish_ci
分别。该INFORMATION_SCHEMA
CHARACTER_SETS
表和SHOW CHARACTER SET
语句指示每个字符集的默认校验规则。该INFORMATION_SCHEMA
COLLATIONS
表和SHOW COLLATION
语句具有一列,用于指示每个归类是否为其字符集的默认设置(Yes
如果是,则为空)。 - 归类名称以它们所关联的字符集的名称开头,通常后跟一个或多个后缀,以表示其他归类特征。有关命名约定的更多信息,请参见“校验规则命名约定”。
当一个字符集具有多个校验规则时,可能不清楚哪种校验规则最适合给定的应用程序。为避免选择不合适的校验规则,请对代表性数据值进行一些比较,以确保给定的校验规则以期望的方式对值进行校验。
字符集库
字符集的全部是字符集中的字符集合。
字符串表达式具有一个曲目属性,该属性可以具有两个值:
ASCII
:表达式只能包含UnicodeU +0000
到范围内的字符U +007F
。UNICODE
:表达式可以包含UnicodeU +0000
到范围内的字符U +10FFFF
。其中包括基本多语言平面(BMP)范围内的字符(U +0000
至U +FFFF
)和BMP范围外的辅助字符(U +10000
至U +10FFFF
)。
ASCII
范围的一个子集UNICODE
范围内,所以用一个字符串ASCII
剧目可以安全地没有信息的字符集与任何串的损失被转换UNICODE
库或为一个字符集是一个超集ASCII
。(所有MySQL字符集都是的超集,ASCII
但除外swe7
,它将在瑞典重音符号中重用一些标点符号。)在许多情况下,MySQL否则会返回“非法的校验规则混合”错误,因此使用表目功能可以在表达式中进行字符集转换。。
以下讨论提供了表达式及其组成部分的示例,并描述了组成部分的使用如何更改字符串表达式求值:
字符串常量的库取决于字符串内容,并且可能与字符串字符集的库不同。考虑以下语句:
SET NAMES utf8;SELECT 'abc';SELECT _utf8'def';SELECT N'MySQL';尽管
utf8
在以上每种情况下都使用字符集,但是这些字符串实际上并不包含ASCII范围以外的任何字符,因此它们的字符表ASCII
不是UNICODE
。具有
ascii
字符集的列由于其字符集而具有ASCII
全部功能。在下表中,1
具有ASCII
曲目:CREATE TABLE t1 ( 1 CHAR(1)CHARACTER SET ascii);下面的示例说明在没有库的情况下发生错误的情况下,库可以如何确定结果:
CREATE TABLE t1 ( c1 CHAR(1)CHARACTER SET latin1, c2 CHAR(1)CHARACTER SET ascii );INSERT INTO t1VALUES ('a','b');SELECT CONCAT( 1, 2)FROM t1;没有曲目,将发生以下错误:
ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (ascii_general_ci,IMPLICIT) for operation 'concat'
使用库,可以发生子集到超集(
ascii
到latin1
)的转换,并返回结果:+--------------- + | CONCAT( 1, 2) | +--------------- + | ab | +--------------- +
- 具有一个字符串参数的函数将继承其参数库。的结果具有指令集,因为其参数具有指令集。
UPPER(_utf8'ab ')
ASCII
ASCII
对于返回字符串但没有字符串参数并
haracter_set_connection
用作结果字符集的函数,结果表为ASCII
ifharacter_set_connection
isascii
,UNICODE
否则为:FORMAT(numeric_column, 4);
使用库会改变MySQL评估以下示例的方式:
SET NAMES ascii;CREATE TABLE t1 (a INT, b VARCHAR(10)CHARACTER SET latin1);INSERT INTO t1VALUES (1,'b');SELECT CONCAT(FORMAT(a, 4), b)FROM t1;没有曲目,将发生以下错误:
ERROR 1267 (HY000): Illegal mix of collations (ascii_general_ci,COERCIBLE) and (latin1_swedish_ci,IMPLICIT) for operation 'concat'
使用曲目时,将返回结果:
+------------------------- + | CONCAT(FORMAT(a, 4), b) | +------------------------- + | 1.0000b | +------------------------- +
具有两个或多个字符串参数的函数使用“最宽的”参数表作为结果表(
UNICODE
大于ASCII
)。考虑以下CONCAT()
调用:CONCAT(_ucs2 X'0041', _ucs2 X'0042') CONCAT(_ucs2 X'0041', _ucs2 X'00C2')
对于第一个调用,指令表是
ASCII
因为两个参数都在ascii
字符集范围内。对于第二个调用,该库是UNICODE
因为第二个自变量在ascii
字符集范围之外。仅根据影响结果的字符集和校验规则的参数的清单确定函数返回值的清单。
IF( olumn1 < column2, 'smaller', 'greater')
结果库是
ASCII
因为两个字符串参数(第二个参数和第三个参数)都具有ASCII
库。即使表达式使用字符串值,第一个参数对于结果库也不重要。
元数据的UTF-8
元数据是“关于数据的数据。”描述数据库的任何内容(而不是数据库的内容)都是元数据。因此,列名,数据库名,用户名,版本名以及大多数字符串结果SHOW
都是元数据。表中的内容也是如此,INFORMATION_SCHEMA
因为按定义这些表包含有关数据库对象的信息。
元数据的表示形式必须满足以下要求:
- 所有元数据必须使用相同的字符集。否则,由于这些操作结果的同一列中的不同行将使用不同的字符集,因此其中的
SHOW
语句或SELECT
表中的语句均INFORMATION_SCHEMA
无法正常工作。 - 元数据必须包含所有语言的所有字符。否则,用户将无法使用自己的语言命名列和表。
为了满足这两个要求,MySQL将元数据存储在Unicode字符集(即UTF-8)中。如果您从不使用带重音符号或非拉丁字符,则不会造成任何干扰。但是,如果这样做,您应该知道元数据位于UTF-8中。
元数据要求意味着返回值USER()
,CURRENT_USER()
,SESSION_USER()
,SYSTEM_USER()
,DATABASE()
,和VERSION()
功能在默认情况下使用UTF-8字符集。
服务器将 haracter_set_system
系统变量设置为元数据字符集的名称:
mysql>SHOW VARIABLES LIKE 'character_set_system'; +---------------------- +------- + | Variable_name | Value | +---------------------- +------- + | character_set_system | utf8 | +---------------------- +------- +
使用Unicode存储元数据并不意味着服务器默认返回列标题和字符集中的DESCRIBE
函数结果 haracter_set_system
。使用SELECT column1 FROM t
该名称时,名称 olumn1
本身将从服务器返回给客户端,使用 haracter_set_results
系统变量值确定的字符集,该字符集的默认值为utf8mb4
。如果希望服务器将元数据结果传递回不同的字符集,请使用该SET NAMES
语句强制服务器执行字符集转换。SET NAMES
设置 haracter_set_results
和其他相关的系统变量。(看到“连接字符集和校验规则”。)或者,客户端程序可以在从服务器接收到结果后执行转换。客户端执行转换的效率更高,但是此选项并非始终对所有客户端都可用。
如果 haracter_set_results
将设置为NULL
,则不执行任何转换,并且服务器使用其原始字符集(由表示的字符集)返回元数据 haracter_set_system
。
从服务器返回到客户端的错误消息将与元数据一样自动转换为客户端字符集。
如果您USER()
在单个语句中使用(例如)该函数进行比较或赋值,请不要担心。MySQL为您执行一些自动转换。
SELECT *FROM t1WHERE USER() = latin1_column;
之所以可行,latin1_column
是因为比较之前,的内容会自动转换为UTF-8。
INSERT INTO t1 (latin1_column)SELECT USER();
之所以可以这样做是因为的内容USER()
会latin1
在分配之前自动转换为。
尽管自动转换不在SQL标准中,但该标准确实指出,每个字符集(就支持的字符而言)都是Unicode 的“子集”。因为众所周知的原则是“适用于超集的内容可以适用于子集”,所以我们认为Unicode的校验规则可以适用于与非Unicode字符串的比较。有关字符串强制转换的更多信息,请参见“SQL语句中的校验规则强制性”。