39

あるユーザーが別のユーザーの友達であることを示すデータ モデルを設計しようとしています。これは私がこれまでに思いついたものですが、不格好に思えます。より良い解決策はありますか?

User
=====
Id
Name
etc...

UserFriend
===========
UserId
FriendId
IsMutual
IsBlocked
4

14 に答える 14

64
UserRelationship
====
RelatingUserID
RelatedUserID
Type[friend, block, etc]

相互関係は列として属していないことに同意します。正規化を破ります。

于 2008-12-18T21:04:15.017 に答える
57

2 人のユーザーごとに1 つのレコードを使用し、提案された方法が示唆する余分なメモリを消費しないようにするには (ユーザーごとに 2 つのレコードがあるため、必要な量の 2 倍)、次のようにします。

  1. テーブル構造:

    USER_RELATIONSHIP {
        user_first_id,
        user_second_id,
        type
    
        primary key(user_first_id, user_second_id)
    }
    
  2. 確認:user_first_id < user_second_id

  3. 最も興味深い部分 -関係の可能typeすべての状態について、対応する値を作成します。例:

    pending_first_second
    pending_second_first
    friends
    block_first_second
    block_second_first
    block_both
    

あなたが持っているもの:

  1. user_first_id < user_second_id、2 人の特定のユーザー間の関係のレコードが 1 つだけであることを保証します。これは、この制約と主キーの制約により、それ以外の場所に配置することが許可されないためです。
  2. 関係の状態を適切に切り替えることで、2 人のユーザーが互いにどのように関係しているかを判断できます。2 人のユーザー間に関係がない場合、記録はありません。
  3. 2 人のユーザー間の関係 (および更新) を調べるには、次の 1 つのクエリを実行するだけです。

    select * from USER_RELATIONSHIP where
        user_first_id = user1_id and
        user_second_id = user2_id;
    

    orこの列を逆にチェックするステートメントがないため、高速です。

シナリオ例:

  1. no record: 関係がない

  2. pending_first_second: 1 人目が 2 人目に友達リクエストをした

  3. friends: 2 番目が友達リクエストを承認しました

  4. no record: ユーザーの 1 人が他のユーザーを自分のファイアーエンドから削除しました

このソリューションは、1 つのレコードのみを作成、保存、および更新するため、メモリと速度の両方の点で効率的です。

于 2015-07-10T22:52:43.630 に答える
8

私は現在、クライアント向けのソーシャルネットワーキングサイトを構築しており、このように表現しました

CREATE TABLE [dbo].[PersonFriend] (
    [Id]                          INT            IDENTITY (1, 1) NOT NULL,
    [Timestamp]                   DATETIME       NOT NULL,
    [ChangeUser]                  NVARCHAR (200) NOT NULL,
    [FriendStatusId]              TINYINT        NOT NULL,
    [Person1Id]                   INT            NOT NULL,
    [Person2Id]                   INT            NOT NULL,
    [Person1RequestTimestamp]     DATETIME       NOT NULL,
    [Person2AcknowledgeTimestamp] DATETIME       NULL
);

各人物は Person テーブルに格納されます (想像してみてください)。Person1Id および Person2Id フィールドは、person テーブルの外部キーです。何かが要求されたか、受け入れられたか、拒否されたか、無視されたかなどをカバーするために、FriendStatus テーブルにステータス リストを保持しています。Timestamp フィールドは、レコードの作成を示すために私の設計の標準です (これは、基本永続化クラスで使用されるパターンのものです)。 ) と、Person1RequestTimestamp に同じデータが含まれているため、この表ではその種類が複製されています。また、Person2 がリクエストを見てアクション (FriendStatusId で示される) を行った時刻をキャプチャし、それを Person2AcknowledgeTimestamp に保存します)。

この設計の核となる前提の 1 つは、Person1 が Person2 の友情を要求したことです。その友情が受け入れられた場合、友情は相互と見なされます。

于 2008-12-18T21:21:18.117 に答える
5

あなたが持っているものと同様のことをしますが、「IsMutual」フラグを削除します。相互の場合は、逆の値を持つ 2 番目の行を追加するだけです。行を追加しますが、よりクリーンに感じます。

于 2008-12-18T20:58:22.360 に答える
3

おそらく、Relationship テーブルを追加し、そこに関係プロパティを配置して、UserFriend から参照します。

于 2008-12-18T20:57:55.590 に答える
3

私はこのようにしました:

テーブル ユーザー

id  name
-----------
1   foo
2   roo
3   shoo
4   mooo

TABLE 友人関係

id   u_id f_id
--------------
1    1    2
2    2    1
3    3    1
4    1    3

友達リクエストが受け入れられるたびに、挿入逆の方法1 2 & 2 1と簡単なクエリ:

$ufq=mysql_query("SELECT t1.f_id,t2.id,t2.name FROM friends AS t1, user AS t2 WHERE t1.u_id='$u_id' AND t2.id=t1.f_id ORDER BY t2.name ")or die(mysql_error());
while($fn=mysql_fetch_array($ufq)){
    echo $fn["name"].'<br>';
}
于 2011-11-09T10:35:27.590 に答える
2

おそらくやりすぎですが、セマンティック Web を使用してこれをモデル化できます。FOAF (FOAF Friend of a Friend) 形式を使用できます。

于 2008-12-18T21:16:25.303 に答える
2

私の解決策についてどう思いますか?

3 つのテーブルがあります

1 **the user** (id,.etc)
2 **friend_request**(id,flaggerID,flaggedID)
3 **friend**(id,frienderID,friendedID)

あなたはサインインし、私が友達テーブルにいるかどうかを確認し、はいの場合は友達をリストします(私は友達にいます>友達リストにいます)(私は友達にいます>リスト友達にいます)

リクエストはありますか?(私は flaggedID にいますか?) 彼を知っていますか? そうでない場合は、レコードを削除します。はいの場合は、私がフラガーに入れられ、フラガーがフラグを立てられるので、リクエストで新しいレコードを作成します。これで、リクエスト テーブル内の 2 つのレコード間に相互性があるため、両方を削除してフレンド テーブルに配置します。リクエスト/フレンドを簡単に分離できます。

于 2011-04-18T23:04:40.640 に答える
1

友情は、古典的な雇用主/上司およびユーザー/配偶者の自己参加シナリオよりも明確ではありません。友情は関係ですか、それとも活動ですか?後者を無視したことで、私はかなりの批判を受けました。いずれにせよ、データ モデルがどれほど一般的であっても、おそらく複数のテーブルが必要になるでしょう。

于 2008-12-18T21:13:27.167 に答える
-1

2 つのテーブルを作成する必要があると思います。

1. ユーザー
u_id int
u_username 文字列
balahhh............

2. 友情
fs_id int
related_id
int related_id int

于 2014-02-07T04:54:02.960 に答える