前もって 2 つのこと。まず、私の問題に対する解決策があります。私はそれが良い解決策であるかどうか、そして私がそれを改善できるかどうかについてのガイダンスのためにここにいます. 第二に、私の無知を前もって謝罪したいと思います! 私はサイトを構築しているJavaの男で、SQLを始めたばかりです。私はまだやるべきことがたくさんあるので、ここでガイダンスを探しています。
このクエリを処理する 3 つのテーブルがあります。
- ユーザー - サイト上のすべてのユーザーに関する基本情報
- 友達 - 友達である 2 人のユーザー ID を保持します
- Strides - Strides は、Facebook のウォール ポストのようなものと考えてください。どのユーザーも、ストライドの更新を自分のウォールまたは友達のウォールに投稿できます。
すべてのユーザーの友達を見つけて ID 番号を返す SQL ステートメントは次のようになります。
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
今の私の目標は、Facebook のようなライブ フィードを持つことです。ユーザーがストライドを投稿するたびに、すべての友人に通知されるようにします。したがって、ステップ 1 は、上記で行ったすべてのユーザーの友人を取得することであることがわかりました。そこで、これらの友達をストライド テーブルにリンクさせたいと思います。
ストライド テーブルには、sourceUserId (ストライドを書いた人) と recipientId (ストライドを受け取った人) の列があります。したがって、自分のボードに書き込み、ID が 2 の場合、両方の列で 2 になります。私の目標は、すべてのユーザーの友達、およびそれらの友達が自分のボードと友達のボードで行ったすべての投稿を見つけることができる SQL ステートメントを作成することです。
あまりにも多くのグーグル検索の後、SQL サブクエリについて知り、結果を出しました。問題は、私が新人で、今日これらのことを学んだばかりなので、これが良い結果かどうかわからないことです! 私はスケーラビリティが怖いです.100人、1,000人、または100,000人のユーザーがいると、これがうまくいかない場合! だから私の質問は、
- ここではサブクエリが最適なオプションですか? もしそうなら、私はそれを正しくしましたか?そうでない場合、どうすればこれを修正できますか
- このクエリを高速化するためにインデックスを作成する必要がある列はありますか。
- 今後のクエリを改善する方法について、新しい SQL 担当者に何かアドバイスはありますか
これが私が思いついたコードです!
SELECT * FROM stride WHERE sourceUserId = ANY
(
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
)
AND recipientId = ANY
(
SELECT user.id
FROM user
INNER JOIN friends ON user.id = friends.user2 WHERE friends.user1 = 1
UNION ALL
SELECT user.id FROM user
INNER JOIN friends on user.id = friends.user1 WHERE friends.user2 = 1
)
更新:たくさんの新しい知識により、0.0009 秒のライブ フィードの確実な SQL ステートメントを取得することができました! 興味のある方はこちらから。
SELECT stride.id AS link, sourceUser.userName, sourceUser.displayName, recipientUser.fName AS recipient, sourceUser.currentDefault, stride.content, stride.timestamp,
CASE WHEN (recipientId = sourceUserId) THEN "personalStride" ELSE "friendStride" END AS notType
FROM stride
INNER JOIN user AS sourceUser ON sourceUser.id = stride.sourceUserId
INNER JOIN user AS recipientUser ON recipientUser.id = stride.recipientId
WHERE sourceUserId = ANY
(
SELECT CASE WHEN user1 = 1
THEN user2 ELSE user1 END AS sourceUserId
FROM friends
WHERE user1 = 1 OR user2 = 1
)
AND recipientId = ANY
(
SELECT CASE WHEN user1 = 1
THEN user2 ELSE user1 END AS sourceUserId
FROM friends
WHERE user1 = 1 OR user2 = 1
)
ORDER BY timestamp desc