从具有多行的关系表中获取数据


Get data from relational table with multiple rows

我有这个表:

博客

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 列表。这些很常见:

  1. 来自拉拉维尔团队的雄辩。
  2. 推动

这是来自同一博客的一篇关于ORM的文章;)