10.14.4.1 使用 LDML 语法定义 UCA 归类
要在不重新编译 MySQL 的情况下为 Unicode 字符集添加 UCA 归类,请使用以下过程。如果您不熟悉用于描述排序规则的排序 Feature 的 LDML 规则,请参见第 10.14.4.2 节“ MySQL 支持的 LDML 语法”。
该示例将名为utf8_phone_ci
的排序规则添加到utf8
字符集。该整理是针对涉及 Web 应用程序的场景而设计的,用户在该 Web 应用程序中发布其姓名和电话 Numbers。电话 Numbers 的格式可以非常不同:
+7-12345-67
+7-12-345-67
+7 12 345 67
+7 (12) 345 67
+71234567
通过处理这些类型的值引起的问题是,不同的允许格式使搜索特定电话 Numbers 变得非常困难。解决方案是定义一个新的排序规则,重新排序标点符号,使其可忽略。
-
选择一个归类 ID,如第 10.14.2 节“选择归类 ID”所示。以下步骤使用 ID 1029.
-
修改
Index.xml
配置文件。该文件位于character_sets_dir系统变量命名的目录中。尽管路径名称在您的系统上可能有所不同,但是您可以按以下方式检查变量值:
mysql> SHOW VARIABLES LIKE 'character_sets_dir';
+--------------------+-----------------------------------------+
| Variable_name | Value |
+--------------------+-----------------------------------------+
| character_sets_dir | /user/local/mysql/share/mysql/charsets/ |
+--------------------+-----------------------------------------+
- 选择排序规则的名称,并将其列出在
Index.xml
文件中。此外,您需要提供排序规则的规则。找到要向其添加排序规则的字符集的<charset>
元素,并添加一个指示排序规则名称和 ID 的<collation>
元素,以将该名称与 ID 关联。在<collation>
元素内,提供一个<rules>
元素,其中包含排序规则:
<charset name="utf8">
...
<collation name="utf8_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>
-
如果要对其他 Unicode 字符集使用类似的排序规则,请添加其他
<collation>
元素。例如,要定义ucs2_phone_ci
,请将<collation>
元素添加到<charset name="ucs2">
元素。请记住,每个排序规则必须具有自己的唯一 ID。 -
重新启动服务器,并使用此语句验证是否存在排序规则:
mysql> SHOW COLLATION WHERE Collation = 'utf8_phone_ci';
+---------------+---------+------+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+---------------+---------+------+---------+----------+---------+
| utf8_phone_ci | utf8 | 1029 | | | 8 |
+---------------+---------+------+---------+----------+---------+
现在测试排序规则,以确保它具有所需的属性。
使用新的排序规则创建一个包含一些示例电话 Numbers 的 table:
mysql> CREATE TABLE phonebook (
name VARCHAR(64),
phone VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_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)