表情符号作为 MariaDB 主键中的问号
Posted
技术标签:
【中文标题】表情符号作为 MariaDB 主键中的问号【英文标题】:Emojis as question marks in MariaDB primary key 【发布时间】:2018-12-28 15:18:05 【问题描述】:如下表,使用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'")
在第二次尝试插入表情符号时。
第一个在数据库中似乎没问题(相信我,它在我的控制台和浏览器中显示为“外星人”表情符号):
> 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 插入时同样的问题。也试过这个看看发生了什么(在mysql utf8mb4_unicode_ci cause unique key collision找到这个):
> SELECT '????'='????' COLLATE utf8mb4_unicode_ci;
+------------------------------------+
| '?'='?' COLLATE utf8mb4_unicode_ci |
+------------------------------------+
| 1 |
+------------------------------------+
但不确定这是否相关。
我不明白:数据库有时会正常显示(通过客户端 - shell 和 SQLAlchemy 应用程序),但随后无法在标题中显示?从我得到的证据来看,我不明白这种糟糕的转变发生在哪里。数据库中的数据似乎没问题(见上面的十六进制),但是两个表情符号等效于主键?
还有一个对比:
> SELECT '????'='????' COLLATE utf8mb4_bin;
+-----------------------------+
| '?'='?' COLLATE utf8mb4_bin |
+-----------------------------+
| 0 |
+-----------------------------+
这种点手指主键不使用二进制?所有表情符号在用于索引之前都转换为其他内容?很奇怪。
【问题讨论】:
查看***.com/questions/38363566/…中的问号 Trouble with UTF-8 characters; what I see is not what I stored的可能重复 @RickJames 请不要这么快下结论。你提到的问题并没有解决我的问题。我已经在使用那里描述的技术了。 难道#1532 已经被那个表情符号标记了?而你又是INSERTing
同一个标签?而“问号”实际上来自 SQLAlchemy,而不是 MySQL?如果是这样,请考虑INSERT IGNORE ...
。
通过 mysql shell 也是一样的。我找到了另一个与排序相关的答案,但不确定该怎么做。将在一分钟内更新答案
【参考方案1】:
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'")
而且,如果您想用两个 Emoji 标记 1532,则该列需要为 utf8mb4_unicode_520_ci
(或 utf8mb4_bin)。
【讨论】:
是的,我的结果和上面一样。但那是什么utf8mb4_unicode_520_ci
?为什么我应该选择它而不是我当前的选择?我看到很多帖子如何摆脱“520”。
好的。找到描述***.com/questions/18904883/…
@RomanSusi - 520 将 Emoji 视为独特的。该链接正在谈论土耳其语。 520 不能很好地处理特定语言的要求。
***.com/questions/42385099/… ,加上谷歌搜索的更多内容 - 我没有进一步阅读。当然,也有类似的错误建议将 utf8mb4 替换为 utf8
@RomanSusi - 第二个链接涉及有人从 5.6(有 520)降级到 5.5。同样,这是避免 520 的正当理由,但不是适用于您的理由。以上是关于表情符号作为 MariaDB 主键中的问号的主要内容,如果未能解决你的问题,请参考以下文章