表情符号作为 MariaDB 主键中的问号
Emojis as question marks in MariaDB primary key
与以下 table, 使用 mariadb-server-10.1 10.1.32+maria-1~trusty:
CREATE TABLE `tags` (
`tag_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`thing_id` int(11) NOT NULL,
PRIMARY KEY (`thing_id`,`tag_name`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
显示为(在 SQLAlchemy 应用程序中):
IntegrityError: (IntegrityError)
(1062, "Duplicate entry '1532-?' for key 'PRIMARY'")
在第二次尝试插入表情符号时。
第一个在数据库中似乎没问题(相信我,它在我的控制台和浏览器中显示为 "alien" 表情符号):
> select tag_name, HEX(tag_name) from tags;
+----------+----------------+
| tag_name | HEX(tag_name) |
+----------+----------------+
| GOODGUY | 474F4F44475559 |
| | F09F91BD |
+----------+----------------+
2 rows in set (0.00 sec)
我知道 Emoji's in mysql turns to question marks ,但是 my.cnf 有:
default-character-set = utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-character-set = utf8mb4
和 utf8mb4 正在客户端中使用(字符集作为 ?charset=utf8mb4
添加到连接字符串)。而且我相信主键是在服务器端检查的。
还有什么我遗漏的吗(可以检查)或者是一些 MariaDB 错误还是需要一些额外的配置?
不确定是否相关,但通过 mysql
shell 插入时出现同样的问题。还尝试了这个以查看发生了什么(在 中找到):
> SELECT ''='' COLLATE utf8mb4_unicode_ci;
+------------------------------------+
| '?'='?' COLLATE utf8mb4_unicode_ci |
+------------------------------------+
| 1 |
+------------------------------------+
但不确定这是否相关。
我不明白:数据库有时显示正常(通过两个客户端 - shell 和 SQLAlchemy 应用程序),但随后无法在 header 中显示?从我得到的证据来看,我不明白这种糟糕的转换发生在哪里。数据库中的数据似乎没问题(见上面的十六进制),但是两个表情符号相当于主键?
再对比一下:
> SELECT ''='' COLLATE utf8mb4_bin;
+-----------------------------+
| '?'='?' COLLATE utf8mb4_bin |
+-----------------------------+
| 0 |
+-----------------------------+
这种分指主键不使用二进制?在索引中使用之前,所有表情符号都转换成其他东西了吗?很奇怪。
mysql> SELECT ''='' COLLATE utf8mb4_unicode_520_ci;
+----------------------------------------+
| '?'='?' COLLATE utf8mb4_unicode_520_ci |
+----------------------------------------+
| 0 |
+----------------------------------------+
需要注意两点:
- 520 归类将它们视为不同。
- 问号是显示问题。
进一步隔离...
mysql> SELECT HEX('');
+----------+
| HEX('?') |
+----------+
| F09F9886 |
+----------+
我的观点是问号可能是 显示 问题,并且(正如您用十六进制指出的那样)它不是编码问题:
(1062, "Duplicate entry '1532-?' for key 'PRIMARY'")
并且,如果您想用两个表情符号标记 1532,则该列需要为 utf8mb4_unicode_520_ci
(或 utf8mb4_bin)。
与以下 table, 使用 mariadb-server-10.1 10.1.32+maria-1~trusty:
CREATE TABLE `tags` (
`tag_name` varchar(150) COLLATE utf8mb4_unicode_ci NOT NULL,
`thing_id` int(11) NOT NULL,
PRIMARY KEY (`thing_id`,`tag_name`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
显示为(在 SQLAlchemy 应用程序中):
IntegrityError: (IntegrityError)
(1062, "Duplicate entry '1532-?' for key 'PRIMARY'")
在第二次尝试插入表情符号时。
第一个在数据库中似乎没问题(相信我,它在我的控制台和浏览器中显示为 "alien" 表情符号):
> select tag_name, HEX(tag_name) from tags;
+----------+----------------+
| tag_name | HEX(tag_name) |
+----------+----------------+
| GOODGUY | 474F4F44475559 |
| | F09F91BD |
+----------+----------------+
2 rows in set (0.00 sec)
我知道 Emoji's in mysql turns to question marks ,但是 my.cnf 有:
default-character-set = utf8mb4
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
default-character-set = utf8mb4
和 utf8mb4 正在客户端中使用(字符集作为 ?charset=utf8mb4
添加到连接字符串)。而且我相信主键是在服务器端检查的。
还有什么我遗漏的吗(可以检查)或者是一些 MariaDB 错误还是需要一些额外的配置?
不确定是否相关,但通过 mysql
shell 插入时出现同样的问题。还尝试了这个以查看发生了什么(在
> SELECT ''='' COLLATE utf8mb4_unicode_ci;
+------------------------------------+
| '?'='?' COLLATE utf8mb4_unicode_ci |
+------------------------------------+
| 1 |
+------------------------------------+
但不确定这是否相关。
我不明白:数据库有时显示正常(通过两个客户端 - shell 和 SQLAlchemy 应用程序),但随后无法在 header 中显示?从我得到的证据来看,我不明白这种糟糕的转换发生在哪里。数据库中的数据似乎没问题(见上面的十六进制),但是两个表情符号相当于主键?
再对比一下:
> SELECT ''='' COLLATE utf8mb4_bin;
+-----------------------------+
| '?'='?' COLLATE utf8mb4_bin |
+-----------------------------+
| 0 |
+-----------------------------+
这种分指主键不使用二进制?在索引中使用之前,所有表情符号都转换成其他东西了吗?很奇怪。
mysql> SELECT ''='' COLLATE utf8mb4_unicode_520_ci;
+----------------------------------------+
| '?'='?' COLLATE utf8mb4_unicode_520_ci |
+----------------------------------------+
| 0 |
+----------------------------------------+
需要注意两点:
- 520 归类将它们视为不同。
- 问号是显示问题。
进一步隔离...
mysql> SELECT HEX('');
+----------+
| HEX('?') |
+----------+
| F09F9886 |
+----------+
我的观点是问号可能是 显示 问题,并且(正如您用十六进制指出的那样)它不是编码问题:
(1062, "Duplicate entry '1532-?' for key 'PRIMARY'")
并且,如果您想用两个表情符号标记 1532,则该列需要为 utf8mb4_unicode_520_ci
(或 utf8mb4_bin)。