2

MongoDB で 100 台のカメラから記録された画像のメタデータを保持することを検討しており、記録はカメラごとに 30 日間保持されます。1 台のカメラが 1 日に 100,000 枚の画像を提供する場合、MongoDB で最大 ( 100 x 30 x 100000 ) の画像 (ドキュメント)を保存します。私の Web アプリケーションは、このデータを次のようにクエリします。

カメラを選択 > 日付を選択 > 時間を選択 > その時間内のすべての画像を取得します。

次の 3 つのオプションを使用してスキーマを設計する予定です。最良の方法については、専門家の意見/提案が必要です。

1)時間単位のコレクション: 72000 の MongoDB コレクションを作成します。つまり、カメラごとに 1 時間あたり 1 つのコレクション(100 台のカメラ X 30 日 X 24 時間) (24000 の制限を超えるには --nssize 500 コマンドを使用)。MongoDB でこれほど多くのコレクションを作成できるかどうか、そして次に、これらのコレクションの読み取りと書き込み中に予想されるパフォーマンスの利点と損失が何であるかが心配です。ただし、時間ごとの画像の読み取りについては、このスキーマを使用すると非常に簡単に見えます。これは、単一のクエリで任意のコレクションにデータをフェッチできるためです。

2)日単位のコレクション: 3000 の MongoDB コレクションを作成します。つまり、カメラごとに 1 日あたり 1 つのコレクション(100 台のカメラ X 30 日)。これは許容範囲であり、コレクションの数も適切に見えますが、私の懸念は、特定の日のコレクション内の特定の時間から画像を読み取ることです。

3)カメラ単位のコレクション: 100 個の MongoDB コレクション、つまりカメラごとに 1 つのコレクション(100 台のカメラ/コレクション)を作成します。次に、完全な日付タイムスタンプ (2014-11-22 06:10:55.000) の言い換えである (20141122061055000) のような形式の一意の「id」でスナップショットを保存します。

理想的には(1)、(2)、または(3)ができればいいのですが、他のオプションは大歓迎です。

私の場合を考慮して、MongoDB の選択についても提案してください。

よろしく。

4

2 に答える 2

5

これは次のとおりです。MSSQLServerの代わりにMongoDBを使用することの長所と短所

なぜあなたが多くのコレクションを使用するようにアドバイスしようとしているのかわかりません。

MongoDBでこのように多くのコレクションを使用することは悪い考えと見なされます(そして、インデックスのオーバーヘッドの後で、おそらくnsサイズを増やす必要があります)。代わりに、一般的なドキュメントの単一のコレクションを水平方向にスケーリングする必要があります。他の回答者も同意しているようです。

私はおそらく(頭のてっぺんからすぐに)ドキュメント構造を持つ単一のコレクションを使用します:

{
    _id: {},
    camera_id: ObjectId(),
    image: {},
    hour: ts_of_hour,
    day: ts_of_day
}

そうすれば、必要な金種に基づいて画像を選択するために必要なすべてのデータを取得できます。

注意:MongoDBのロックはデータベースレベルであり、コレクションレベルではないことも考慮してください。ここでは、クエリをより困難かつ複雑にし、データの保守を困難にするだけで、有用なものは何も得られません。

編集

あなたの懸念のいくつかに答えるために:

NB:私はあなたのアプリを設計していません、そしてこれは遅い答えです(夜遅くも)ので、基本的にこれは私がすぐに頭に浮かぶ基本的な概念を具体化することです。

カメラごとに1つのコレクション、つまりほぼ100のコレクション。

繰り返しになりますが、最適化の理由でこれを行う場合は、DBごとに1台のカメラとして行うことになりますが、それは公式にはやり過ぎです。正直なところ、30mのレコードは何もありません、私は今その懸念を解決します。SQLとMongoDBのどちらについて話している場合でも、データベースの可能性の観点から、30mのレコードコレクションは通常、小さく、分単位であると見なされます(MS SQLは、テーブルごとにペタバイトを格納できると言っています)。

  1. FromDateとToDate2の間のすべての画像を選択します

上記の回答を使用して、ドキュメントのBSON日付フィールドを使用してそれを実現できます。

  1. FromDateとToDateの間のTop(COUNT)画像を選択します

あなたはただすることができますcount()

top()はすべてのDBシステムに実装されているわけではないため、これはここではMS SQL固有ですが、この特定のクエリでは、クエリは常に1行を返すため、何の役にも立ちません。

この特定のデータを別のコレクションに集約できます。それは問題ないので、別のコレクションでは、一連の日があります。

{
     count: 3,
     day: (date|ts)
}

そしてcount()、大規模なワーキングセットでは遅くなる可能性があるため、数日のうちに少しだけアップすることができます。したがって、コレクションの目的は、データを要約して、クエリのワーキングセットをより管理しやすくすることです。

したがって、他のコレクションを使用して、低速な集計関数の「キャッシュ」を保持したり、もちろんアプリ内の他のエンティティを保持したりすることができます(リレーショナルDBのように)。

基本的に、SQLの場合と同様に、一般的なスキーマまたはドキュメントはコレクションにグループ化されます。したがって、実際には、1つのテーブルのみを使用してSQLでアプリを設計しimagesますcamera

5を除く他のすべてはここで大まかにカバーされているので:

  1. IDを持つ画像から/への前/次の画像を選択します

あなたは_idこのようにここを使うことができます:

db.images.find({_id: {$gt: last_id}}).limit(1)

そして、それはかなりうまくいくはずです。

あなたがここに投稿したコメントについても:

MongoDBで、30個のドキュメントを含むコレクションのクエリは、30,00,000個のドキュメントを含むコレクションのクエリと同じであるということですか?

これは、データベース設計全般についてどれだけ知っているか、およびデータベースアーキテクチャを拡張する方法によって異なります。これは、MongoDBだけでなくSQLにも当てはまるものです。正しく設定されていれば、SQLは30のような30mのレコードを簡単にクエリできます。

結局のところ、シャーディングです。高速であるかどうかは、クエリを実行するシャード全体のインデックスとそのワーキングセットサイズ(RAMに必要なデータ量、RAMにあるかどうか)に依存します。見た目では、image_id(ObjectId)と日付のシャードインデックスが必要なものを提供する可能性があります。ただし、これにはさらにテストが必要です。データベースのスケーリングは少し慣れていないので、Googleなどを介してこのテーマを検索する必要があります。

注意:30mのドキュメントはシャーディングを必要としない可能性があるため、これは適切なインデックスを作成する場合にすぎません。

うまくいけば、これがお役に立てば幸いです。私はここで輪になって回っていません。

于 2012-11-03T12:48:54.530 に答える
2

コレクションに問題はありません。写真は単一のスキームであり、単一のコレクションに含まれている必要があります。

各写真にはタイムスタンプが付けられます。残りはクエリによって行われます。問題なく1時間あたりのドキュメントをクエリできます。

var begin_hour = new Date(date.year, date.month, date.day, hour);
var end_hour = new Date(date.year, date.month, date.day, hour + 1);

db.photos.find({taken: {$gte: begin_hour, $lt: end_hour}})

選択した写真を選択しhourます。

それでも満足できない場合は、MapReduceもあります。

于 2012-11-03T08:17:24.843 に答える