CouchDB と MongoDB の比較 #1 通信プロトコル
まずは、DBを利用するにあたって、どんな環境が必要なの?ということで、プロトコルについて比べます。
項目 | CouchDB | MongoDB |
---|---|---|
通信プロトコル | HTTP | 専用プロトコル |
利用環境 | HTTP クライアントが使える環境 | 各種ドライバあり |
いきなり比較が難しいですね。
CouchDBは、HTTP なので curl で確認できます。手軽に確認できる反面、オーバーヘッドはそれなりにあります。究極のパフォーマンスを求めるなら、Hovercraftというストレージを直接操作できるErlangライブラリを使った方がいいです。また、普通に使う場合でも couch-rest (Ruby/Gem) や couchdb-python (Python) などのドライバライブラリを使うという手もあります。
MongoDB のほうはBSON(http://www.mongodb.org/display/DOCS/BSON)という、JSONのようなものをバイナリでシリアライズしたデータをやりとりする専用プロトコルです。これだとちょっと取っつきにくそうですが、各種ドライバがあるのでドライバのAPIを覚えていけば大変ではないように見えます。
CouchDB と MongoDB の比較 #2 取り扱い可能なデータ
項目 | CouchDB | MongoDB |
---|---|---|
データタイプ | null,bool,number,string,array,object(, binary) | たくさん |
これまた、Mongoのほうがよさげ。
CouchDBはJSONなのでJSONで規定されるデータタイプに準じます。ただし、添付ファイル機能があるので、binary も(いろいろ制約がありますが)一応可能、ということで。Date がないのが致命的なので、書き込む際はDate型は"YYYY/MM/DD HH:MM:SS +ZZZZ"形式にシリアライズして、読み込むときは毎回 Date.parse() するなどの工夫が必要です。ドライバライブラリの中にはこのあたりをうまくやってくれるものもあるかと思います。
一方で、MongoDB では BSON でデータタイプを決めています。ドライバから利用するので、その言語のデータ型に適当にマップしてくれるものと想像ができます。で、http://www.mongodb.org/display/DOCS/BSON#BSON-ElementDataTypes を見る限り、JSONよりも表現が豊富です。Date もあるし。Timestamp もあるので、ドキュメント管理には向いているじゃないか。。。
CouchDB と MongoDB の比較 #3 ドキュメントで予約されたフィールド
CouchDBもMongoDBも、それぞれのドキュメントに対して一意キーである_idフィールドを持つようです。いずれも、ドキュメントの追加時に自動的にサーバー側で(UUID 32文字)付与させるか、クライアントから指定することができるようです(TODO: Mongo でもクライアントから指定できるかどうかは未検証)。
一方、CouchDBでは、_rev というドキュメントの衝突管理のための版番号を持ちます。版番号はドキュメントの更新履歴に対して一意のため、
- ドキュメントを取得
- 変更を実施
- ドキュメントを更新
の操作において、1の後、3をコミットする前に、他のクライアントによってドキュメントが更新されてしまった場合には、3. で送信する_revとDB上の_revが不一致のため、更新に失敗する、という仕組みを提供します。Optimistic Lockです。
一方で、MongoDBは「指定した条件にマッチしたドキュメントを更新する」というAPIを持っているので、_rev のような仕組みがなくても、同様のことは実施できます。これについては、「Atomic Operations」に記載があるようです。"Update if Current" の項が参考になります。
まとめます。
項目 | CouchDB | MongoDB |
---|---|---|
ドキュメントの一意性 | _id で保証 | _id で保証 |
更新衝突検出 | _rev を使ったOptimistic Lock | なし /「指定した条件にマッチしたドキュメントを更新する」ことでOptimistic Lockが実現できる |
_rev はレプリケーションの衝突検出にも使うので、これについてはあとでまた調べます。