我正在寻找编写最简单,最有效的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
这是一个写得很好的问题,我的朋友,我可以看到你已经试图自己解决它,表明你已经投入了工作。 –