【问题标题】:Best practice to select data from many postgres tables从许多 postgres 表中选择数据的最佳实践
【发布时间】:2017-08-13 23:22:00
【问题描述】:

我有包含以下表格的电影数据库:

电影

 mid |  title     
-----+---------
  9  | Jason X

演员

mid |   name 
----+------------
 9  | Kane Hodder
 9  | Lexa Doig

我的问题是从所有表中获取与特定电影相关的所有数据的最佳做法是什么,我认为在一个 sql 查询中获取数据是理想的,因此我不必为每个表对 db 进行多次查询.

当我尝试在一个查询中获取所有内容时,我得到了重复的数据,例如,我在每一行都得到 titlemid,而它只需要一次:

 mid | title   | name 
---------------+------------
  9  | Jason X | Kane Hodder
  9  | Jason X | Lexa Doig

webapp 会将 Postgres 输出转换为哈希,例如:

电影 => {mid => 9, 标题 => 'Jason X', 演员 => ['Kane Hodger', 'Lexa doig']}

使用当前的 postgres 输出,我得到重复的数据,例如 $movie{title} 等于 ['Jason X', 'Jason X'],仅需要 强>'杰森 X'

【问题讨论】:

  • 这是可能的,但你不应该这样。你应该在你的业务逻辑中处理它。
  • @JakubKania 所以你会建议在一个查询中获取所有数据(带有重复数据)并在业务逻辑中解析它?或者通过多个查询获取数据,查询每个表并在逻辑中组合它们?我更关心如何做到这一点,寻找一个好的做法。

标签: postgresql web-development-server


【解决方案1】:

您可以使用JSONB type:

select to_jsonb(m) || jsonb_build_object('actors', jsonb_agg(a.name)) as movies
from movies m
join actors a using(mid)
group by mid;

                                 movies                                 
------------------------------------------------------------------------
 {"mid": 9, "title": "Jason X", "actors": ["Kane Hodder", "Lexa Doig"]}
(1 row)

另见:

关于 SO 的最佳实践问题有点冒险,因为它可能被认为过于宽泛或基于意见。这在很大程度上取决于数据的大小。在大多数返回行数有限的简单情况下,使用 json 非常方便。您还可以使用其他聚合函数,例如string_agg ():

select m.*, string_agg(a.name, ',') as actors
from movies m
join actors a using(mid)
group by mid;

 mid |  title  |        actors         
-----+---------+-----------------------
   9 | Jason X | Kane Hodder,Lexa Doig
(1 row) 

如果应用程序一次处理的行数较大(例如几十万),那么更有效的解决方案可能是在客户端使用多个查询和数据处理。

【讨论】:

  • klin:感谢您的帮助,我将尝试使用 JSON 和聚合函数,并将报告它对我的工作方式。
  • 感谢 klin,我现在看不到使用 jsonb 类型的任何好处(将来可能需要)... array_agg 函数完全符合我的需要,并且我使用的编程语言很好地处理了 postgres 数组类型所以用了array_agg(演员)
猜你喜欢
  • 2010-11-28
  • 2020-02-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
相关资源
最近更新 更多