9

ソーシャルネットワーキングサイトのユーザー間の友情をモデル化するための最良の方法は何ですか?

可能な状態は次のとおりです。

  • 友情なし
  • 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つのテーブルを照会します

では、友情関係を保存するための最もクリーンで直感的なソリューションは何だと思いますか?それを行うための一般的なパターンはありますか?

4

3 に答える 3

2

これらすべての友情関係を再実装したくない場合は、次のモジュールを使用できます:https ://github.com/revsys/django-friendship

その動作は、3番目のオプションで説明するものです。個別のManyToManyテーブルを作成します。友情リクエスト用の1つ:

class FriendshipRequest(models.Model):
    """ Model to represent friendship requests """
    from_user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='friendship_requests_sent')
    to_user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='friendship_requests_received')

友情ステータスのもう1つ:

class Friend(models.Model):
    """ Model to represent Friendships """
    to_user = models.ForeignKey(AUTH_USER_MODEL, models.CASCADE, related_name='friends')
    from_user = models.ForeignKey(AUTH_USER_MODEL, models.CASCADE, related_name='_unused_friend_relation')

また、フォロー、ブロック、および関連するマネージャーも提供します。

于 2018-10-21T13:02:49.207 に答える
1

これは、Djangoでサポートされている拡張された多対多関係のユースケースだと思います:https ://docs.djangoproject.com/en/dev/topics/db/models/#intermediary-manytomany

これらのユーザー間の接続を保存するだけでなく、追加のプロパティを保存することもできます。これにより、問題のドメインがDBモデルにうまく投影されるはずです。つまり、2人のうちの1人が友情を開始するとすぐに接続を作成し、追加のフィールドを設定して、誰が誰を尋ねているか、他の人が友情を受け入れたかどうかを保存します。

于 2011-12-25T20:36:08.083 に答える
0

SQLデータベースの場合、これには多対多の関係を使用します。しかし、多くのユーザーがいると思われる場合は、この種のデータ用に特別に設計されたflock-dbのようなグラフデータベースを検討することをお勧めします。

http://en.wikipedia.org/wiki/Graph_database

(SQLデータベースに通常のデータを保持し、グラフデータベースに関係を保持します)

于 2011-12-25T20:32:29.313 に答える