MySQL 截断 GROUP_CONCAT 函数的连接结果
Posted
技术标签:
【中文标题】MySQL 截断 GROUP_CONCAT 函数的连接结果【英文标题】:MySQL truncates concatenated result of a GROUP_CONCAT function 【发布时间】:2015-06-14 00:45:49 【问题描述】:我创建了一个视图,它使用GROUP_CONCAT
将数据类型为'varchar(7) utf8_general_ci'
的产品列的查询结果连接到名为concat_products
的列中。
问题是 mysql 截断了“concat_products”列的值。
phpMyAdmin 说“concat_products”列的数据类型是varchar(341) utf8_bin
餐桌产品:
CREATE TABLE `products`(
`productId` tinyint(2) unsigned NOT NULL AUTO_INCREMENT,
`product` varchar(7) COLLATE utf8_general_ci NOT NULL,
`price` mediumint(5) unsigned NOT NULL,
PRIMARY KEY (`productId`)
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci
“concat_products_vw”视图:
CREATE VIEW concat_products_vw AS
SELECT
`userId`,
GROUP_CONCAT(CONCAT_WS('_', `product`, `productId`, `price`)
ORDER BY `productId` ASC SEPARATOR '*') AS concat_products
FROM
`users`
LEFT JOIN `products`
ON `users`.`accountBalance` >= `product`.`price`
GROUP BY `productId`
根据 MySQL 手册:
VARCHAR 列中的值是可变长度字符串 在 MySQL 4.0.2 之前,长度可以指定为 1 到 255 之间的值,在 MySQL 4.0.2 之前可以指定为 0 到 255。
编辑
Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535.
为什么 MySQL 为 varchar
"concat_products" 列指定超过 255 个字符? (已解决!)
为什么是uf8_bin
而不是utf8_general_ci
?
是否可以将视图中列的数据类型更改为“concat_products”列的文本?
如果不能,我该怎么做才能防止 MySQL 截断“concat_products”列?
【问题讨论】:
你用的是什么版本的 MySQL? 仔细检查您的来源。 MySQL manual 说:VARCHAR 列中的值是可变长度字符串。长度可以指定为 0 到 65,535 之间的值。 @Jocelyn 你是对的,如果 mysql 可以在 varchar 列中存储多达 65535 个字符,为什么还要在这里截断? 【参考方案1】:正如我在之前的评论中所写,MySQL manual 说:
VARCHAR 列中的值是可变长度字符串。长度可以 指定为 0 到 65,535 之间的值。
所以问题不在于字段的数据类型。
MySQL manual 还说:
结果被截断为由 group_concat_max_len 系统变量,默认值为 1024.该值可以设置得更高,虽然返回值的有效最大长度受值的限制 最大允许数据包。改变值的语法 运行时的 group_concat_max_len 如下,其中 val 是 无符号整数: 设置 [全球 |会话] group_concat_max_len = val;
您更改 group_concat_max_len 值的选项是:
-
在 MySQL 启动时通过将其附加到以下命令来更改值:
--group_concat_max_len=your_value_here
在您的 MySQL 配置文件 (mysql.ini) 中添加这一行:group_concat_max_len=your_value_here
在 MySQL 启动后运行此命令:SET GLOBAL group_concat_max_len=your_value_here;
打开 MySQL 连接后运行此命令:SET SESSION group_concat_max_len=your_value_here;
文档:SET、Server System Variables: group_concat_max_len
【讨论】:
感谢 mysql 不再截断 concat_products 列 我个人使用我列出的第 4 个选项,因为我的脚本中只有少数需要计算“大”GROUP_CONCAT,而且这些脚本并不经常运行。【参考方案2】:正如 Jocelyn 提到的,GROUP_CONCAT()
结果的大小受group_concat_max_len
的限制,但是与ORDER BY
的额外交互导致进一步截断为group_concat_max_len
的1/3。示例见this related answer。
group_concat_max_len
的默认值为 1024,而 1024 / 3 = 341 可能解释了为什么 concat_products 的类型在原始示例中显示为 varchar(341)
。如果您要删除 GROUP BY productId
子句,concat_products 应该显示为 varchar(1024)
。
我没有发现MySQL Manual中提到的GROUP_CONCAT()
和ORDER BY
之间的这种交互,但它至少会影响MySQL Server 5.1。
【讨论】:
以上是关于MySQL 截断 GROUP_CONCAT 函数的连接结果的主要内容,如果未能解决你的问题,请参考以下文章