あるユーザーが別のユーザーの友達であることを示すデータ モデルを設計しようとしています。これは私がこれまでに思いついたものですが、不格好に思えます。より良い解決策はありますか?
User
=====
Id
Name
etc...
UserFriend
===========
UserId
FriendId
IsMutual
IsBlocked
あるユーザーが別のユーザーの友達であることを示すデータ モデルを設計しようとしています。これは私がこれまでに思いついたものですが、不格好に思えます。より良い解決策はありますか?
User
=====
Id
Name
etc...
UserFriend
===========
UserId
FriendId
IsMutual
IsBlocked
UserRelationship
====
RelatingUserID
RelatedUserID
Type[friend, block, etc]
相互関係は列として属していないことに同意します。正規化を破ります。
2 人のユーザーごとに1 つのレコードを使用し、提案された方法が示唆する余分なメモリを消費しないようにするには (ユーザーごとに 2 つのレコードがあるため、必要な量の 2 倍)、次のようにします。
テーブル構造:
USER_RELATIONSHIP {
user_first_id,
user_second_id,
type
primary key(user_first_id, user_second_id)
}
確認:user_first_id < user_second_id
最も興味深い部分 -関係の可能type
なすべての状態について、対応する値を作成します。例:
pending_first_second
pending_second_first
friends
block_first_second
block_second_first
block_both
あなたが持っているもの:
user_first_id < user_second_id
、2 人の特定のユーザー間の関係のレコードが 1 つだけであることを保証します。これは、この制約と主キーの制約により、それ以外の場所に配置することが許可されないためです。2 人のユーザー間の関係 (および更新) を調べるには、次の 1 つのクエリを実行するだけです。
select * from USER_RELATIONSHIP where
user_first_id = user1_id and
user_second_id = user2_id;
or
この列を逆にチェックするステートメントがないため、高速です。
シナリオ例:
no record
: 関係がない
pending_first_second
: 1 人目が 2 人目に友達リクエストをした
friends
: 2 番目が友達リクエストを承認しました
no record
: ユーザーの 1 人が他のユーザーを自分のファイアーエンドから削除しました
このソリューションは、1 つのレコードのみを作成、保存、および更新するため、メモリと速度の両方の点で効率的です。
私は現在、クライアント向けのソーシャルネットワーキングサイトを構築しており、このように表現しました
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 の友情を要求したことです。その友情が受け入れられた場合、友情は相互と見なされます。
あなたが持っているものと同様のことをしますが、「IsMutual」フラグを削除します。相互の場合は、逆の値を持つ 2 番目の行を追加するだけです。行を追加しますが、よりクリーンに感じます。
おそらく、Relationship テーブルを追加し、そこに関係プロパティを配置して、UserFriend から参照します。
私はこのようにしました:
テーブル ユーザー
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>';
}
おそらくやりすぎですが、セマンティック Web を使用してこれをモデル化できます。FOAF (FOAF Friend of a Friend) 形式を使用できます。
私の解決策についてどう思いますか?
3 つのテーブルがあります
1 **the user** (id,.etc)
2 **friend_request**(id,flaggerID,flaggedID)
3 **friend**(id,frienderID,friendedID)
あなたはサインインし、私が友達テーブルにいるかどうかを確認し、はいの場合は友達をリストします(私は友達にいます>友達リストにいます)(私は友達にいます>リスト友達にいます)
リクエストはありますか?(私は flaggedID にいますか?) 彼を知っていますか? そうでない場合は、レコードを削除します。はいの場合は、私がフラガーに入れられ、フラガーがフラグを立てられるので、リクエストで新しいレコードを作成します。これで、リクエスト テーブル内の 2 つのレコード間に相互性があるため、両方を削除してフレンド テーブルに配置します。リクエスト/フレンドを簡単に分離できます。
友情は、古典的な雇用主/上司およびユーザー/配偶者の自己参加シナリオよりも明確ではありません。友情は関係ですか、それとも活動ですか?後者を無視したことで、私はかなりの批判を受けました。いずれにせよ、データ モデルがどれほど一般的であっても、おそらく複数のテーブルが必要になるでしょう。
2 つのテーブルを作成する必要があると思います。
1. ユーザー
u_id int
u_username 文字列
balahhh............
2. 友情
fs_id int
related_id
int related_id int