ソーシャルネットワーキングサイトのユーザー間の友情をモデル化するための最良の方法は何ですか?
可能な状態は次のとおりです。
- 友情なし
- AからBへのFriendRequest、Bは確認する必要があります(これは非対称です)
- AとBは友達です(これは対称です)
今ではモデルを正しく選択するのは複雑です。
私の友達は私のプロフィールの一部です
非常に明白なことですが、A.profile.friendsは他のユーザーとの多対多の関係です。
- 友情なし:BはA.friendsになく、AはB.friendsにありません
- AはBとの友情を要求します:A.friendsのB
- 友達:A.friendsのBとB.friendsのA
しかし、友人をfriendrequest関係とマージするのはかなり汚れているようです。このマージがないと、データは冗長になります。これは、「A.friendsのBではなくA.friendsのA」が未定義の状態になるためです。
Friend-Lookup:A.friends.filter(friends__contains = B)#dbレベルでのかなり複雑なルックアップ、コーダーにとって直感的ではない
個別のテーブル
FriendRequestは非常に明白であり、requesterとrequested_userを持つクラスであり、selectも非常に明白です。
フレンドモデルは、フィールドとしてperson1とperson2を持ち、すべてのルックアップで、person1=Aとperson2=Bまたはperson1=Bとperson2=Aのフレンドを選択する必要があるためあまり良くありません。
Friend-Lookup:Friend.objects.filter(person1 = A)union Friend.objects.filter(person2 = A)#uncleanで、2つのセットを結合する必要があります
many2manyテーブルを分離する
もう1つのオプションは、friendsフィールドを持つFriendモデルです。これは、many2manyフィールドであり、正確に2人の人物にリンクします。次に、selectはfriendsフィールドの人物の1人と一致し、モデルを返します。ここで、人物Bは、友達セットからAを差し引くことで抽出できます。しかし、これはやり過ぎです。なぜなら、フレンドオブジェクトに2人以上が関連付けられることはないからです。
Friend-Lookup:Friendship.objects.filter(persons__contains = A)#2つのテーブルを照会します
では、友情関係を保存するための最もクリーンで直感的なソリューションは何だと思いますか?それを行うための一般的なパターンはありますか?