Php 在一个查询中获取行及其外键行与在多个查询中获取行及其外键行相比

Php 在一个查询中获取行及其外键行与在多个查询中获取行及其外键行相比,php,mysql,database,foreign-keys,Php,Mysql,Database,Foreign Keys,假设我有三个表(MySQL),一个用于用户,一个用于标记,最后一个用于连接它们(多对多关系): 我想从数据库中获得一个完整的用户列表(或者至少是其中的许多用户)以及他们关联的标签。为此,我使用PHP作为服务器语言 因此,我的问题是,执行一个SQL查询以获取以下所有信息是否更好: select user.name, user.image, ..., tag.name from user, tag, user_tag where user.user_id = user_tag.user_id

假设我有三个表(MySQL),一个用于用户,一个用于标记,最后一个用于连接它们(多对多关系):

我想从数据库中获得一个完整的用户列表(或者至少是其中的许多用户)以及他们关联的标签。为此,我使用PHP作为服务器语言

因此,我的问题是,执行一个SQL查询以获取以下所有信息是否更好:

select user.name, user.image, ..., tag.name from user, tag, user_tag
   where user.user_id = user_tag.user_id and tag.tag_id = user_tag.tag_id;
还是最好先为用户执行一次查询,然后再获取他们的标记:

select user.name, user.image, ... from user;
然后针对每个用户:

select tag.name from tag, user_tag where tag.tag_id = user_tag.tag_id
   and user_tag.user_id = $USERID;
我觉得第二个是更好的选择,但我担心对数据库的查询太多(请注意,这是一个通用的设计示例,但此模式可以在具有不同表的数据库上多次出现)

哪个更好?利与弊?其他方式

谢谢


PS:请不要考虑SQL语法,我还没有对照真实的数据库进行检查,这只是设计问题,谢谢

这实际上取决于许多特定项目、数据库大小、数据大小、使用情况、并发查询数

我建议您尝试(为了性能)每种方法,并应用最适合您的要求/需求的方法


我会99%的时间使用一个查询-如果你有所有的相关索引,那么发送一个查询要快得多。。。。在编码、服务器响应方面,速度更快,而且更易于阅读—您可以像看到连接一样理解数据库结构—您可以在另一个查询中使用不同的Alise,这可能会让人感到困惑。

没有简单的答案,因为这取决于您的体系结构。最好的方法是在您的体系结构中对这两个解决方案进行基准测试。但是,如果可以在一个查询和多个查询之间进行选择,那么只要表的索引正确,我就选择一个查询解决方案。这样你就可以节省数据库连接和文件读取的开销。

< P>我只考虑两个选项:

  • 一个问题:

    SELECT user.user_id, user.name, user.image, ..., tag.tag_id, tag.name
    FROM user
    LEFT JOIN user_tag ON user.user_id = user_tag.user_id
    LEFT JOIN tag ON user_tag.tag_id=tag.tag_id
    
  • 两个问题:

    SELECT user_id, name, image, ...
    FROM user
    
    SELECT user_tag.user_id, tag.tag_id, tag.name
    FROM user_tag
    INNER JOIN tag ON user_tag.tag_id=tag.tag_id
    
  • 如果您有100个用户,那么发出100次相同的查询是没有意义的

    当我只获取几列时,我通常选择1,否则我选择2。在这种情况下,您似乎正在检索一个相当完整的用户配置文件,因此#2听起来不错。

    更多选项:

    选项3:两个查询。首先获取所有用户:

    select user.name, user.image, ... 
    from user
    ORDER BY user_id;
    
    然后获取所有用户的标签(并在PHP中组合两个查询):

    备选案文4。在一个查询中获取所有内容,每个用户一行:

    SELECT user.name, user.image, ... 
         , GROUP_CONCAT(tag.name ORDER BY tag_name SEPARATOR ' ') AS tags
    FROM user
      LEFT JOIN user_tag
        ON user_tag.user_id = user.user_id 
      LEF JOIN tag 
        ON tag.tag_id = user_tag.tag_id
    GROUP BY user.user_id 
    ORDER BY user.user_id;
    
    可能重复的
    select user_tag.user_id, tag.name 
    from tag
      JOIN user_tag 
        ON tag.tag_id = user_tag.tag_id
    GROUP BY tag.user_id 
    ORDER BY tag.user_id
           , tag.name;
    
    SELECT user.name, user.image, ... 
         , GROUP_CONCAT(tag.name ORDER BY tag_name SEPARATOR ' ') AS tags
    FROM user
      LEFT JOIN user_tag
        ON user_tag.user_id = user.user_id 
      LEF JOIN tag 
        ON tag.tag_id = user_tag.tag_id
    GROUP BY user.user_id 
    ORDER BY user.user_id;