我正在尋找編寫最簡單,最有效的SQL查詢來檢索與給定的user
相關的所有events
。如何簡單高效地查詢SQL中的嵌套關系?
設置
這裏是什麼我的架構看起來像一個簡單的表示:
幾件事情要注意:
users
通過memberships
屬於teams
。teams
可以有許多collections
,apps
和webhooks
。collections
也可以有很多webhooks
。webhooks
可以屬於team
或collection
,但只有一個。events
可以屬於任何對象,但只有一個。
這似乎是大多數SaaS類型公司都會擁有的基本設置(例如Slack或Stripe)。一切都由團隊「擁有」,但用戶屬於團隊並與界面交互。
問題
鑑於設置,我想創建一個解決一個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}
網絡掛接得到一個更復雜的,因爲他們可以在兩種不同的方式有關......
找出所有通過任何網絡掛接與用戶間接事件他們的團隊或收藏。
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
這是一個寫得很好的問題,我的朋友,我可以看到你已經試圖自己解決它,表明你已經投入了工作。 –