インサート

based on v12 (2010-10-03更新) - オリジナル

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

Document-Orientation

document-oriented データベースは、"ドキュメント"を格納します。これは、構造化されたドキュメントを意味します。この言葉は"XML ドキュメント"から来たのかもしれません。 JSONや、様々な言語のネストされたディクショナリ型は同じような構造を持ちます。

MongoDBに格納されるドキュメントはJSONに似ています。JSONは、オブジェクトスタイルのデータを言語に依存せず標準的な方法で格納するには良い形式です。

効率的にするために、MongoDBでは、 BSON と呼ばれるフォーマットを使っています。これはデータをバイナリで表現するものです。BSONは、JSONよりも指定したフィールドをスキャンするのが速いです。また、BSONデータは、dataやbyte-array (bindata)タイプのようないくつかの追加の型を持っています。BSONは、JSONや、多くのプログラム言語のデータ構造に簡単に変換できます。

クライアントドライバはデータを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> ,
      ...
   }
}

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

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