2016-09-16 7 views
-1

У меня довольно простые отношения «один ко многим». Есть «узлы», и каждый узел относится к нескольким «опциям». Я делаю довольно простое соединение, и мои результаты, как это:Есть ли более эффективный способ сделать отношения «один ко многим», чем иметь «одно» значение в каждой возвращаемой строке?

  content  | optionid |  content  
--------------------------+----------+------------------ 
This is the node content |  1 | This is option 1 
This is the node content |  2 | This is option 2 

Однако, потому что это один-ко-многим, каждая строка имеет то же содержание узла: This is the node content. Кажется излишним возвращать то же значение с каждой строкой, когда мне это нужно только один раз. Есть ли способ лучше?

+2

Есть довольно много различных агрегатных функций [] (https://www.postgresql.org/docs/9.5/static/functions-aggregate.html) вы могли бы использовать. Например, 'json (b) _object_agg' может работать для вас хорошо, если' optionid' уникален. – Sevanteri

+0

Является ли избыточность причиняющим вам вред? Например, это замедляет вас? –

+0

@Sevanteri Спасибо, что рассказали мне об этом! 'jsonb_object_agg' делает именно то, что я хотел. Если вы опубликуете это в качестве ответа, я соглашусь с ним. – Markasoftware

ответ

2

The jsonb_object_agg aggregate function кажется хорошим выбором для этого.

SELECT 
    n.content, 
    jsonb_object_agg(o.optionid, o.content) 
FROM node n 
JOIN option o ON (
    -- what ever are the conditions 
) 
GROUP BY n.content; 
+0

Я думаю, что json (текстовый формат) предпочтительнее jsonb (двоичный формат), но хороший ответ. – Bohemian

+0

Всё зависит от меня. Если вы всегда будете выбирать весь JSON, тогда да, возможно, лучше использовать JSON вместо JSONB. И да, в этом случае это может быть лучше. – Sevanteri

0

Ну, так работают реляционные базы данных - вам нужно идти на компромиссы.

Если вы считаете, что этот запрос создает слишком большой поток данных между сервером приложений и базой данных, вы можете разбить его на два запроса. Загрузите content отдельно, а затем загрузите options, избегая избыточности. Это может также иметь преимущество в производительности (меньше памяти, нет JOIN и т. Д.).

С другой стороны, у этого есть латентность из-за запуска отдельных запросов. Особенно в зацикленных запросах это может быть заметно медленнее. Итак, все дело в компромиссах.

 Смежные вопросы

  • Нет связанных вопросов^_^