MongoDBのようなNoSQLデータベースが登場し、新しい可能性が拓け、そして新しい課題も持ち上がっています。ここ何ヶ月間か、そのことについて考えてました。NoSQLデータベースはどんな用途でどのように使うのがいいのでしょう? -- トランザクションやジョインは不得意なので、そういう苦手なことをやらせるべきではありません。NoSQLの良いところを活かせるような使い方をしたいですよね。
ひとつの方向として、価値はあるがRDBでは扱いにくいデータをとりあず今すぐ使うという用途が考えられます。そして、扱いにくいデータを改善してより良いデータにしていくのです。この改善作業は一段落することもあるだろうし、場合によりエンドレスかもしれません。
価値はある(かも知れない)が扱いにくいデータを、野生のデータと呼ぶことにしましょう。野生のデータを飼い慣らし、できるだけ扱いやすいデータへと改善する行為、より良いデータを繁殖させる過程をデータ・ブリーディングと呼ぶことにします。
ブリード(breed)の意味は、英辞郎によると:
- 飼育する、繁殖させる、交配する、品種改良する、養育する、しつける、仕込む
といったことらしいです。「ブリーディング」は、まーまーふさわしい言葉なのではないでしょうか。データ・ブリーディングでは、個々のデータもデータの全体も変更していくので、その課題は進化的データベースの構築と運用の問題と言えます。
さて、野生のデータとは何か?をもっと具体的に言えば、次のような条件のいくつかに該当するものです。
- 構造がほとんどない。
- 構造があるかもしれないが、非定形であったり未知・未定の部分がある。
- データ群の構造が一様ではなくて、多様性がある。
- 相互に関連しているが、その関連にも未知・未定の部分がある。
- 現在の構造は把握できているが、将来頻繁に変更される可能性が高い。
データのなかですぐ使える部分や、不完全なデータでも許容出来る用途があれば、今すぐにデータを使っていきます。例えば、Webへの情報の公開ならば、多少は未整理な部分があっても早く公開するほうが重要なときがあります。ティム・バーナーズ=リーが訴えていたように、「Raw Data Now!」と切望している人がいるかも知れません(「目で見えるだけじゃなくて、機械可読なデータをくれー!」も参照)。
既存のデータが在るのではなくて、これからデータを作っていく場合でも、構造が未知・未定で、変更される可能性が高いなら、今後生まれ出るデータは野性的だと言えます。データ・ブリーディングを行っていくことになります。
以下では、データ・ブリーディングに必要な処理、あるいは進化的データベースと周辺ツールが備えるべき機能について概要を述べます。
基本的な用語
データに関する用語は、MongoDBの用語法を借用します。コレクション、ドキュメント、フィールドの3つが基本的な概念です。
- コレクションは、ドキュメントの集まりです。
- ドキュメントとは、JSONオブジェクトのことだと思ってかまいません。
- フィールドは、JSONオブジェクトのプロパティ、またはJSON配列の項目のことです。入れ子構造を持ったドキュメントの深い場所も、favorites.music.2 のようなパス形式のフィールドで参照できます。
MongoDBで言う“ドキュメント”が純粋なJSONオブジェクトと違う点は、画像や動画などのバイナリデータを含めてもいい点です。また、RDBのレコードと同様に、ドキュメントを一意識別する主キー・フィールドが必要です。
データを今すぐ使うための機能
ここでは、Webへの情報の公開を想定します。今すぐにデータをWebに公開するには次の機能が必要です。
- コレクションとドキュメントにURLを与える
- ドキュメントを、適切なメディアフォーマットに変換する
- ドキュメント間の相互参照をハイパーリンクに置き換える
また、Webからのデータの入力や編集を可能としたいなら、なんらかの入力フォームを生成できると便利です。野生のデータでは、データ形式が非定形で多様になるので、単一形式の入力フォームではまかないきれず、多数の入力フォームが必要になるかもしれません。入力フォームに対応するバリデーションも必要です。
後で述べるドキュメントへの処理は、Webリクエスト時に実行することもあります。シーケンスに対する処理でも比較的に軽い処理なら、同じくWebリクエスト時に行えるでしょう。これらのデータ処理がすぐさま使えることが重要です。
安心して変更できること
データ・ブリーディングでは、個々のデータもデータの全体も変更していくのが前提です。しかし、変更はとても恐いものです。データを変更すれば、データ相互の関連性に不整合が生じたり、データを扱うプログラムが動かなくなる危険があります。だから、変更したくても出来ないことが多いのです。
変更により改善や適応をし続けるためには、「変更したら何が起きるか分からない」という懸念や恐怖感を払拭してくれる仕掛けが必要です。変更しても以前と互換性があることを保証してくれる、あるいは、互換性が壊れる場所はどこかを正確に指摘してくれる、そういう仕掛けです。
事前に処理の実験をしてみるためには、テスト用データの生成や、実データのサンプリングの機能も必要でしょう。互換性が壊れる場合の半自動的なデータ移行手段もないと困ります。
安心して変更できること -- これは、データ・ブリーディングを支える最も重要な要件だと思います。
ドキュメントへの処理
単一のドキュメントを加工したり、2つのドキュメントから新しいドキュメントを合成するには、次のような処理があります。
- フィールドパスによる部分ドキュメントの抽出
- フィールドグループによる射影
- フィールド名のリネーム
- より一般的なフィールド再構成や定数データの追加
- 参照を埋め込み部分ドキュメントに置換する(脱参照)
- 埋め込み部分ドキュメントを参照にする(参照化)
- フィールドごとのデータ形式変換
- フィールド値からの計算とその結果の挿入
- 複数のドキュメントのマージ
ドキュメントのシーケンスへの処理
コレクションに含まれるドキュメントをすべて列挙したり、あるいは問い合わせにより絞り込んだ結果は、ドキュメントのシーケンス(順序が付いた並び)になります。それらのシーケンスに対する処理には次があります。
- マップ: シーケンスに含まれるすべてのドキュメントに、同じ処理を適用した結果のシーケンスを作る
- フィルター: シーケンスに含まれるドキュメントのなかから、条件を満たすドキュメントを選び出したシーケンスを作る
- フォールド: 初期値からスタートして、シーケンスに含まれるドキュメントとの処理結果を次々と引き渡して処理をした結果を求める。(「foldrとfoldl」参照)
- ジップ: 2つのシーケンスからドキュメントを1つずつ取って作ったペアを並べたシーケンスを作る。
- 分配: 1つのドキュメントを、シーケンスの各ドキュメントと組み合わせたペアからなるシーケンスを作る。
- マルチプレキシング: 複数のシーケンスを混ぜて1つのシーケンスにまとめ上げる。
ご指摘・ご意見・ご要望を
以上にざっと述べたのが、今の僕の考えです。
我々は、上記のような操作・作業に対してある程度の経験を積み、知見と方針を得たとは思いますが、その範囲は「ある程度」であり、見落としや勘違いがあるかもしれません。また、もっとよい方法に気付いてないかもしれません。という次第で、ご指摘・ご意見・ご要望がありましたら、どうかお知らせください。(ブックマークでもコメントでも hiyama{at}chimaira{dot}org でもトラックバックでも何でも。)