Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

12.14.4.1 使用 LDML 语法定义 UCA 排序

要添加 Unicode 字符集的 UCA 排序而不需要重新编译 MySQL,请按照以下步骤进行。如果您不熟悉 LDML 规则用于描述排序特征,请参阅 第 12.14.4.2 节,“MySQL 中支持的 LDML 语法”

该示例将添加一个名为 utf8mb4_phone_ci 的排序到 utf8mb4 字符集中。该排序旨在处理 Web 应用程序中用户发布的姓名和电话号码。电话号码可以以非常不同的格式出现:

+7-12345-67
+7-12-345-67
+7 12 345 67
+7 (12) 345 67
+71234567

处理这些值时出现的问题是,各种允许的格式使得搜索特定的电话号码变得非常困难。解决方案是定义一个新的排序,使标点符号可被忽略。

  1. 选择一个排序 ID,如 第 12.14.2 节,“选择排序 ID”所示。以下步骤使用 ID 1029。

  2. 修改 Index.xml 配置文件,该文件位于由 character_sets_dir 系统变量命名的目录中。您可以检查变量值,如下所示,尽管路径名可能在您的系统上不同:

    mysql> SHOW VARIABLES LIKE 'character_sets_dir';
    +--------------------+-----------------------------------------+
    | Variable_name      | Value                                   |
    +--------------------+-----------------------------------------+
    | character_sets_dir | /user/local/mysql/share/mysql/charsets/ |
    +--------------------+-----------------------------------------+
  3. 选择排序的名称并将其列在 Index.xml 文件中。此外,您还需要提供排序规则。找到 <charset> 元素,以便将排序添加到该字符集,然后添加一个 <collation> 元素,指示排序名称和 ID,以关联名称与 ID。在 <collation> 元素中,提供一个 <rules> 元素,包含排序规则:

    <charset name="utf8mb4">
      ...
      <collation name="utf8mb4_phone_ci" id="1029">
        <rules>
          <reset>\u0000</reset>
          <i>\u0020</i> <!-- space -->
          <i>\u0028</i> <!-- left parenthesis -->
          <i>\u0029</i> <!-- right parenthesis -->
          <i>\u002B</i> <!-- plus -->
          <i>\u002D</i> <!-- hyphen -->
        </rules>
      </collation>
      ...
    </charset>
  4. 如果您想为其他 Unicode 字符集定义类似的排序,只需添加其他 <collation> 元素。例如,要定义 ucs2_phone_ci,请将 <collation> 元素添加到 <charset name="ucs2"> 元素中。请记住,每个排序都必须有其唯一的 ID。

  5. 重新启动服务器,并使用以下语句来验证排序是否存在:

    mysql> SHOW COLLATION WHERE Collation = 'utf8mb4_phone_ci';
    +------------------+---------+------+---------+----------+---------+
    | Collation        | Charset | Id   | Default | Compiled | Sortlen |
    +------------------+---------+------+---------+----------+---------+
    | utf8mb4_phone_ci | utf8mb4 | 1029 |         |          |       8 |
    +------------------+---------+------+---------+----------+---------+

现在测试排序,以确保它具有所需的属性。

创建一个包含一些示例电话号码的表,使用新的排序:

mysql> CREATE TABLE phonebook (
         name VARCHAR(64),
         phone VARCHAR(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_phone_ci
       );
Query OK, 0 rows affected (0.09 sec)

mysql> INSERT INTO phonebook VALUES ('Svoj','+7 912 800 80 02');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Hf','+7 (912) 800 80 04');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Bar','+7-912-800-80-01');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Ramil','(7912) 800 80 03');
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO phonebook VALUES ('Sanja','+380 (912) 8008005');
Query OK, 1 row affected (0.00 sec)

运行一些查询,以查看是否忽略了比较和排序中的标点符号:

mysql> SELECT * FROM phonebook ORDER BY phone;
+-------+--------------------+
| name  | phone              |
+-------+--------------------+
| Sanja | +380 (912) 8008005 |
| Bar   | +7-912-800-80-01   |
| Svoj  | +7 912 800 80 02   |
| Ramil | (7912) 800 80 03   |
| Hf    | +7 (912) 800 80 04 |
+-------+--------------------+
5 rows in set (0.00 sec)

mysql> SELECT * FROM phonebook WHERE phone='+7(912)800-80-01';
+------+------------------+
| name | phone            |
+------+------------------+
| Bar  | +7-912-800-80-01 |
+------+------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM phonebook WHERE phone='79128008001';
+------+------------------+
| name | phone            |
+------+------------------+
| Bar  | +7-912-800-80-01 |
+------+------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM phonebook WHERE phone='7 9 1 2 8 0 0 8 0 0 1';
+------+------------------+
| name | phone            |
+------+------------------+
| Bar  | +7-912-800-80-01 |
+------+------------------+
1 row in set (0.00 sec)