web-dev-qa-db-ja.com

マルチオブジェクトの「アクティビティ」と「フォロー」機能のための構造化データベース

ユーザー、プロファイル、ページなど、さまざまなタイプのオブジェクトで動作するWebアプリケーションに取り組んでいます。すべてのオブジェクトには一意のobject_idがあります。

オブジェクトが相互作用すると、ページまたはプロファイルへのユーザー投稿などの「アクティビティ」が生成される場合があります。アクティビティは、object_idを介して複数のオブジェクトに関連付けられている場合があります。

ユーザーは「オブジェクト」をフォローすることもでき、関連するアクティビティのストリームを表示できる必要があります。

効率的でスケーラブルなデータ構造の提案を教えていただけますか?私の目標は、ユーザーがフォローしているオブジェクトに限定されたアクティビティを示すことですリレーショナルデータベースに制限されていません。

更新

ORMとインデックスの作成方法についてアドバイスを受けているので、もう一度質問します。現在の設計モデルによると、データベース構造は次のようになります。

enter image description here

ご覧のとおり、このようなデータベースを実装するのは非常に簡単です。アクティビティテーブルとフォロワーテーブルには、上位レベルよりもはるかに多くのレコードが含まれていますが、許容範囲です。

しかし、「タイムライン」テーブルを作成することになると、それは悪夢になります。すべてのユーザーについて、私は彼がフォローしているすべてのオブジェクトアクティビティを参照する必要があります。レコードに関しては、簡単に制御できなくなります。

この構造を変更してタイムラインの作成を回避し、特定のユーザーのアクティビティをすばやく取得する方法を教えてください。ありがとう。

5
romaninsh

リレーショナルデータベースに限定されないことを書きました。 neo4j のようなグラフデータベースの使用を検討できます。グラフデータベースは、たとえば平均や合計よりも関係が重要であるような状況に特に適しています。

ここで紹介ここでの使用例 を見つけることができます。

使用できるより複雑でより効率的な構造は graphity です。

もっと詳しく知らないと言うのは難しいですが、非常に一般的なものが必要なようです。多分このような何かが役立つでしょう:

 activity 
 -------- 
 activity_id-アクティビティのID 
参加_object_id-参加オブジェクトのID 
 activity_type_id-アクティビティのタイプのID 
 activity_datetime-このアクティビティが発生した日時
データ-アクティビティのコンテキストデータ

これにより、次のようなことが可能になります。

 activity_id |参加オブジェクトID | activity_type_id |日付|データ
 ------------ + ------------------------- + ----- ------------- + ------- + ----- 
 1 | 2 | 3 | ... |これは投稿です
 1 | 84 | 3 | ... | [email protected] 

これは、アクティビティインスタンス(ID#1)を示します。ユーザー(オブジェクト#84、コンテキストデータ "[email protected]")は、オブジェクトIDが2のフォーラム(アクティビティタイプ3)に投稿を作成し、その投稿には「これは投稿です」というテキスト。

状況に応じて、おそらくこれを拡張する必要があります。

...実際に考えてみたところ、data列は必要ありません。ベースobjectテーブルからどのようなデータでも取得できるためです。 participating_object_idの値を使用してクエリします。

1つの可能性は、「継承」、特にを使用することです。参照するオブジェクトに共通のフィールドがある場合。スキーマは次のようになります。

followables
    followable_id      primary key
    -- common fields

users
    user_id            primary key references followables(followable_id)
    -- user specific fields

pages
    page_id            primary key references followables(followable_id)
    -- page specific fields

...

random_entities
    ...
    followed_id        references followables(followable_id)

つまり、pagesusersはどちらもfollowablesであり、followables '属性を持ち、同じように参照できます。

ORMは継承をモデル化し、結合を処理するために、このようなスキーマを作成することがよくあります。

それが問題であることを証明できるまで、非効率を心配しないでください。


に関して。効率に。必要と思われる行数までテスト情報を挿入する簡単なSQLスクリプトを記述します。クエリを記述します(タイムライン全体をクエリする必要はありません。通常はクエリをLIMIT実行します)。実行速度を確認します-パフォーマンスは満足できるものだと思います。そうでない場合は、クエリとEXPLAINの出力を投稿してください。

2
alex

非正規化はここであなたの友達になるでしょう-あなたは簡単に選択できる静的タイムラインテーブルを作ることを考えましたか?

ここでは、非リレーショナルデータストアも強く検討します。これらは、この種の問題によく適合する傾向があります。

1
Wyatt Barnett

クラスのスキームを構築できるORMを使用してみませんか?このようにして、抽象化のより高いレベルで詳細をワークアウトし、ORMにスキーマを設計させ、パフォーマンスに基づいてスキーマの変更/微調整を確認できます。

0
Ominus