1

ユーザーが他のユーザーをフィーンドとして追加できるように、Web アプリに「友達を追加」を実装しています。

tbl_userstbl_relationsの2 つのテーブルがあります。tbl_users には登録ユーザーの一意の ID があり、tbl_relations には友人であるユーザーが格納されます。たとえば、tbl_relations のいくつかの行は次のとおりです。

id     user_id_1     user_id_2
1      4             6
2      4             8
3      8             23
4      12            84
5      3             4
...

上記の結果では、id は tbl_relations の一意の ID であり、user_id_1 は tbl_users の外部キーであり、user_id_2 は tbl_users の外部キーです。ID「4」のユーザーが ID のユーザーと友達であるかどうかを照会して確認したいとします。 「9」かどうか、ここでは 2 つの方法でクエリを送信する必要があります。

SELECT * FROM tbl_relations WHERE (user_id_1 = '4' AND user_id_2 = '9') OR (user_id_1 = '9' AND user_id_2 = '4')

上記のクエリは私には少し奇妙に思えます。これを実装する別の方法があるはずです。おそらく別のデータベース構造でしょうか?

または別のクエリ、ID「4」と「8」のユーザー間の相互の友達を取得したいのですが、このシナリオで相互の友達を取得するにはどうすればよいですか? これに適したデータベース構造はありますか?

あらゆる種類の助けをいただければ幸いです。

4

2 に答える 2

2

対称になるように関係を非正規化します。つまり、1と2が友達の場合、2つの行(1,2)と(2,1)があります。

欠点は、サイズが2倍になることです。友情を築いたり壊したりするときは、2回の書き込みを行う必要があります。利点は、すべての読み取りクエリが簡単になることです。ほとんどの場合、書き込みではなく読み取りを行うため、これはおそらく適切なトレードオフです。

これには、最終的に1つのデータベースを超えてユーザーシャーディングを実行することにした場合に、他のすべてのデータベースシャードをトラバースして人の友達を見つける必要がないという追加の利点があります。

于 2012-12-18T12:45:10.267 に答える
1

このようにすると、更新するたびに重複をチェックする必要があります。持ってみませんか

user_id1 friend_id

次に、次のようにクエリします

select * from tbl_relations where user_id1 in(4,9)

これは、「友達」の関係が一方向であることを意味するという点で、まだ奇妙に思えます。

「相互の」友達を獲得するには-このようにすると-

select * from tbl_relations t0
join tbl_relations t1 on t0.friend_id = t1.friend_id
where t0.user_id1 =?およびt1.user_id1=?

于 2012-12-18T12:45:44.527 に答える