当 MySQL 有一个使用 utf8mb4 字符集的 concat() 从派生表中选择内容时,为什么每个字符使用 4 个字节?

问题描述

从此表开始,带有 utf8mb4_unicode_ci 排序规则:

DROP TABLE IF EXISTS preferences;
CREATE TABLE IF NOT EXISTS preferences
(
    id      int auto_increment primary key,user_id int          not null,title   varchar(150) not null
) collate = utf8mb4_unicode_ci;

使用这些值:

INSERT INTO preferences (user_id,title) VALUES (1,'Preference 1'),(1,'Preference 2'),'Preference 3'),'Preference 4'),'Preference 5');

这个查询

SELECT CONCAT('"',GROUP_CONCAT(p.title SEPARATOR '","'),'"') AS title
FROM preferences AS p
GROUP BY p.user_id

带有 group_concat_max_len=64 结果

标题
“偏好1”、“偏好2”、“偏好3”、“偏好4”、“偏好”

但是在派生表中使用该查询时,如下所示:

SELECT preferences_grouped.title
FROM (
    SELECT CONCAT('"','"') AS title
    FROM preferences AS p
    GROUP BY p.user_id
) as preferences_grouped

你只会得到 16 个字符 (64/4)

标题
"偏好 1","Pr

concat 被移除或移动到主查询时不会发生这种情况:

SELECT CONCAT('"',preferences_grouped.title,'"')
FROM (
    SELECT GROUP_CONCAT(p.title SEPARATOR '","') AS title
    FROM preferences AS p
    GROUP BY p.user_id
) as preferences_grouped;
CONCAT('"','"')
“偏好1”、“偏好2”、“偏好3”、“偏好4”、“偏好”

因此似乎将 concat 与派生表和 utf8mb4 字符集相结合会导致结果集中字符的字节数增加四倍,这意味着我的 group_concat_max_len 真的应该增加四倍

  1. 这是为什么?
  2. 我可以使用 COLLATE 来解决此问题/更改此行为吗?

注意:当 preferences 表具有非 utf8mb4 字符集时,如默认的 latin1_swedish_ci 排序规则,那么也不会进行字节四倍处理。

检查这里的小提琴:https://www.db-fiddle.com/f/hQD6r3pE5pmgR3n2XA7VtX/5

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)