特集
» 2011年12月22日 00時00分 公開

こんなときに役立つCouchDB:モバイルからクラウドまで、幅広く活躍するCouchDB (1/3)

「NoSQLデータベース」と呼ばれるものの中で、あまり目立たないがよく見ると面白い機能を搭載しているCouchDB。この連載ではCouchDBの役立つ場面を紹介していく(編集部)

[河村康爾,CouchDB JP]

CouchDBってどんなことに使うの?

 「CouchDB? 名前は聞いたことある、ドキュメント指向、JSON……、特徴も何となく分かっている、だけど、どんな場面で使うの?」

 CouchDBについて、こんなイメージを持っている方は多いでしょう。この連載ではサンプルアプリケーションを作りながら、「こんなときこそCouchDB!」という活用例を解説していきます。

 連載「ゆったリラックス! CouchDBがあるところ」でもCouchDBの特徴を解説していますが、あらためてCouchDBについて、リレーショナルデータベース(RDB)と比較しながらご説明します。

RDBの実績とその限界

 RDBには長い歴史と実績があり、現在では「データベース」と言えばほとんどの人がRDBを思い出すほどです。しかし、どんな要求にも応えられる完全なものなど存在しません。これはRDBにも言えることです。

 RDBは、正規化したテーブルにデータを格納するようになっており、必要に応じて取り出せます。しかし、正規化したデータが大きくなっていき、膨大な量になると、データを取り出すときに問題が発生します。複数のテーブルを結合(Join)して、データを取り出すときに処理性能が低下してしまうのです。

 また、テーブルの列などの構造(スキーマ)を一度定義してしまうと、これを変えるのが難しくなります。つまりRDBは、あらかじめ構造が決まっているデータ以外は格納しにくいのです。

NoSQLデータベースの登場

 正規化したデータの処理性能の問題や、スキーマを変えにくい、スキーマ定義に従わないデータを格納できないなど、RDBが抱える問題が目立つようになり、最近はRDBの抱える問題を解決することを狙ったデータベース管理システムが登場しています。一般に「NoSQL(Not Only SQL)データベース」と呼ぶものです。

 処理性能を追求するタイプのNoSQLデータベースとしては、Key/Valueデータストア列指向データベースなどがあります。一方で、スキーマ構造にとらわれない、自由な形のデータを扱うことを目指したNoSQLデータベースとして、ドキュメント指向データベースがあります。CouchDBは、ドキュメント指向データベースの1種です。

 CouchDBは、データ(ドキュメント)をJSON(JavaScript Object Notation)形式で保存します。RDBのようにあらかじめスキーマを定義する必要はなく、JSONオブジェクトをそのまま保存できます。JSON形式のデータは、配列や連想配列を保持できるので、繰り返し要素を保存するために別のテーブルを作成するような作業は必要ありません。また、ドキュメントの更新履歴をリビジョンという形で保存しています。

 下に示したのは、都道府県の男女別人口をなどのデータを保存したJSONドキュメントのサンプルです。CouchDBではバイナリデータをドキュメントに添付できるので、県章のPNG画像ファイル(emblem.png)を添付してみました。

{
   "_id": "Kanagawa",
   "_rev": "2-33800f007105d4d32afa40fc9b9dad1a",
   "type": "prefecture",
   "name": "神奈川県",
   "population_female": 4517279,
   "population_male": 4544194,
   "district": "関東地方",
   "_attachments": {
       "emblem.png": {
           "content_type": "image/png",
           "revpos": 2,
           "digest": "md5-y0il+Gf7UecfOFpoNLdUew==",
           "length": 9792,
           "stub": true
       }
   }
}

JavaScriptで検索文を記述

 CouchDBでデータを検索するときは、Viewを利用します。ViewはJavaScriptを使って、MapReduceの考え方で記述します。MapReduceはApache Hadoopで有名になったプログラミングモデルで、ドキュメントの情報を解析し、Key/Valueのペアを抽出するMap処理と、Map処理の結果から、同一のキーを持つペアを集計するReduce処理でデータを処理するものです。

 前述の都道府県ドキュメントの人口データを抽出してみましょう。Mapプログラムは以下のようになります。

function(doc) {
  if(doc.type == 'prefecture'){
    emit([doc.district, doc.name, "男性"], doc.population_male);
    emit([doc.district, doc.name, "女性"], doc.population_female);
  }
}

 最初にdoc.typeを判定しているのは、同一のデータベースに都道府県以外のドキュメントも格納できるため、都道府県以外のデータを処理対象としないようにしているのです。Reduceの段階で段階的に集計できるように、キーとして地方、県名、性別を指定しています。

 以下のサンプルコードがReduceプログラムです。人口の合計を計算するsum関数だけを記述してあります。

function(keys, values, rereduce) {
    return sum(values);
}

 このViewの結果を見てみましょう。以下のURLにアクセスすると、JSON形式でViewの結果を取得できます。

http://localhost:5984/japan/_design/japan/_view/populations?group_level=1

 結果は以下の通りになります。

{"rows":[
{"key":["関東地方"],"value":42688508}
]}

 CouchDBにおけるViewの動作がイメージできましたか? 結果を参照するときに"group_level"を変えることで、より詳細なデータを見ることができます。先ほどは"group_level=1"として実行しました。今度は"group_level=2"で実行してみましょう。

{"rows":[
{"key":["関東地方","千葉県"],"value":6210707},
{"key":["関東地方","埼玉県"],"value":7263549},
{"key":["関東地方","東京都"],"value":13188831},
{"key":["関東地方","栃木県"],"value":1999972},
{"key":["関東地方","神奈川県"],"value":9061473},
{"key":["関東地方","群馬県"],"value":2008068},
{"key":["関東地方","茨城県"],"value":2955908}
]}

 "group_level=3"で実行すると、次のようになります。

{"rows":[
{"key":["関東地方","千葉県","女性"],"value":3116776},
{"key":["関東地方","千葉県","男性"],"value":3093931},
{"key":["関東地方","埼玉県","女性"],"value":3612815},
{"key":["関東地方","埼玉県","男性"],"value":3650734},
{"key":["関東地方","東京都","女性"],"value":6668496},
{"key":["関東地方","東京都","男性"],"value":6520335},
{"key":["関東地方","栃木県","女性"],"value":1006775},
{"key":["関東地方","栃木県","男性"],"value":993197},
{"key":["関東地方","神奈川県","女性"],"value":4517279},
{"key":["関東地方","神奈川県","男性"],"value":4544194},
{"key":["関東地方","群馬県","女性"],"value":1020049},
{"key":["関東地方","群馬県","男性"],"value":988019},
{"key":["関東地方","茨城県","女性"],"value":1482593},
{"key":["関東地方","茨城県","男性"],"value":1473315}
]}

 ここでは、JavaScriptで記述したMapReduceのコードをお見せしましたが、追加プログラムを用意すれば、ほかの言語で記述したMapReduceを処理させることもできます。CouchDBのWikiを見ると、ほかの言語でMapReduce処理を記述する方法の説明があります。

 MapReduceのほか、全文検索エンジンApache Luceneelasticsearchと連携することもできます。CouchDBでこれらの全文検索エンジンを利用するには、couchdb-luceneや、CouchDB Riverといったライブラリを利用します。couchdb-luceneの利用例については連載「ゆったリラックス! CouchDBがあるところ」の第4回を参考にしてください。

HTTPさえ使えればOK

 CouchDBでは、ドキュメント保存、更新、削除、検索といった操作にはRESTful APIを利用します。つまりWebブラウザや、Linux/UNIXの「curl」といった、HTTP(HyperText Transfer Protocol)のやりとりができるプログラムであれば、特別なドライバを用意することなく、そのプログラムからCouchDBを操作できます。

 さらに、CouchDBにはJSON形式のドキュメントを整形して一覧表示する「list」と、詳細表示する「show」という機能を備えています。これらの機能を利用すれば、JavaScript、HTML、CSSを利用した簡単なWebアプリケーションを、CouchDB単体で実現できてしまいます。CouchDB単体でWebアプリケーションを作成する方法については、連載「ゆったリラックス! CouchDBがあるところ」の第2回を参考にしてください。

サーバ同士だけでなく、携帯機器ともレプリケーション

 CouchDBはHTTPを利用したレプリケーション機能を備え、複数のサーバ間でデータを同期させることができます。この仕組みを利用すると、複数のCouchDBインスタンスとクライアントの間にNginXなどのロードバランサを配置し、負荷を分散させることができます。

 CouchDBでは、1つのドキュメントが複数のサーバで同時に更新されると、それぞれのリビジョンを保持します。このような処理方法をMVCC(Multi Version Concurrency Control)と呼びます。CouchDBが自動的にマージするのではなく、ユーザーにデータの競合が発生していることを伝え、マージする手段もユーザーに委ねる形となっているのです。

 CouchDBはサーバやPCだけでなく、AndroidやiOSを搭載したスマートフォンでも動作します。そして、携帯機器で動作するCouchDBのデータベースと、サーバ上のデータベースの間で簡単にデータのレプリケーションができるようになっています。

 2011年10月、NTTドコモの海外拠点の1つであるDocomo Innovationsは、Couchbaseという企業と提携を結ぶことを明らかにしました。Couchbaseは、CouchDBを改良したデータベース管理システムを開発している企業です。

 Docomo Innovationsは提携を結んだ理由として、Couchbaseが携帯機器からクラウド環境まで、多様な環境で利用できるデータベース管理システムを提供していることを挙げています。オフライン時は携帯端末内で動作し、オンライン時にサーバとデータを同期(レプリケーション)するシステムを容易に構築できるということです。

       1|2|3 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。