代码之家  ›  专栏  ›  技术社区  ›  Roman Susi

在Mariadb主键中用作问号的emojis

  •  0
  • Roman Susi  · 技术社区  · 8 年前

    下表中,使用mariadb-server-10.1 10.1.32+maria-1~信任:

    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'")
    

    在第二次插入emoji时。

    第一个在数据库中似乎没问题(相信我,它在我的控制台和浏览器中显示为“外星人”emoji):

    > 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 但是我的CNF有:

    default-character-set = utf8mb4
    character-set-server = utf8mb4
    collation-server = utf8mb4_unicode_ci
    default-character-set = utf8mb4
    

    客户机中正在使用utf8mb4(在连接字符串中添加的字符集为 ?charset=utf8mb4 )我相信主键是在服务器端检查的。

    是否还有其他遗漏(可以检查)的地方,或者是否需要一些Mariadb错误或其他配置?

    不确定是否相关,但插入via时同样有问题 mysql 外壳。也试着看看发生了什么(在 mysql utf8mb4_unicode_ci cause unique key collision ):

    > SELECT '😗'='😆' COLLATE utf8mb4_unicode_ci;
    +------------------------------------+
    | '?'='?' COLLATE utf8mb4_unicode_ci |
    +------------------------------------+
    |                                  1 |
    +------------------------------------+
    

    但不确定这是否相关。

    我不明白:数据库有时会显示得很好(通过客户机shell和sqlacalchemy应用程序),但却无法在头中显示?从我得到的证据来看,我不明白这种糟糕的转变发生在哪里。数据库中的数据似乎正常(参见上面的十六进制),但是两个emojis等价于主键?

    再对比一下:

    > SELECT '😗'='😆' COLLATE utf8mb4_bin;
    +-----------------------------+
    | '?'='?' COLLATE utf8mb4_bin |
    +-----------------------------+
    |                           0 |
    +-----------------------------+
    

    这种点指主键不使用二进制?在索引中使用之前,所有的emoji都转换成了其他的东西?很奇怪。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Rick James diyism    8 年前
    mysql> SELECT '😗'='😆' COLLATE utf8mb4_unicode_520_ci;
    +----------------------------------------+
    | '?'='?' COLLATE utf8mb4_unicode_520_ci |
    +----------------------------------------+
    |                                      0 |
    +----------------------------------------+
    

    需要注意的两件事:

    • 这个 五百二十 排序规则将它们视为不同的。
    • 问号是显示问题。

    为了进一步隔离…

    mysql> SELECT HEX('😆');
    +----------+
    | HEX('?') |
    +----------+
    | F09F9886 |
    +----------+
    

    我的观点是问号可能是 显示 问题,并且(正如您用十六进制指出的那样)它不是编码问题:

    (1062, "Duplicate entry '1532-?' for key 'PRIMARY'")
    

    如果你想用两个emoji标记1532,那一列应该是 utf8mb4_unicode_520_ci (或utf8mb4_-bin)。