# 15.2 校对规则

在本教程中，您将了解MySQL校对规则以及如何设置MySQL服务器，数据库，表和列的字符集和校对规则。

## MySQL校对规则简介

MySQL校对规则是用于比较特定字符集中的字符的一组规则。 MySQL中的每个字符集可以有多个校对规则，并且至少具有一个默认校对规则。两个字符集不能具有相同的归类。

MySQL提供了`SHOW CHARACTER SET`语句，查看字符集的默认校对规则，如下所示：

```sql
+----------+---------------------------------+---------------------+--------+
| 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
```

默认校对规则列的值指定字符集的默认校对规则。

按照惯例，字符集的校对规则以字符集名称开头，以`_ci`(不区分大小写)`_cs`(区分大小写)或`_bin`(二进制文件)结尾。

要获取给定字符集的所有校对规则，请使用`SHOW COLLATION`语句如下：

```sql
SHOW COLLATION LIKE 'character_set_name%';
```

例如，要获取`latin1`字符集的所有校对规则，请使用以下语句：

```sql
SHOW COLLATION LIKE 'latin1%';
```

执行上面语句，得到用于`latin1`字符集的MySQL校对规则，如下结果 -

```sql
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation         | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1  |  5 |         | Yes      |       1 |
| latin1_swedish_ci | latin1  |  8 | Yes     | Yes      |       1 |
| latin1_danish_ci  | latin1  | 15 |         | Yes      |       1 |
| latin1_german2_ci | latin1  | 31 |         | Yes      |       2 |
| latin1_bin        | latin1  | 47 |         | Yes      |       1 |
| latin1_general_ci | latin1  | 48 |         | Yes      |       1 |
| latin1_general_cs | latin1  | 49 |         | Yes      |       1 |
| latin1_spanish_ci | latin1  | 94 |         | Yes      |       1 |
+-------------------+---------+----+---------+----------+---------+
8 rows in set
```

如上所述，每个字符集都具有默认校对规则，例如`latin1_swedish_ci`是`latin1`字符集的默认校对规则。

## 设置字符集和校对规则

MySQL允许您在四个级别指定字符集和校对规则：服务器，数据库，表和列。

**在服务器级别设置字符集和校对规则**

注意MySQL使用`latin1`作为默认字符集，因此，其默认校对规则为`latin1_swedish_ci`。 您可以在服务器启动时更改这些设置。

如果在服务器启动时仅指定一个字符集，MySQL将使用字符集的默认校对规则。 如果您明确指定了一个字符集和校对规则，MySQL将使用数据库服务器中的字符集和校对规则来创建的所有数据库。

以下语句通过命令行启动并设置服务器使用`utf8`字符集和`utf8_unicode_cs`校对规则：

```sql
$ mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
```

**在数据库级别设置字符集和校对规则**

创建数据库时，如果不指定其字符集和校对规则，MySQL将使用数据库的服务器的默认字符集和校对规则。

可以使用[CREATE DATABASE](http://www.yiibai.com/mysql/create-table.html)或[ALTER DATABASE](http://www.yiibai.com/mysql/alter-table.html)语句来覆盖数据库级的默认设置，如下所示：

```sql
CREATE DATABASE database_name
CHARACTER SET character_set_name
COLLATE collation_name

-- 修改校对规则
ALTER  DATABASE database_name
CHARACTER SET character_set_name
COLLATE collation_name
```

MySQL在数据库级使用数据库中创建的所有表的字符集和校对规则。

**在表级别设置字符集和校对规则**

数据库可能包含与默认数据库的字符集和校对规则不同的字符集和校对规则的表。

当您通过使用`CREATE TABLE`语句创建表或使用`ALTER TABLE`语句更改表的结构时，可以指定表的默认字符集和校对规则。

```sql
CREATE TABLE table_name(
)
CHARACTER SET character_set_name
COLLATE collation_name
```

或者 -

```sql
ALTER TABLE table_name(
)
CHARACTER SET character_set_name
COLLATE collation_name
```

**在列级别设置字符集和校对规则**

`CHAR`，`VARCHAR`或`TEXT`类型的列可以使用与表的默认字符集和校对规则不同的，自己指定的字符集和校对规则。

可以按照`CREATE TABLE`或`ALTER TABLE`语句的列定义中的列指定字符集和校对规则，如下所示：

```sql
column_name [CHAR | VARCHAR | TEXT] (length)
CHARACTER SET character_set_name
COLLATE collation_name
```

以下是设置字符集和校对规则的规则：

* 如果显式指定字符集和校对规则，则使用字符集和校对规则。
* 如果指定一个字符集并忽略校对规则，则使用字符集的默认校对规则。
* 如果指定没有字符集的校对规则，则使用与校对规则相关联的字符集。
* 如果省略字符集和校对规则，则使用默认字符集和校对规则。

我们来看一些设置字符集和校对规则的例子。

## 设置字符集和校对规则的示例

**首先**，我们使用`utf8`作为字符集创建一个新数据库，将`utf8_unicode_ci`作为默认校对规则：

```sql
CREATE DATABASE mydbdemo
CHARACTER SET utf8
COLLATE utf8_unicode_ci;
```

因为明确指定`mydbdemo`数据库的字符集和校对规则，所以`mydbdemo`数据库不会在服务器级别采用默认字符集和校对规则。

**其次**，我们在`mydbdemo`数据库中创建一个名为`t1`的新表，但不指定字符集和校对规则：

```sql
USE mydbdemo; 
CREATE TABLE t1(
    c1 char(25)
);
```

如上所示，我们并没有为`t1`表指定字符集和校对规则; MySQL将检查数据库级别以确定`t1`表的字符集和校对规则。 在这种情况下，`t1`表将使用`utf8`作为默认字符集，`utf8_unicode_ci`作为默认校对规则。

**第三**，对于`t1`表，我们将其字符集更改为`latin1`，并将其校对规则改为`latin1_german1_ci`：

```sql
ALTER TABLE t1
CHARACTER SET latin1
COLLATE latin1_german1_ci;
```

`t1`表中的`c1`列使用`latin1`作为字符集，`latin1_german1_ci`作为校对规则。

**第四**，将`c1`列的字符集更改为`latin1`：

```sql
ALTER TABLE t2
MODIFY c1 VARCHAR(25)
CHARACTER SET latin1;
```

现在，`c1`列使用`latin1`字符集，但是它的校对规则呢？ 是否从表的校对规则继承了`latin1_german1_ci`校对规则？ 不是的，因为`latin1`字符集的默认校对规则是`latin1_swedish_ci`，所以`c1`列具有`latin1_swedish_ci`校对规则。

在本教程中，您已经了解了MySQL校对规则以及如何为MySQL服务器，数据库，表和列指定字符集和校对规则。
