微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 不使用GROUP_CONCAT的原因?

我刚刚发现了这个非常有用的MySQL函数GROUP_CONCAT.对我来说它看起来非常有用且过于简单,我实际上害怕使用它.主要是因为自从我开始进行网络编程以来已经有一段时间了,我从未在任何地方看过它.令人敬畏的用法示例如下

表客户端拥有客户端(您不会说…)每个客户端有一行具有唯一ID.
表货币有3列client_id,货币和金额.

现在,如果我想从客户端表和他的余额中获取用户15的名称,使用“旧”数组覆盖方法,我将不得不使用以下sql

SELECT id, name, currency, amount 
FROM clients LEFT JOIN currencies ON clients.id = client_id 
WHERE clients.id = 15

然后在PHP中我将不得不循环遍历结果集并进行数组覆盖(我真的不喜欢它,特别是在大规模结果集中)

$result = array();
foreach($stmt->fetchAll() as $row){
    $result[$row['id']]['name'] = $row['name'];
    $result[$row['id']]['currencies'][$row['currency']] = $row['amount'];
}

然而,通过新发现的功能,我可以使用它

SELECT id, name, GROUP_CONCAT(currency) as currencies GROUP_CONCAT(amount) as amounts 
FROM clients LEFT JOIN currencies ON clients.id = client_id 
WHERE clients.id = 15
GROUP BY clients.id

然后在应用程序级别,事情是如此可怕和漂亮

$results = $stmt->fetchAll();
foreach($results as $k => $v){
    $results[$k]['currencies'] = array_combine(explode(',', $v['currencies']), explode(',', $v['amounts']));
}

我想问的问题是在演奏中使用这个功能有什么缺点或任何东西,因为对我来说它看起来像纯粹的真棒,这让我觉得必须有人不使用它的理由经常.

编辑:

我想最后问一下,除了数组覆盖之外还有哪些其他选项最终会得到一个来自MysqL结果集的多维数组,因为如果我选择了15个列,那么写这个野兽真的很痛苦.

解决方法:

>使用GROUP_CONCAT()通常会调用分组逻辑并创建临时表,这通常会对性能产生很大的负面影响.有时您可以添加正确的索引以避免分组查询中的临时表,但不是在所有情况下都是如此.
>正如@marcB指出的那样,组连接字符串的认长度限制非常短,很多人都被截断列表搞糊涂了.您可以使用group_concat_max_len增加限制.
>在PHP中将字符串爆炸成数组并不是免费的.仅仅因为你可以在PHP中的一个函数调用中执行它并不意味着它对性能最好.我没有对差异进行基准测试,但我怀疑你是否也有.
> GROUP_CONCAT()是一个MysqLism.其他sql产品不支持它.在某些情况下(例如sqlite),它们具有GROUP_CONCAT()函数,但它与MysqL中的工作方式完全不同,因此如果必须支持多个RDBMS后端,这可能会导致混乱的错误.当然,如果您不需要担心移植,这不是问题.
>如果要从货币表中获取多个列,则需要多个GROUP_CONCAT()表达式.这些清单是否保证是相同的顺序?也就是说,一个列表中的第三个字段是否与下一个列表中的第三个字段相对应?答案是否定的 – 除非您在GROUP_CONCAT()中使用ORDER BY子句指定订单.

我通常喜欢你的第一个代码格式,使用传统的结果集,并循环结果,保存到由客户端ID索引的新数组,将货币附加到数组.这是一个简单的解决方案,使sql更简单,更容易优化,并且如果您有多个要提取的列,则效果会更好.

我不是说GROUP_CONCAT()不好!在许多情况下它确实很有用.但是,尝试使用(或避免)任何功能或语言功能的任何一刀切的规则都是过于简单化.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐