2011-09-20 15 views
26

私はfacebookがあなたが好きなことができるすべての異なるものについてデータベース設計をどのように管理しているのだろうと思っています。好きなものが1つしかない場合、これはシンプルです。あなたの好きなものには外来のキー、あなたが誰であるかには外来のキーです。Facebookの "like"データ構造

しかし、あなたがFacebookに「好き」できる何百もの異なるテーブルがなければなりません。どのように彼らは好きを格納するのですか?

答えて

24

リレーショナルデータベースでこのような構造を表現する場合は、通常はテーブル継承と呼ばれる階層を使用する必要があります。テーブルの継承では、親のタイプを定義する1つのテーブルがあり、次に子のテーブルのプライマリ・キーも親に戻る外部キーです。 Facebookの例を使用して

、あなたはこのようなものかもしれません:金利完全に

User 
------------ 
UserId (PK) 

Item 
------------- 
ItemId (PK) 
ItemType (discriminator column) 
OwnerId (FK to User) 

Status 
------------ 
ItemId (PK, FK to Item) 
StatusText 

RelationshipUpdate 
------------------ 
ItemId (PK, FK to Item) 
RelationshipStatus 
RelationTo (FK to User) 

Like 
------------ 
OwnerId (FK to User) 
ItemId (FK to Item) 
Compound PK of OwnerId, ItemId 

を、それはFacebookがこの種のもののためにRDBMSを使用していないことは注目に値します。彼らはこの種のストレージ用のNoSQLソリューションを選択しました。しかし、これはRDBMS内に疎結合された情報を格納する1つの方法です。

+0

それは解決策になるかもしれませんが、私は問題は、 "アイテム"でなければならないと思っています。なぜなら、アイテムではないテーブルがあり、いつかそれも好きです。私は、時にはシンプルな方が良いと思っています。反対の遺産を作るのはどうですか? likeは親であり、FK to status、like_for_photoなどのlike_for_statusテーブルがあり、テーブルに簡単に拡張でき、クエリも高速になります。 – Enrique

+0

+1、**あなたは**タイプごとのテーブル**またはTPTを意味すると思います。 – Yuck

+0

@Yuck:TPTとTPHは、私が知る限り、より一般的なSQLではなく、Entity Frameworkの辞書の一部ですが、TPT(Table-Per-Hierarchy)ではなくTPTです。 –

0

Id、ForeignId、およびTypeのテーブルを持つことができます。 TypeはPhoto、Status、Eventなどのようになります。ForeignIdはテーブルタイプのレコードのIDです。これにより、コメントや好きなことが可能になります。あなたはすべての好きなもののために1つのテーブル、すべてのコメントと私が説明したテーブルが必要です。

例:

Items 
Id | Foreign Id | Type 
----+-------------+-------- 
    1 |   322 | Photo 
    4 |   346 | Status 

Likes 
Id | User Id  | Item Id 
----+-------------+-------- 
    1 |   111 | 1 

ここで、同上111を持つユーザーは、ID 322


ノートと一緒に写真が好き:私はあなたのRDBMSを使用していると仮定しますが、Adronの回答を参照してください。 Facebookはではありません。ではほとんどのデータにRDBMSを使用しています。

+0

しかし、その後、あなたは手の込んだ「外国ID」 – Enrique

+0

@Enriqueで制約を使用することはできませんか? RI制約のみを使用してテーブルの継承パターンで実施できることとできないことについては確かに制限がありますが、あなたが話していることは明確ではありません。 –

+0

@Adam Robinson "Items"テーブルの "Foreign_Id"カラムは、本当に(「タイプ」カラムに応じて)多くのテーブルを指しているため、どのテーブルにもポイントできないため、実際のFKではありません。だからあなたはFKを(そしてそれゆえ制約を)置くことはできません。それはあなたのデータを矛盾させる可能性があります。 – Enrique

2

Facebookには、ほとんどのデータストレージにリレーショナルデータベースを使用していないため、従来の外部キーなどはありません。単純に、彼らはそれをカットしません。

しかし、いくつかのNoSQLタイプのデータストアを使用します。 「好き」は、おそらくインフラストラクチャ全体でSOAスタイルの方法で設定されたサービスに基づいて帰属される可能性が高いです。このようにして、「好き」は、基本的に、関連したいものに帰せられる。このすべては、膨大なスケーラビリティと緊密に結合された関係上の問題を扱うことができません。 Facebookは、彼らが動いているボリュームで本当に対処する余裕がない。

また、AOP(Aspect Oriented Programming)スタイルの処理メカニズムを使用して、ページのレンダリング時に「好き」を「添付」することもできますが、JavaScript経由の非同期処理であるという概念がありますSOAスタイルのWebサービスや他の配信メカニズムとの比較

いずれにしても、私は彼らがアーキテクチャの観点から自分自身でこの設定をどのように持っているか聞きたいと思います。そのボリュームを考慮すると、単純な「好き」ボタンでさえ、技術の重要な実装になります。

+0

-1。 "彼らはそれのためにそれをカットしない"意見と多くの投機の問題です。実際に質問に対処するこの回答の唯一の部分(そのようなものがどのように格納されるか)は、第2段落です。 –

+0

+1 @adam、簡単な技術的事実、意見は関係ありません。 RDBMSは、異なる使用モデル用に設計されています。 –

+0

@StephanEggermontのように、アダムは異なるモデル、異なる目的のために、Facebookはもっと必要としています。私は推測していないし、一般的なデータベースコミュニティと科学コミュニティも同意する。それが他の解決策が存在する理由です。 #justsayin 上記のアサーションについては、キーがそのように配置されていません。それはRDBMSのために働く方法ですが、RDBMSはFacebookが扱うデータを供給したり処理したりすることができませんでした。 Facebookは、何か別のものを書こうとしていたからといって、RDBMSを試したり削除したりしませんでした。 – Adron

-5

私は、Facebookが「好き」の情報をRDBMSを使ってどのように示唆しているかという情報を保存していないと確信しています。何百万人ものユーザーや数千人ものユーザーがいるため、ここに参加するために何千もの行があり、パフォーマンスに影響します。

ここでの最善のアプローチは、すべての「お気に入り」を1行に追加することです。たとえば、テキストデータ型のuser_like_id列を持つ表。投稿を気に入ったすべてのIDが添付されます。この場合、1つの行のみを照会するだけですべてが得られます。これは、テーブルを結合してカウントを得るよりもはるかに高速です。

編集:最近このサイトにはいませんでしたが、私はこの回答がダウンしていることを発見しました。さて、ここにexample post with like count and their avatarsがあります。これは私が今話していることを実装した私のデザインです。

2つのコンポーネントは、1)XREFテーブルと2)JSONオブジェクトです。

お気に入りはXREFテーブルに格納されています。しかし同時に、データはJSONオブジェクトに追加され、ポストテーブルのテキスト列に格納されます。

なぜお気に入り情報をテキスト列にJSONとして保存したのですか?そのため、DBルックアップ/ジョインを行う必要はありません。投稿と違う人がいる場合、JSONオブジェクトは更新されたばかりです。

今、私はこの回答がなぜここで一部のユーザーによって下降されたのか分かりません。この回答は、迅速なデータ検索を提供します。これは、FBアクセスデータの方法であるNoSQLのアプローチに近いです。この場合、お気に入りの情報を取得するために余分なジョイン/ルックアップは必要ありません。

これを保持するテーブルは次のとおりです。これは、ユーザーとアイテムテーブル間の単純なXREFマッピングです。

enter image description here

+0

あなたは「どれくらいの人がこれを好きだったか」を知る方法は?ユーザーテーブルのすべての行を照会しますか? – Wint

+0

最悪の解決策;) – Pars

+0

@Pars worst reply;) – Ross