CouchDBとMongoDBを比較してみた

3rd Feb, 2010 | couchdb mongodb

ドキュメント指向なKVSってことと、字面が似ていると言うことぐらいしか比較する意味がなさそうなCouchDBMongoDBだけど、ここ2,3ヶ月で両方をそれなりに突っ込んで見てきたので比較してみた。実装面やパフォーマンス、ということよりはどちらかというと(私が感じる)思想的なものや、ユーザ側からの視点での比較。

共通するところ

これはもう簡単に、

  • ドキュメント指向データベース - RDBMSのようなカラムと言ったものを持たずにスキーマレスで好きな情報を入れられる
  • Javascript/JSONを使用 - データ自体もJSONというJavascript由来のフォーマットで持ち(MongoDBはJSONを元にしたBSONというものだが)、データベースのアクセスにはJavascriptを使用する
  • スケールアウトするように考えられている
  • NoSQLな流行

CouchDBの特徴

機能を限定しているが、その中にいる限りは幸せになれることを目指しているのがCouchDB。たぶんそのことを"Relax"と呼んでいる。

Viewが中心

クエリ(一般的なRDBMSで言うとSQL)のようなものがほぼないCouchDBにとって、(RESTでアクセスする)Viewがそれに代わるユーザとの接点になる。

CouchDBのViewは、RDBMSのViewのイメージとは違い、実体を持ち永続的/静的なものになっている。そのため、内部的に、同じ実体のViewがすべてのユーザでシェアされるので効率もよい。Viewを作った時点で、Viewに対するIndexも作成され(開発者が余計なことをしなくても)パフォーマンスがでる。

ただ、それを実現するためにViewを作る上での制約が多い。Viewは、map-reduce(のようなもの)を使ってドキュメント本体から作るのだが、世の中の他のmap-reduceと比べるとかなり貧弱。ちょっと複雑なViewを作ろうとすると挫折する。(例えば、A:B=1:N と B:C=1:N のような構造で、Cをキーとして、BとAも持ってくるView、とかはたぶん無理。RDBMS的に言うとJoin2回以上は無理、な感じ。)

これは、CouchDBは、ドキュメント(RDBMSで言うレコード)が一件追加(更新や削除も)されたときに、View全体を作りなおすことなく、View側もデータ一件分の変更で済ますことがでることを目指しているからだと思う。このため一つのドキュメントが他のドキュメントと関連するようなViewを作ることができない。上記の例だと、Aが追加されたときにCとの関連が(Bを経由しないことには)持ってこれないのでダメ、という感じ。

きれいにViewに落とせるようなデータ構造とViewの定義さえ作れれば、データの追加も、更新も、参照も、さほどサーバ資源を使わなくてすむし、スピードも速い。

Tableがない

もう一つの大きい特徴が、CouchDBは、RDBMSで言う”テーブル”のようなものを持たないということ。「1つのデータベース」は「何を入れてもいい巨大な箱」という感じ。

RDBMSでいう"テーブル"なような物を持つ場合には、自分でそれ用のメタ情報を各ドキュメントに持たせる必要がある。

各言語のライブラリ(mapper)では独自にそういうことをしているが、mapper間でそのメタ情報の互換性がない。また、1ドキュメントを1テーブルと見たてるようなライブラリもあるが、複数のドキュメント間ではViewを作れないのでCouchDBの大きなメリットが消えてしまう。

スキーマレスで、何でも突っ込む、というのはドキュメント指向なデータベースとしては正しいのかもしれないが、いざ、この上でシステムを作るとなるとあまりにも自由過ぎると個人的には思っている。

アプリケーションを書ける

CouchDBはアプリケーションの層までCouchDB内に書くことができる。もちろんよくあるRDBMSを使ったWebシステムのように、CouchDBを単機能な「データベース」として使い、フロントエンドは別のシステム、という構成も取れる。ただ、CouchDBが目指しているところはデータベースとアプリケーションがセットになったオールインワンなものなのかな、と感じる。

MongoDBの特徴

CouchDBと比較すると、MongoDBは「なんでもあり」と言った感じ。

なにしろ、MongoDBの公式ページの最初の宣伝文句が「Combining the best features of document databases, key-value stores, and RDBMSes」だ。KVSとドキュメント指向データベースとRDBMSのいいとこ取りのデータベースを目指すと言った感じだろうか。

一般的に、RDBMSに慣れた人がKVSなデータベースを触る場合、「RDBMSのことは忘れろ」が定石だ。実際、私もそう思うし、そうした方がいいんだろうけど、やはり長年RDBMS生活をしていると難しい面もある。MongoDBを触っていると、あちこちで懐かしいRDBMSの匂いがするので、RDBMS出身の人には入りやすいデータベースだと思う。

たとえば、以下の点でRDBMSと似ている。

  • コレクション(Collection)というテーブルのようなものを持つ
  • (SQLではないが)クエリーを持っている。またその書き方
  • indexの考え方
  • データベースチューニングの考え方
  • データを直接コマンドラインから操作できるシェル的な物が付属されていたりと言った環境面

これに加えRDBMSでは色々とめんどください、データを複数のデータベースに分割して保存する(Sharding)といったKVSらしい機能がついてくるのがMongoDB。

まとめ

これらの特徴から、CouchDBは、できるだけユーザ(or/and開発者)にとって単純なインターフェースにして、(そんなに多くない)ルールにさえ従っていれば、幸せになれるものを目指している、という気がしている。

一方のMongoDBは、何でもありな方向で、多機能高機能を目指している。たとえば、RDBMSでできることはなるべく実現できるように考えられている。ただ、これは、もちろん「ごちゃごちゃ」しすぎたり「パフォーマンスが出なかったり」する原因になりやすく、そうなってくると、「なんでMongoDB? "RDBMS"でいいんじゃない?」ということにもなってしまうので、その辺のバランスについては今後見ていきたいと思っている。

簡単に言うと、まったく新しいデータベースを目指しているCouchDBと、超現実指向のMongoDB、といったところだろか。

おまけ - CouchDB/MongoDBを始める

CouchDBは、公式ドキュメントはいまいちだが、このドキュメント(本?)がすごくよくまとまっているので、最初にこれを読むのがおすすめ。

MongoDBは、公式ドキュメントがそれなりにまとまっているのでそれを最初に読むのがおすすめ。日本語版も少しある。翻訳に関してはこちら

追記:

CouchDB詳しい方からフィードバックを頂いたのでそちらも見てみてください。

Twitterでも少し話したのですが、私は、基本的に現行のWebシステムのどの部分をKVSに持って行けそうか、というのがベースにあるので、どうしてもそういう目線になってしまいます。それと、完全CouchDBの世界に入るにはまだ少し怖い。DocumentとViewだけで表現できることから少し飛び出すだけで、突然色々なことが難しくなるのが今のところのCouchDBと感じてます。

ただ、MongoDBはいい意味でも悪い意味でも「普通」なので、CouchDBの方が化けるかなという感じはしているので期待して追って行こうと思ってます。


記事の内容についての質問、苦情、間違いの指摘等なんでもtwitterでどうぞ。