在 MySQL 中使用区分重音的主键
Use accent senstive primary key in MySQL
想要的结果:
在 MySQL 中有一个区分重音的主键。
我有一个 table 个独特的词,所以我使用这个词本身作为主键(顺便说一下,如果有人可以给我一个建议,我不知道它是否是一个好design/practice 或没有)。
我需要该字段区分重音(为什么不区分大小写),因为它必须区分,例如,'demandé'
和 'demande'
,法语动词 [=] 的两种不同变形83=]。我在数据库中存储带重音的单词没有任何问题。我只是无法插入两个在未重音时相同的重音字符串。
错误:
尝试使用以下查询创建 'demandé'
行时:
INSERT INTO `corpus`.`token` (`name_token`) VALUES ('demandé');
我遇到了这个错误:
ERROR 1062: 1062: Duplicate entry 'demandé' for key 'PRIMARY'
问题:
- 为了让 "demande" 和 "demandé" 在 table 中有两个不同的唯一主键,应该在流程中的哪个位置进行修改?
解决方案 table 声明
- 我如何进行重音敏感查询?以下是正确的方法吗:
SELECT * FROM corpus.token WHERE name_token = 'demandé' COLLATE utf8_bin
SOLUTION with WHERE 语句
我发现我可以通过使用 BINARY
关键字来实现这一点(参见 sqlFiddle)。 collate
和 binary
有什么区别?
我可以保留其他 table 的任何更改吗? (无论如何,我将不得不重建 table,因为它有点乱)
我对 MySQL 中的编码不太满意table。我对该数据库中的编码没有任何问题(我很幸运,因为我的数据可能并不总是使用相同的编码......而且我对此无能为力)。我有一种感觉,关于 "accent sensitive" 问题的任何修改都可能会对其他查询或数据完整性造成一些编码问题。我的担心对吗?
一步一步:
数据库创建:
CREATE DATABASE corpus DEFAULT CHARACTER SET utf8;
Table 个独特的单词:
CREATE TABLE token (name_token VARCHAR(50), freq INTEGER, CONSTRAINT pk_token PRIMARY KEY (name_token))
查询
SELECT * FROM corpus.token WHERE name_token = 'demande';
SELECT * FROM corpus.token WHERE name_token = 'demandé';
两个returns同一行:
demande
可能你需要这个
_ci in a collation name=case insensitive
如果您对该字段的搜索总是区分大小写,则将该字段的排序规则声明为 utf8_bin...这将比较 utf8 编码的字节是否相等。
col_name varchar(10) collate utf8_bin
如果搜索通常不区分大小写,但您想为此搜索设置例外,请尝试;
WHERE col_name = 'demandé' collate utf8_bin
试试这个
mysql> SET NAMES 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1
-> (c1 CHAR(1) CHARACTER SET UTF8 COLLATE utf8_general_ci);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t1 VALUES ('a'),('A'),('À'),('á');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
+------+---------+------------------------+
| c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
+------+---------+------------------------+
| a | 61 | 0041 |
| A | 41 | 0041 |
| À | C380 | 0041 |
| á | C3A1 | 0041 |
+------+---------+------------------------+
4 rows in set (0.00 sec)
排序规则。你有两个选择,而不是三个:
utf8_bin
将所有这些视为 不同的 :demandé
和 demande
以及 Demandé
。
utf8_..._ci
(通常是 utf8_general_ci
或 utf8_unicode_ci
)将所有这些视为 相同:demandé
和 demande
和 Demandé
.
如果您只想区分大小写(demandé
= demande
,但都不匹配 Demandé
),那您就不走运了。
如果你只想要区分口音(demandé
= Demandé
,但两者都不匹配 demande
),那你就不走运了。
声明。随心所欲的最佳方式:
CREATE TABLE (
name VARCHAR(...) CHARACTER SET utf8 COLLATE utf8_... NOT NULL,
...
PRIMARY KEY(name)
)
不要即时更改排序规则。如果 name
:
中的排序规则不同,这将不会使用索引(也就是说,会很慢)
WHERE name = ... COLLATE ...
二进制。 数据类型BINARY
、VARBINARY
和BLOB
非常类似于CHAR
、VARCHAR
和TEXT
与 COLLATE ..._bin
。也许唯一的区别是文本将被检查为有效的 utf8 存储在 VARCHAR ... COLLATE ..._bin
中,但在存储到 VARBINARY...
中时不会被检查。 比较(WHERE
、ORDER BY
等)将相同;也就是说,简单地比较位,不要进行大小写折叠或重音剥离等。
想要的结果:
在 MySQL 中有一个区分重音的主键。
我有一个 table 个独特的词,所以我使用这个词本身作为主键(顺便说一下,如果有人可以给我一个建议,我不知道它是否是一个好design/practice 或没有)。
我需要该字段区分重音(为什么不区分大小写),因为它必须区分,例如,'demandé'
和 'demande'
,法语动词 [=] 的两种不同变形83=]。我在数据库中存储带重音的单词没有任何问题。我只是无法插入两个在未重音时相同的重音字符串。
错误:
尝试使用以下查询创建 'demandé'
行时:
INSERT INTO `corpus`.`token` (`name_token`) VALUES ('demandé');
我遇到了这个错误:
ERROR 1062: 1062: Duplicate entry 'demandé' for key 'PRIMARY'
问题:
- 为了让 "demande" 和 "demandé" 在 table 中有两个不同的唯一主键,应该在流程中的哪个位置进行修改?
解决方案
- 我如何进行重音敏感查询?以下是正确的方法吗:
SELECT * FROM corpus.token WHERE name_token = 'demandé' COLLATE utf8_bin
SOLUTION
我发现我可以通过使用
BINARY
关键字来实现这一点(参见 sqlFiddle)。collate
和binary
有什么区别?我可以保留其他 table 的任何更改吗? (无论如何,我将不得不重建 table,因为它有点乱)
我对 MySQL 中的编码不太满意table。我对该数据库中的编码没有任何问题(我很幸运,因为我的数据可能并不总是使用相同的编码......而且我对此无能为力)。我有一种感觉,关于 "accent sensitive" 问题的任何修改都可能会对其他查询或数据完整性造成一些编码问题。我的担心对吗?
一步一步:
数据库创建:
CREATE DATABASE corpus DEFAULT CHARACTER SET utf8;
Table 个独特的单词:
CREATE TABLE token (name_token VARCHAR(50), freq INTEGER, CONSTRAINT pk_token PRIMARY KEY (name_token))
查询
SELECT * FROM corpus.token WHERE name_token = 'demande';
SELECT * FROM corpus.token WHERE name_token = 'demandé';
两个returns同一行:
demande
可能你需要这个
_ci in a collation name=case insensitive
如果您对该字段的搜索总是区分大小写,则将该字段的排序规则声明为 utf8_bin...这将比较 utf8 编码的字节是否相等。
col_name varchar(10) collate utf8_bin
如果搜索通常不区分大小写,但您想为此搜索设置例外,请尝试;
WHERE col_name = 'demandé' collate utf8_bin
试试这个
mysql> SET NAMES 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE TABLE t1
-> (c1 CHAR(1) CHARACTER SET UTF8 COLLATE utf8_general_ci);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t1 VALUES ('a'),('A'),('À'),('á');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT c1, HEX(c1), HEX(WEIGHT_STRING(c1)) FROM t1;
+------+---------+------------------------+
| c1 | HEX(c1) | HEX(WEIGHT_STRING(c1)) |
+------+---------+------------------------+
| a | 61 | 0041 |
| A | 41 | 0041 |
| À | C380 | 0041 |
| á | C3A1 | 0041 |
+------+---------+------------------------+
4 rows in set (0.00 sec)
排序规则。你有两个选择,而不是三个:
utf8_bin
将所有这些视为 不同的 :demandé
和 demande
以及 Demandé
。
utf8_..._ci
(通常是 utf8_general_ci
或 utf8_unicode_ci
)将所有这些视为 相同:demandé
和 demande
和 Demandé
.
如果您只想区分大小写(demandé
= demande
,但都不匹配 Demandé
),那您就不走运了。
如果你只想要区分口音(demandé
= Demandé
,但两者都不匹配 demande
),那你就不走运了。
声明。随心所欲的最佳方式:
CREATE TABLE (
name VARCHAR(...) CHARACTER SET utf8 COLLATE utf8_... NOT NULL,
...
PRIMARY KEY(name)
)
不要即时更改排序规则。如果 name
:
WHERE name = ... COLLATE ...
二进制。 数据类型BINARY
、VARBINARY
和BLOB
非常类似于CHAR
、VARCHAR
和TEXT
与 COLLATE ..._bin
。也许唯一的区别是文本将被检查为有效的 utf8 存储在 VARCHAR ... COLLATE ..._bin
中,但在存储到 VARBINARY...
中时不会被检查。 比较(WHERE
、ORDER BY
等)将相同;也就是说,简单地比较位,不要进行大小写折叠或重音剥离等。