我有这个表:
博客
id
name
user_id // author - relational to "users"
用户
id
nickname
avatar
题目
id
blog_id // relational to "blogs"
user_id // relational to "users"
这个想法是在网站上显示这样的东西:
Blogname
Created By Stack
Suscriptions: Overflow, Easy, Robinson, Porter
我正在从blogs
获取所有数据
SELECT
b.id,
b.name,
b.user_id,
u.nickname as user_nickname,
u.avatar as user_avatar
FROM blogs b
LEFT JOIN users u ON b.user_id = u.id
使用 PHP,我创建了一个包含所有blogs ID
的数组,因此我可以将它们与 IN 运算符一起使用,如下所示:
SELECT
s.id,
s.blog_id,
u.nickname,
u.avatar
FROM suscriptions s
LEFT JOIN users u ON s.user_id = u.id
WHERE s.blog_id IN (1, 2, 3)
然后再次使用 PHP 对结果进行排序。
但是,有没有更好的方法?我正在考虑只使用MySQL,而不是PHP。也许只在一个查询中获取所有数据?或者最好的方法是什么?
重要的是要记住,一个blog
可以有多个subscriptions
。
我发现 2012 年的这个问题有点相似:连接三个表,并为单独列中的每一行聚合多行的数据但是OP说它真的很慢,所以我现在有点迷茫。
我认为您需要的是将"连接说明"生成的所有行分组,并用逗号将它们连接起来以进行演示。
SELECT
b.id AS blog_id,
b.name AS blog_name,
u.nickname AS user_create_nickname,
u.avatar AS user_create_avatar,
GROUP_CONCAT(us.nickname SEPARATOR ', ') AS users_suscritions
FROM blogs b
INNER JOIN users u ON b.user_id = u.id
LEFT JOIN suscriptions s ON s.blog_id = b.id
LEFT JOIN users us ON s.user_id = us.id
GROUP BY b.id;
您可以执行以下两项中的任何一项。几个小查询或一个具有更多联接的大查询或(甚至是子查询)一次获取所有数据。在这两种情况下,您都不会注意到性能的任何差异,直到您获得大量数据。
如果您刚刚开始使用 PHP,我建议您坚持使用更易于调试和理解的较小查询。毕竟,MySQL对于小型快速查询表现良好。
很快,您将转到ORM(或框架),它将为您编写查询。你只需要关注你试图解决的问题的逻辑。
例如,在 CakePHP 中,您只需要执行以下操作:
$blogs = $this->Blog->find('all')
并且给定一个Blog
属于一个User
并且一个User
可以有很多Subscriptions
,所有数据都将被"自动"检索(它将自己为连接表生成SQL,就像Doglas的答案一样)。
所以现在,我建议专注于构建易于理解、调试、优化和维护的小查询。
以下是 PHP 中的 ORM 列表。这些很常见:
- 来自拉拉维尔团队的雄辩。
- 推动
这是来自同一博客的一篇关于ORM的文章;)