インサート

based on v5

MongoDBにデータをインサートするとき、データは常にdocument形式になります。documentは、JSONや、Pythonのdictionary、RubyのHashに似ているデータストラクチャです。ここでは、もう少しdocument-orientationについて論じましょう。そしてMongoDBにデータがどうインサートされるのかを見てみます。

Document-Orientation

MongoDBを"document-oriented"として言及するとき、それは、データベースのクラスのための基本となるストレージの単位が、key/valuesのペアとする(おそらく構造化された)データの集まり、であることを意味します。

いくつかのドキュメントフォーマットの例として、 JSON や、XML、そして単純なkey/valueのペアがあります。

MongoDBに保存されるドキュメントはJSONに似ています。効率化のため、データベースは BSON と呼ばれるバイナリ形式表現されたフォーマットを使います。サイズがコンパクトになることや、速いスキャンが目的です。

クライアントドライバはデータをBSONにシリアライズし、データをDBに転送します。データはBSONフォーマットでディスクに保存されます。つかり、取得するためには、データベースはほぼそのままの形でオブジェクトを送出でき、とても効率的です。クライントドライバは受け取ったBSON、ネイティブ言語のフォーマットへをアンシリアライズします。

JSON

例として、以下の"document"をMongoDBに保存するとします。

{ author: 'joe',
  created : new Date('03-28-2009'),
  title : 'Yet another blog post',
  text : 'Here is the text...',
  tags : [ 'example', 'joe' ],
  comments : [ { author: 'jim', comment: 'I disagree' },
               { author: 'nancy', comment: 'Good post' }
  ]
}

このdocumentはブログのポストなので、"posts"コレクションにシェルを使って保存します。

> doc = { author : 'joe', created : new Date('03-28-2009'), ... }
> db.posts.insert(doc);

MongoDBは、ただ保存するだけではなく、BSONオブジェクトの中を理解するので、内側のフィールドとインデックスを使いクエリーをすることができます。   たとえば、

> db.posts.find( { "comments.author" : "jim" } )

このクエリーを実行することができます。意味としては、"author=='jim'なcommentがサブオブジェクト内に一つでもあるブログポストをfindする"ということになります。

Mongo向きのスキーマ

Mongoは、たくさんの方法で使われますが、人々がそれを最初に使うとき、リレーショナルデータベースでどうアプリケーションを書くか、ということと似たようなことを考えてしまいます。これはいい方法ではあるのですが、Mongoの本当の力を出しきることはできません。Mongoは、リッチなオブジェクトモデルで使うために設計されています。

保存する例

リレーショナルデータベースで、商品を売る単純なオンラインストアを構築するとします。多分このようなスキーマを持つでしょう。

item
   title
   price
   sku
item_features
   sku
   feature_name
   feature_value

多分、別のitemは別のfeatureを持つことになるので、このように正規化することになるでしょうが、すべてのfeatureを持ったtableを作りたくはないでしょう。Mongoでも同じようなモデルを作ることはできますが、次の方がより効率的です。

item : {
   "title" : <title> ,
   "price" : <price> ,
   "sku" : <sku> ,
   "features" : {
      "optical zoom" : <value> ,
      ...
   }
}

この方法はいくつかのいいことがあります。

  • itemすべての情報を一回のdbクエリーで取得することができます。
  • 一つのアイテムのすべてのデータはディスク上の同じ場所にあるので、すべてを読み込むために1回のディスクseekですみます。

いくつかの問題があるように感じるかもしれませんので補足しておきます。

  • 一つのfeatureをinsert/updateしたい場合があるので、mongoはembedされたデータに対して次のような操作を提供します。
    db.items.update( { sku : 123 } , { "$set" : { "features.zoom" : "5" } } )
  • 新しいfeatureを加える場合、それはそのオブジェクト全体がディスク上で移動することになりますか? いいえ、mongoは、オブジェクトが増えることを見越して空きのスペースを残しています。これはインデックスが変更されることなども防ぎます。

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

IF YOU HAVE A QUESTION, POST IT TO THE USER GROUP.

These pages are fine for comments, but for questions, your best bet will always be the MongoDB User Group.

blog comments powered by Disqus