【问题标题】:Is there a better way I can structure my tables, do a 4 table join, or will I have to perform multiple queries?有没有更好的方法可以构建我的表,进行 4 表连接,或者我必须执行多个查询?
【发布时间】:2019-11-23 19:02:29
【问题描述】:

执行此 GET 请求的正确方法是什么?我目前有 4 张桌子:

事件、event_cmets、event_photos、event_users_going

最后 3 个表 event_cmets、event_photos 和 event_users_going 都有一个使用 events 表主键的外键。

我不确定的是,我是否必须对所有 4 个表或 4 个单独的查询进行 JOIN?因为,每个表上的每个查询都返回不同数量的行。

例如,第一个查询将针对事件:

SELECT * FROM events where e_id = 1

这将返回 1 行。

第二次查询:

SELECT * FROM event_photos where e_id = 1

这将返回 12 行

第三次查询:

SELECT * FROM event_comments WHERE e_id = 1

这将返回 20 行

第四次查询:

SELECT * FROM event_users_going WHERE e_id = 1

这将返回 30 行

【问题讨论】:

  • 四个查询可能是最好的方法,因为每个查询返回不同的列和不同的行数。
  • 您真正想要的结果是什么?请提供样本数据和预期结果。
  • The last 3 tables, event_comments, event_photos, and event_users_going all have a foreign key that uses events table's primary key. 请使用 DDL,而不是文本来解释您的表结构。

标签: sql postgresql


【解决方案1】:

这取决于收到的结果。如果它可以处理 JSON 并且这样做的开销不会破坏交易,您可以执行以下操作以将相关行包含为 JSON 数组:

SELECT *,
       COALESCE((
         SELECT json_agg(event_photos)
           FROM event_photos
          WHERE event_photos.e_id = events.e_id
       ), '[]') AS photos,
       COALESCE((
         SELECT json_agg(event_comments)
           FROM event_comments
          WHERE event_comments.e_id = events.e_id
       ), '[]') AS comments,
       COALESCE((
         SELECT json_agg(event_users_going)
           FROM event_users_going
          WHERE event_users_going.e_id = events.e_id
       ), '[]') AS going
  FROM events
 WHERE e_id = 1;

样本输出:

 e_id |          photos          |        comments         | going 
------+--------------------------+-------------------------+-------
    1 | [{"e_id":1,"url":"p1"}, +| [{"e_id":1,"txt":"c1"}] | []
      |  {"e_id":1,"url":"p2"}]  |                         | 
(1 row)

返回 JSON 时,您可以更进一步,用单列构建结果:

SELECT json_build_object(
         'event', events,
         'photos', COALESCE((
           SELECT json_agg(event_photos)
             FROM event_photos
            WHERE event_photos.e_id = events.e_id
         ), '[]'),
         'comments', COALESCE((
           SELECT json_agg(event_comments)
             FROM event_comments
            WHERE event_comments.e_id = events.e_id
         ), '[]'),
         'going', COALESCE((
           SELECT json_agg(event_users_going)
             FROM event_users_going
            WHERE event_users_going.e_id = events.e_id
         ), '[]')
       )
  FROM events
 WHERE e_id = 1;

样本输出:

                              json_build_object                               
------------------------------------------------------------------------------
 {"event" : {"e_id":1}, "photos" : [{"e_id":1,"url":"p1"},                   +
  {"e_id":1,"url":"p2"}], "comments" : [{"e_id":1,"txt":"c1"}], "going" : []}
(1 row)

【讨论】:

  • Postgres 是关系数据库 -> 规范化表上的连接将比 json 类型的操作快得多(10 倍甚至更多)。仅在必要时才应使用非原子类型 - 由于低结构化数据没有可能的规范化。在简单的情况下,它只能用于学习原因。
  • 同意。表格应保持标准化。像这样构建 JSON 会增加数据库服务器上的 CPU 负载和内存使用率。
【解决方案2】:

联接成本高昂,并且可能导致冗余数据,并且总行数远大于上述 4 个查询获得的实际行数总和。

因此,您必须使用这 4 个单独的查询,因为它们还包含您上面已经提到的不同数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    • 1970-01-01
    相关资源
    最近更新 更多