user
に関連するevents
をすべて取得するための、最も単純で効率的なSQLクエリを作成したいと考えています。SQLでネストされたリレーションシップを簡単かつ効率的にクエリする方法はありますか?
注意するカップルの事を:
セットアップ
は、ここに私のスキーマがどのように見えるかの単純化した表現だ
users
はmemberships
経由teams
に属し。teams
は、多くがcollections
,apps
およびwebhooks
であることがあります。collections
もまた、多くのwebhooks
を持つことができます。webhooks
は、team
またはcollection
のいずれかに属することができますが、1つのみです。events
は、任意のオブジェクトに属することができますが、1つだけです。
これは、ほとんどのSaaS型企業(例えば、スラックまたはストライプ)が持つようなかなり基本的な設定のようです。すべてがチームによって「所有」されていますが、ユーザーはチームに属し、インターフェイスとやりとりします。セットアップは、私が解決SQLクエリを作成したいことを考えると
問題
...
が関連しているすべてのイベント(直接的または間接的に)にして下さい指定されたユーザーは
id
です。
直接または特定の手段で間接的に検索されるクエリを簡単に書き込むことができます。たとえば...
は直接
がid
により、ユーザに関連するすべてのイベントを検索します。
SELECT *
FROM events
WHERE user_id = ${id}
それとも...
は間接的自分のチームを介してユーザに関連するイベントのすべてを検索します。
SELECT events.*
FROM events
JOIN memberships ON memberships.team_id = events.team_id
WHERE memberships.user_id = ${id}
たり...
が間接的 が自分のチームのいずれかのコレクションを介してユーザに関連するイベントのすべてを検索します。
SELECT events.*
FROM events
JOIN collections ON collections.id = events.collection_id
JOIN memberships ON memberships.team_id = collections.team_id
WHERE memberships.user_id = ${id}
彼らは2つの異なる方法で関連することができますので、ウェブフックは、より複雑な取得...
は、任意のウェブフックを介してユーザに関連する間接的あるすべてのイベントを探しますそのチームやコレクションの
SELECT *
FROM events
WHERE webhook_id IN (
SELECT webhooks.id
FROM webhooks
JOIN memberships ON memberships.team_id = webhooks.team_id
WHERE memberships.user_id = ${id}
)
OR webhook_id IN (
SELECT webhooks.id
FROM webhooks
JOIN collections ON collections.id = webhooks.collection_id
JOIN memberships ON memberships.team_id = collections.team_id
WHERE memberships.user_id = ${id}
)
しかし、あなたが見ることができるように、これらすべての経路を介して、発生したイベントに関連するユーザーのためのさまざまな方法がたくさんあります!私は成功し、それらに関連するイベントのすべてを取得するクエリにしようとすると、だから、それはのように見てしまい...
SELECT *
FROM events
WHERE user_id = ${id}
OR app_id IN (
SELECT apps.id
FROM apps
JOIN memberships ON memberships.team_id = apps.team_id
WHERE memberships.user_id = ${id}
)
OR collection_id IN (
SELECT collections.id
FROM collections
JOIN memberships ON memberships.team_id = collections.team_id
WHERE memberships.user_id = ${id}
)
OR memberships_id IN (
SELECT id
FROM memberships
WHERE user_id = ${id}
)
OR team_id IN (
SELECT team_id
FROM memberships
WHERE user_id = ${id}
)
OR webhook_id IN (
SELECT webhooks.id
FROM webhooks
JOIN memberships ON memberships.team_id = webhooks.team_id
WHERE memberships.user_id = ${id}
)
OR webhook_id IN (
SELECT webhooks.id
FROM webhooks
JOIN collections ON collections.id = webhooks.collection_id
JOIN memberships ON memberships.team_id = collections.team_id
WHERE memberships.user_id = ${id}
)
質問
- 最終的には非常にクエリを「すべて含まれている」ということです非効率的な?
- もっと効率的な書き方がありますか?
- 後で読むのが簡単で、読みやすい方法がありますか?
ここでは3つの異なるデータベースシステムにタグを付けました。 – DavidG
これは、私の友人のよく書かれた質問です。あなたがすでにそれを解決しようとしているのを見て、あなたが仕事をしていることを示しています。 –