MySQL中的字符集和校验规则
MySQL Server支持多种字符集,包括几种Unicode字符集。要显示可用的字符集,请使用INFORMATION_SCHEMACHARACTER_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_SCHEMACOLLATIONS表或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_SCHEMACHARACTER_SETS表和SHOW CHARACTER SET语句指示每个字符集的默认校验规则。该INFORMATION_SCHEMACOLLATIONS表和SHOW COLLATION语句具有一列,用于指示每个归类是否为其字符集的默认设置(Yes如果是,则为空)。
- 归类名称以它们所关联的字符集的名称开头,通常后跟一个或多个后缀,以表示其他归类特征。有关命名约定的更多信息,请参见“校验规则命名约定”。
当一个字符集具有多个校验规则时,可能不清楚哪种校验规则最适合给定的应用程序。为避免选择不合适的校验规则,请对代表性数据值进行一些比较,以确保给定的校验规则以期望的方式对值进行校验。
字符集库
字符集的全部是字符集中的字符集合。
字符串表达式具有一个曲目属性,该属性可以具有两个值:
- ASCII:表达式只能包含Unicode- U +0000到范围内的字符- U +007F。
- UNICODE:表达式可以包含Unicode- U +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 t1- VALUES ('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 ')ASCIIASCII
- 对于返回字符串但没有字符串参数并 - haracter_set_connection用作结果字符集的函数,结果表为- ASCIIif- haracter_set_connectionis- ascii,- UNICODE否则为:- FORMAT(numeric_column, 4); - 使用库会改变MySQL评估以下示例的方式: - SET - NAMES ascii;- CREATE - TABLE t1 (a INT, b VARCHAR(10)- CHARACTER - SET latin1);- INSERT - INTO t1- VALUES (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语句中的校验规则强制性”。
