2011-09-16 11 views
0

これはNoSQLデータベースを使用した私の最初のプロジェクトで、最も効果的な方法でデータを構造化する方法が不思議です。MongoDBスキーマデザイン:songs/plays/likes

私は、ラジオ局が演奏するすべての曲を保存する小さなサービスを作っています。ユーザーは曲を「好き」することができます。私はそのデータ上のさまざまなクエリを実行する必要が

Song: Id, Artist, Title 
Play: SongId, Time (when was the song played) 
Like: SongId, UserName, Time (when did the user click the like button) 

:だから、基本的に私は、次のデータを持っています。たとえば、最後にX曲が再生された回数、最後のX日の上に再生された曲、特定の曲が好きな人など

最初はすべてを1つのドキュメントに入れ子にした再生などの情報を格納することを考えていました。しかし、これはクエリのいくつかを複雑にし、クライアント側でソートするような作業を必要としますが、データベースから転送されるデータの量を小さくしたいと考えています。

また、メモリで最もよく使用されるクエリの一部をキャッシュすることも考えていました。そのようなことをするときに一般的な推奨事項はありますか?

答えて

1

曲の数、再生回数、ユーザー数がすべて大きくなるため、埋め込みドキュメントを使用するとうまくいかないため、よりリレーショナルモデルに戻る必要がありますそれぞれのコレクションがあります。

私が非正規化するのは、Songの情報をPlayドキュメントとLikeドキュメントに入れて、プレイリストなどを任意のユーザーにレンダリングできるようにすることです。

歌:同上、アーティスト、タイトル
プレイ:SongId、時間(曲が演奏された)、はアーティスト、タイトル
同様:SongId、ユーザー名、タイム(ユーザーのようなボタンをクリックしませんでした) 、アーティスト、タイトル、ユーザーID

1

クエリが入れ子構造を使用してハード取得している場合、あなたはいくつかのオプションがあります。

  1. は、適切な曲のために別の文書を作成します。 vs likesと対戦します。もちろん、これらの文書はお互いを参照することができます。

  2. クライアントを入れ子にして、逆の関係を作成する追加のスタブドキュメントを挿入させます。つまり、データを非正規化します。 Mongoのような分散データストアでは、データの非正規化はリレーショナルDBの世界よりも受け入れやすいものです。

  3. mapreduceクエリを使用して、必要なデータを集計します。これは、データが増加するにつれて高価になる可能性があるので、CouchDBのような別のドキュメントデータストアでは、新しいデータが入ったときにマッパーを継続的に実行できる方が良いかもしれません(Mongoにはか否か)。

  4. (これは私にはあきらめないでください)SQLデータベースを使用してください。あなたのデータは、歌や演奏などの特性がレコードごとに変化しないという点で、かなり正常です。ここでリレーショナルデータベースを使用すると、データの柔軟性を犠牲にすることなく、クエリの柔軟性を確保することができます(本当に必要ないため)。 RDBMSは水平方向には拡張されませんが、それは後であなたがうまくいけば解決できるパフォーマンスの問題です。

これは私がそれを見る方法です - 幸運です!

+0

ご意見ありがとうございます。私は、SQLデータベースがここに行くより良い方法かもしれないと理解していますが、これは主に私がいくつかの新しいテクニックを学ぶ楽しいプロジェクトです。そのためMongoDBを理解しようとしています。 – slurmomatic

+0

心配はいりません!完全に理解して、良いスタータープロジェクトのように聞こえる:) – jimbojw