【问题标题】:Most efficient way to query one to many to many table relationship查询一对多对多表关系的最有效方法
【发布时间】:2011-11-05 16:22:52
【问题描述】:

我有 3 个描述游戏的 MySQL 表:

  1. gamelist {gameId, ... with Primary(gameId) } = 存储有关每个游戏会话的信息。
  2. userlist {userId, ... with Primary(userId) } = 存储每个用户的信息。
  3. game2user {gameId, userId ... with Primary(gameId, userId) } = 存储参与每个游戏会话的用户(两个或更多用户的一个游戏会话)。

现在,对于某个 userId,我需要检索一个游戏列表,其中包含参与该游戏会话的所有用户的名称。

到目前为止我得出的最好的结果是:

SELECT gl.gameid, gl.type, [...], ul.userid, ul.username
FROM userlist as ul, gamelist as gl, game2users as g2u
WHERE g2u.userid = a_certain_numeric_id AND
      ul.userid = g2u.userid AND
      gl.gameid = g2u.gameid`

这会从游戏列表中检索唯一的行,但它只获取给定用户的用户名,而不是他的合作者。

问题是我怎样才能在性能(时间)方面有效地做到这一点,最好不做单独的查询?谢谢。

【问题讨论】:

  • 你有表结构吗?

标签: mysql sql select join


【解决方案1】:
SELECT gl.gameid, gl.type, [...], ul.userid, ul.username
FROM userlist as ul, gamelist as gl, game2users as g2u
WHERE ul.userid = g2u.userid AND
      g2u.gameid IN (SELECT gameid
                     FROM game2users
                     WHERE userid = a_certain_numeric_id);

这实质上是查找涉及给定用户的所有游戏(在子查询中),然后选择也参与该游戏的所有用户。

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT gl.gameid, gl.type, ..., ul.userid, ul.username
    FROM
        (
            SELECT gameid
            FROM game2users
            WHERE userid = a_certain_numeric_id
        ) AS ug
        INNER JOIN gamelist AS gl
            ON ug.gameid = gl.gameid
        INNER JOIN game2users AS g2u
            ON ug.gameid = g2u.gameid
        INNER JOIN userlist AS ul
            ON g2u.userid = ul.userid
    

    【讨论】:

    • 这是最接近我想要的。我得到每个游戏组合的行,这几乎是我需要的。有没有办法为每个游戏会话获取所有用户名减去当前用户名的单行?
    • 我解决的代码是这样的:SELECT g.*, u.username FROM gamelist g inner join game2users gu on gu.gameid = g.gameid inner join game2users gu2 on gu2.gameid = gu.gameid and gu2.userid = the_constant inner join userlist u on u.userid = gu.userid order by g.gameid, u.userid
    【解决方案3】:

    表和关系的完整架构将帮助我们为您提供帮助。

    我不是 MySQL 方面的专家,但似乎使用不同的数据库实现可能会更好(如果可以更改的话)。现在你在 games2user 表中有多余的记录。我认为最简单的方法是为用户表提供一个包含他们参与的游戏的属性。然后,当您对这个问题进行查询时,您只需查询用户参与的特定游戏的 gamesTable 并检索该游戏中涉及的所有用户 ID。

    【讨论】:

    • 架构是正确的,并且是在关系数据库中处理多对多关系的标准方法。 (即一个游戏可以有许多参与者/用户,并且一个用户可以是许多游戏的参与者)。按照您的建议,您将限制用户一次最多参与一个游戏,这在这种情况下是不希望的。 -1.
    猜你喜欢
    • 2020-05-15
    • 2011-12-17
    • 2020-09-02
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    • 2018-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多