私は3つの実体をデータベースに持っています。ボード、リスト、カード。彼らは1対1の関係を持っています。ボードにはリストが含まれ、リストにはカードが含まれます。PostgreSQLでネストされたJSONを取得するためのクエリを簡略化する方法はありますか?
ボード:
CREATE TABLE boards(
id serial PRIMARY KEY,
title text NOT NULL
);
CREATE TABLE boards_lists(
board_id integer NOT NULL REFERENCES boards ON DELETE RESTRICT,
list_id integer PRIMARY KEY REFERENCES lists ON DELETE CASCADE
);
リスト:
CREATE TABLE lists(
id serial PRIMARY KEY,
title text NOT NULL
);
CREATE TABLE lists_cards(
list_id integer NOT NULL REFERENCES lists ON DELETE RESTRICT,
card_id integer PRIMARY KEY REFERENCES cards ON DELETE CASCADE
);
カード:例えば
CREATE TABLE cards(
id serial PRIMARY KEY,
text text NOT NULL
);
、Iは2つのルートを持っている:
1. GET /ボードは - ボード、リストやカードで深いネストされたJSONを返す必要があります
[
{
id: 1,
title: 'board 1',
lists: [
{
id: 1,
title: 'list 1',
cards: [
{
id: 1,
text: 'card 1'
}
]
}
]
}
]
2. GET /リスト - 私は上記のように、ボードなしで、同じJSONを返す必要がありますカード付きリストのみ。
だから、DBの中にすべてのリストとカードを入れておく必要があります。私は、このクエリを使用します。
WITH full_lists AS (
SELECT l.*,
COALESCE (json_agg(c) FILTER (WHERE c.id IS NOT NULL), '[]') AS cards
FROM lists AS l
LEFT JOIN lists_cards ON (l.id = list_id)
LEFT JOIN cards AS c ON (c.id = card_id)
GROUP BY l.id
)
SELECT b.*,
COALESCE (json_agg(l) FILTER (WHERE l.id IS NOT NULL), '[]') AS lists
FROM boards AS b
LEFT JOIN boards_lists ON (b.id = board_id)
LEFT JOIN full_lists as l ON (l.id = list_id)
GROUP BY b.id
それは正常に動作しますが、私は、私はボードやリストを取得するための2つの類似SELECTクエリを持っているだけでなく、それは、非常に面倒だと思います。どのように私はそれを簡単にすることができますか?
をなぜあなたがDBの側にそのロジックを実行する必要がありますか?あなたはフィルタリングをしません。すべてのデータをアプリに読み込んで処理できませんか? JSON(一般に生データよりも重い)を送信しないため、コード化/保守と効率化が容易になります。 – freakish
このアクションはDB側で行う必要があると私は考えました。 3つのクエリを(各エンティティごとに)作成し、アプリケーションでデータをマージする方が簡単になるでしょうか? – 1ven
まず第一に、あなたは何もしなくてはなりません。 :)しかし、はい、このアプローチは間違いなく簡単になり、拡張と維持が容易になります。より効率的かもしれませんが、これをベンチマークする必要があります。それは単なる提案です。 SQLを使って作業することは、ほとんどの場合アプリの側で難しく、IMHOはパフォーマンスが要求しない限り避けるべきです。 – freakish