来自多个 LEFT JOIN 的巨大结果集的替代方案

Alternative To Huge Result Set From Multiple LEFT JOINs

我正在寻求一些关于处理当您 LEFT JOIN 多个 table 时结果集中的行数激增的情况的建议。我知道这是预期的行为,但我想知道推荐的处理方式。我知道我可以让我的应用程序执行多个查询以减少总体返回的行数,但我正在尝试看看是否有办法让 SQL 完成大部分繁重的工作并且仍然只进行一个“回合”旅行”(例如,a la this answer)。

例子

这是我的 SQL:

SELECT al.title albumTitle
    , releaseDate
    , name artistName
    , duration
    , t.title trackTitle
    , styleName
FROM album al
LEFT JOIN lu_albumartist aa ON aa.albumId = al.albumId
LEFT JOIN artist ar ON ar.artistId = aa.artistId
LEFT JOIN track t ON t.albumId = al.albumId
LEFT JOIN lu_albumstyle ast ON ast.albumId = al.albumId
LEFT JOIN style s ON s.styleId = ast.styleId
WHERE al.title LIKE '%A Love Supreme%'

这个SQL Fiddle有助于证明问题:

我正在检索有关音乐专辑的信息。 我真的只需要 11 行 就可以让我的应用填充所有字段(1 张专辑、4 位艺术家、3 首曲目、3 种风格),但是查询返回36 行。我将无法使用大多数行;例如,我不关心风格和艺术家或风格和曲目的所有排列。当我为其他事物(例如,乐器、格式、评论、曲目播放信息等)添加更多 LEFT JOINS 时,排列的数量可以扩展到 10,000s!

理想情况下,我想要一个更简洁的结果集:

超级紧凑:4 行(用这种方式读取 table 没有多大意义,尽管应用程序可以解析它)

|          title |                releaseDate |           name |    duration |                                  title |   styleName |
|----------------|----------------------------|----------------|-------------|----------------------------------------|-------------|
| A Love Supreme |                       1965 |  John Coltrane |         479 |               Part I - Acknowledgement |   Free Jazz |
|    [something] |                [something] |    McCoy Tyner |         435 |                   Part II - Resolution |    Hard Bop |
|    [something] |                [something] | Jimmy Garrison |        1060 | Part III - Pursuance / Part IV - Psalm |       Modal |
|    [something] |                [something] |    Elvin Jones | [something] |                            [something] | [something] |

...[something]" 只是表示值可以是任何东西;该应用程序不会关心

紧凑:11 行(对人类有意义)

|          title |                releaseDate |           name | duration |                                  title | styleName |
|----------------|----------------------------|----------------|----------|----------------------------------------|-----------|
| A Love Supreme |                       1965 |                |          |                                        |           |
|                |                            |  John Coltrane |          |                                        |           |
|                |                            |    McCoy Tyner |          |                                        |           |
|                |                            | Jimmy Garrison |          |                                        |           |
|                |                            |    Elvin Jones |          |                                        |           |
|                |                            |                |      479 |               Part I - Acknowledgement |           |
|                |                            |                |      435 |                   Part II - Resolution |           |
|                |                            |                |     1060 | Part III - Pursuance / Part IV - Psalm |           |
|                |                            |                |          |                                        | Free Jazz |
|                |                            |                |          |                                        | Hard Bop  |
|                |                            |                |          |                                        |     Modal |

与应用程序的代码可移植性、可读性和可扩展性相比,我更关心性能。

基于那个 earlier linked question,其他答案和评论建议我不应该尝试加入超过 3 tables。

  1. 我应该放弃这种方法吗?如果我要使用多个查询,可能会有十几个或更多。
  2. 我怀疑有一种方法可以使用 UNION ALL 来解决这个问题,但这是最佳实践吗?
  3. 我猜这是一个相对常见的问题,但我找不到好的答案或一套可遵循的准则。对于这种情况,推荐的方法是什么?

我可以告诉你第一种方法我会怎么做。

我会使用多个查询,但不是对每件事一个查询,而是对多个相关事物进行一个查询。就像您在查询中所做的那样。但我可能会删除曲目,然后使用此查询进行专辑搜索(如 discogs 以及其他提到的网站)。

如果用户随后选择了一张相册,我会在一个查询中加载多个其他相关内容。就像在一个查询中带有曲目播放信息的曲目,在另一种查询格式和乐器中等等。所以我会把相关的东西放在一起,实际上就像我会把它分组在 ui.

一如既往,我会尽可能简单。并考虑用户在一页上需要多少信息。有些东西可以懒加载,如果用户主动想看的话。

我认为不要加入超过 3 个表的建议是笼统的。想一想一对一或多对一的关系,最多返回一条记录,并且记录的数量不会越来越大。