1

私はソーシャルネットワーキングサイトで働いています。ここでは、ユーザーが別のユーザーに友達になるように要求します (友達リクエスト)。次のような「フレンズ」テーブルを考えました

Table Name: Friends
Coloumns :
    User1   - Int - FK
    User2   - Int - FK
    Request - Enum('0','1')
    Time    - DateTime

PK - (User1, User2)

Request フィールドには、User1 が User2 に対して要求を行った場合は「0」が格納され、User2 が要求を承認した場合は「1」が格納されます。

ユーザーのすべての友達を取得したいときに問題が発生します。Request フィールドが「0」か「1」かを毎回確認する必要がありました。そうする別の方法はありますか?フレンド リクエストのすべての詳細を格納する別のテーブルがあればよいでしょうか?

4

2 に答える 2

2

コメントでは、基本的に、確立された友情(要求ではなく)はセットアップで常に対称的であると述べています。その場合、基本的に2つのオプションがあります。2つの行に格納するか、いずれかの列に一致させて選択することができます。前者はより単純なクエリを生成しますが、後者は対称性がデータベース構造に固有であることを保証し、重複データの保存も回避します。だから私は後者、つまり何らかの形のを選びWHERE (User1 = XX or User2 = XX )ます。クエリは、1つの列だけのクエリが同じ行数を使用する場合の2倍の時間がかかる可能性がありますが、行数は他のストレージスキームの半分にすぎないため、パフォーマンスの面での正味の影響は無視できるはずです。 。

リクエスト用に個別のテーブルが必要か、確立された友情が必要かは、関連データとアプリケーションの制御フローの両方の点で、これら2つがどれほど類似しているかによって異なります。したがって、たとえば、確立された友情と保留中のリクエストの両方を、おそらく異なる色などで、同じリストに表示する単一のリストをユーザーに提示する場合、データベースに単一のテーブルを含めると、より多くのことができます。適切です。一方、リクエストと友情を別々に扱うことがほとんどの場合、2つのテーブルを持つ方が自然になります。share_calendarまた、ある時点で、フレンドシップには次のような属性が必要であるのに対し、リクエストには次のような属性が必要であると判断したconfirmation_key場合は、別のテーブルを使用したほうがよいでしょう。

statusこれを単一のテーブルにすることにした場合は、列と値requestedとを呼び出すなど、列挙型のより記述的な値をお勧めしますestablished。私は、一見すると、の値をrequest = 1「これは要求のみであり、確立された友情ではない」と解釈します。これは、あなたが関連付ける意味とは正反対です。このあいまいさは、さまざまな人がコードを維持する必要があるときにエラーにつながる可能性があります。そして、数年後には、あなた自身でさえあなたの古いコードを誤解するかもしれないので、あなたは今のあなたとは別の人で十分になるでしょう。ですから、そこで説明してください。

もう1つの注意:データベースがクエリに表示される方法を微調整するために、いつでもビューを使用できます。たとえば、ビューを作成できます

CREATE VIEW SymmetricEstablishedFriends AS
SELECT User1 AS Me, User2 AS Friend, Time
FROM Friends
WHERE Status = 'established'
UNION
SELECT User2 AS Me, User1 AS Friend, Time
FROM Friends
WHERE Status = 'established'

これにより、データは確立された友情のみに制限され、対称化が行われます。クエリでこのようなビューを使用すると、すべてのクエリでテーブル構造のすべての詳細を処理する必要がなくなります。そして、これらの詳細を変更した場合、変更する場所が少なくなります。

于 2012-08-13T20:28:02.717 に答える
1

あなたのデータをrequestsとに分割しfriendshipsます。が承認されたら、requestに変換しfriendshipます。これらは実際には 2 つの異なるオブジェクトであり、そのように扱う必要があります。

Requests ::
  requesting_user_id : int()
  requested_user_id  : int()
  date_requested     : datetime()
  status_id          : int()

Statuses ::
  (Active, Declined, Accepted, Ignored)

Friendships ::
  friendship_id      : int()
  user_id            : int()
  friend_id          : int()

リクエストが拒否された場合はリクエストを削除するか、そのための列を作成します (人々が同じユーザーの友情を繰り返しリクエストしないようにするため)。簡単に索引付けできるように、要求を 2 つのフレンドシップ (各方向に 1 つ) に変換する必要があります。

SELECT friend_id FROM friendships WHERE user_id = ? 
于 2012-08-13T17:50:04.273 に答える