要为 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
处理这些类型的值的难题在于,允许使用的不同格式使得搜索特定电话号码变得非常困难。解决方案是定义一个新的排序规则,重新排序标点符号,使其可忽略。
选择一个排序规则 ID,如第 12.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>
元素,并添加一个<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>
如果您想要其他 Unicode 字符集具有类似的排序规则,请添加其他
<collation>
元素。例如,要定义ucs2_phone_ci
,请向<charset name="ucs2">
元素添加一个<collation>
元素。请记住,每个排序规则都必须具有唯一的 ID。重新启动服务器并使用此语句验证排序规则是否存在
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)