【问题标题】:Advice on Optimizing Joins Query优化连接查询的建议
【发布时间】:2013-06-03 17:25:31
【问题描述】:

我有 3 张桌子:videoscategoriesvideo_categories

videos,我有id、title等字段。 在categories,我有 id 和 name。 在video_categories,我有id、video_id和category_id。

一个视频可以有多个类别。所以 video_categories 表会是这样的。

id   video_id  category_id
1    1         1
2    1         2
3    1         3

如果我想要一个视频列表并显示它们的类别,那会是首选?

  1. 通过 PHP,调用 1 个查询以获取所有视频,然后循环查询以获取每个视频的类别,并通过另一个查询获取类别名称。如果表很大,这会很慢,对吧?

  2. 通过 MySQL 连接(在这方面需要帮助)。如果我将加入视频留给 video_categories,将有 3 个相同 video_id 的结果。我可以使用 GROUP BY 或 SELECT DISTINCT 来获得唯一的结果,但我现在如何获得类别的名称?

我的预期结果是这样的:

id title    categories
1  Video1   pop, rock, jazz

【问题讨论】:

  • 我认为您的问题本身与非规范化无关。正如您所描述的,您的架构是完全标准化的,这意味着它没有冗余数据。您可以通过将categories 列添加到videos 表来对其进行非规范化,您将在其中存储以逗号分隔的类别名称字符串(例如“流行音乐、摇滚乐、爵士乐”),然后使其与冗余的保持同步categoriesvideo_categories 表中的数据。就目前而言,您的问题实际上只是询问优化您的连接技术,正如其他人所指出的,这可以使用 group_concat 方法完成。
  • 是的,我很困惑。我一定认为非规范化是规范化的逆过程,即读取和显示规范化的模式。我已经编辑了标题以避免混淆

标签: php mysql codeigniter


【解决方案1】:

对于选项 2,请使用 GROUP_CONCAT。会好的

SELECT v.id, v.title, GROUP_CONCAT(c.name)
FROM videos v
INNER JOIN video_categories vc ON vc.video_id = v.id
INNER JOIN categories c ON vc.category_id = c.id
GROUP BY v.id, v.title

对于Group_Concat() 函数, 是默认分隔符。这就是为什么我不在这里使用它。

【讨论】:

  • 从来不知道 GROUP_CONCAT。谢谢!
  • 不客气。当我第一次听说这个功能时,同样的事情发生在我身上。非常有用的功能。
  • GROUP_CONCAT 会在将太多结果组合在一起后将您切断。我没有看到它在这里发生,但我已经让它在第 200 个分组结果之后停止连接。
  • @PatrickM:你可以将group_concat的长度增加SET [GLOBAL | SESSION] group_concat_max_len = val;dev.mysql.com/doc/refman/5.0/en/…
【解决方案2】:

猜测你的其他列的名称..

SELECT v.video_id, v.title, GROUP_CONCAT(c.category_name SEPARATOR ', ')
FROM videos v
LEFT JOIN video_categories vc ON vc.video_id = v.video_id
LEFT JOIN categories c ON c.category_id = vc.category_id
GROUP BY v.video_id, v.title

【讨论】:

  • 次要 - 它是分隔符,SEPARATOR 之前不应有逗号:GROUP_CONCAT(c.category_name SEPARATOR ', ')
  • @EdGibbs 谢谢,正在输入记忆。
  • @MachoPaay 选择加入和分组是正常的 CI 活动记录。对于组 concat one,$this->db->select('GROUP_CONCAT(c.name SEPARATOR ", ") as categories', false);。 c 是我的类别表的别名
猜你喜欢
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
  • 2020-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多