2011.06.15
CouchDBとMongoDBの使い分け
CouchDBMongoDBをしばらく使ってみて、その使い分けのポイントがわかってきたような気がするので、ちょっと書いてみたい。

CouchDBとMongoDBは、広く「NoSQL」と総称されている非SQL型データベースのうち、「ドキュメントデータベース」と呼ばれるカテゴリを代表する2つだ。ドキュメントデータベースとは、かんたんにいうと、JSONデータ(=ドキュメント)をそのままデータベースに保存できるというもので、従来のRDBのような「スキーマ」がない。複数のテーブルを結合(join)するという使い方をせず、一意キーの指定や比較的単純なクエリーでJSONデータを取り出す。

ここでは詳しい話には踏み込まず、2つのデータベースの違いを私の主観で、ごく大雑把にまとめてみる。

まず、それぞれの強みを私の印象で3つずつ書くと、こんな感じだ。

CouchDBの強み:
1)優れた管理画面「Futon」が付属
2)JavaScriptでWebアプリまで作れて、Webサーバも内蔵するオールインワン環境
3)JSONサーバとしてネットに直接公開し、JavaScriptから利用するという使い方ができる

MongoDBの強み:
1)従来のRDBの感覚で、かつさらにカンタンに使える
2)クエリーが柔軟
3)DBクライアントなどコマンド系が充実

私は最初、CouchDBのほうに強く惹かれた。長年Zopeをやってきた私は、CouchDBを知ったとき、「これこそ新時代のZopeだ」と思った。CouchDBは基本的にはデータベースだが、ブラウザの管理画面を持ち、Webアプリまで作れて、Webサーバまで内蔵するオールインワン環境である。データベースも追記オンリーで、ZopeのZODBにそっくりだ。

しかしCouchDBは、あくまでも基本はデータベースであり、どんな環境からでも使える。それも、アプリケーションとの通信までHTTPを使うという斬新な方式で、言語ごとのDBドライバみたいなものもいらない。Zopeがほぼ完全に閉じた世界だったのに比べて、CouchDBは必要に応じて、さまざまな環境から単なるデータベースとしても使えるし、完結したオールインワン環境としても使える。

そんな感じで、CouchDBは私にとって、「Zopeのいいところを受け継ぎながら、Zopeの限界を超えた」ものに見えたのだ。

しばらくはCouchDBにハマっていて、昨年12月に名称とシステムを変えたこのmojix.orgも、当初はCouchDBを使っていた(いまはMongoDB)。現在は更新が止まっているが、shortcutwebというサイトも、CouchDBで再構築した(いまもCouchDBで稼動中)。CouchDB自体がバーチャルホストつきのWebサーバを内蔵しており、「CouchApp」という仕組みでWebアプリも作れるので、まさにCouchDBだけで動的なサイトができるのだ。

しかし、その後CouchDBを使い続けていくうちに、いろいろカベにブチあたることが増えてきた。主に次の3つである。

CouchDBの弱み:
1)クエリーが柔軟に書けない
2)「テーブル」がない
3)データ更新のたびにデータベースが大きくなる

まず、いちばん困ったのが1)だ。CouchDBのクエリーは、JavaScriptを使って、MapReduce方式でインデックス(「view」と呼ぶ)を作成する。これ自体はよくできた仕組みなのだが、クエリーがいくらか複雑になってくると、だんだん破綻(はたん)してくる。

2)も困った。CouchDBには、RDBなどにもあるいわゆる「データベース」はあるのだが、その下の「テーブル」にあたる概念がない。「データベース」に、いきなりJSONデータを突っ込む方式である。よって、「テーブル」にあたるデータ種別を保持したいときは、JSONデータに「type」などのフィールドを作って入れておき、クエリー時に「type」の値で引き出すことになる。これが面倒なのだ。ただでさえ、複雑なクエリーが作りにくいのに、いつもこのtypeがクエリーに入ってくるので、そのぶんクエリーが複雑になる。MongoDBの場合、クエリーも柔軟に作れる上に、「テーブル」にあたる「コレクション」があるので、このような問題は一切ない。

3)は、データ更新の頻度が大きい場合に問題になる。これはZopeユーザにはおなじみの話で、例えばアクセスカウンタみたいなものをやろうとした場合、アクセスがあるたびにデータベースが更新され、データがだんだん巨大化していく。こういう追記オンリーのデータベースは、過去の履歴が自動的に残るのはいいのだが、「過去の履歴はいらない」という選択ができないのだ。

こうした経験をふまえて、CouchDBではやりにくい場合、MongoDBを使うようになっていった。MongoDBは、ちょうどCouchDBの強みと弱みを反転させたような感じで、CouchDBの持つ弱点はないかわりに、CouchDBの強みを持っていない。つまり、MongoDBの弱みはこんな感じである。

MongoDBの弱み:
1)管理画面が付属していない(コマンド操作が基本)
2)あくまでも「データベース」としての用途のみ
3)ネット越しの操作やレプリケーションなどはできない

これはいずれも、データベースとしてはあたり前の特性であり、普通の意味では「弱点」とは言えない。あくまでも、CouchDBと比べた場合の話である。

MongoDBは、従来のRDBと役割や使用感が似ているので、多くの人にとって違和感がないと思う。いっぽうCouchDBは、いろいろな点で斬新であり、かなりクセが強い。強みと弱みの「振幅」が大きいのだ。

私の場合、もともとZopeというやや特殊な環境になじんでいて、Zopeに似たところがあるCouchDBから入ったので、MongoDBには「欠落」を感じてしまうところがある。ZopeもCouchDBも、インストールしたらすぐにブラウザだけで操作できて、CouchDBなどは、ネット越しにレプリケーション(データの同期)までできる。すべての通信をHTTPで組み立てている強みだ。またデータのバックアップなども、データベースにあたるファイルをコピーすればおわりである。ZODBと同様、ひたすら追記していく方式なので、データファイルが壊れることもまずない。このようなCouchDBの便利さに慣れると、「ただのデータベース」であるMongoDBは、物足りない気がしてしまうのだ。

このように、CouchDBとMongoDBには、それぞれの強みと弱みがある。どちらも経験がなく、これから始めてみたいという人には、オーソドックスなMongoDBのほうをオススメする。人気度でもMongoDBが圧倒的に上のようで、おそらくあと数年もすれば、RDBも含めたすべてのデータベースのなかで、もっともポピュラーなデータベースになると思う。

いっぽうCouchDBは、データの更新が比較的少なく、サイト規模も小さくて、JavaScriptが大好きな人には向いているかもしれない。CouchDBの場合、「JavaScriptの使い方」は主に2つある。ひとつは、WebアプリのサーバサイドロジックをJavaScriptで書く「CouchApp」。もうひとつは、ごく普通のJavaScriptの使い方であるWebクライアントとして、CouchDBを「JSONサーバ」として使う方法。

ちなみにCouchDBは、Ubuntu Linuxに最初から組み込まれていて、一部のデスクトップアプリのデータを保持するのに使われているようだ。CouchDBはスマートフォンでも動くようで、これもいわば「デスクトップ」用途と言えるだろう。サーバ用途に比べて、デスクトップ用途はデータ更新も少ないし、HTTP経由でデータ操作やレプリケーションなどができるCouchDBは、たしかにデスクトップで威力を発揮する余地が大きそうだ。

王道でオーソドックスなMongoDBと、トガっていてクセの強いCouchDB。私にとっては、どちらも捨てがたい魅力があり、今後もケースバイケースで使い分けていくと思う。


関連:
CouchDB
http://couchdb.apache.org/
MongoDB
http://www.mongodb.org/
ウィキペディア - NoSQL
http://ja.wikipedia.org/wiki/NoSQL

関連エントリ:
ブログ名が「Zopeジャンキー日記」から「モジログ」になりました
http://mojix.org/2010/12/05/blog_rename
FriendFeedはどのようにスキーマレスなデータをMySQLに格納しているか
http://mojix.org/2009/02/28/friendfeed_schemaless
サーバの思い出、Zopeの思い出
http://mojix.org/2008/09/22/server_zope