2008年7月1日火曜日

Rails、Hibernate、EJB スキーママッピングあれこれ

久し振りの更新。普段、突発的にものを書きたくなる衝動をブログにぶつけていたのですが、最近はそれがTwitterに吸収されてしまっています。短い単発コメントより、まとまった文章がある方が本当は価値が高いんですけどね。今日はTwitterが重いので、ブログに戻ってきました。

閑話休題。

SIGMOD2008に参加してみて不思議だったのは、Schema Mappingの研究が想像以上に盛んだったこと。これは、データベースのスキーマ(テーブル構造情報)を、他のスキーマへと変換するときに使います。データベースの移行とか、アプリケーションに合わせて形を書き換えるとか。

でも、そもそもマッピングって、足し算が入るだけでも、不可逆変換なんですよね。1+2を合わせて、「3」というデータを作ったとき、この「3」というデータは、1+2の結果か、2+1の結果かわからなくなる。そうすると、マッピングに使える演算の種類は限られてきます。

SIGMOD2007のベストペーパー、Compiling Mappings to Bridge Applications and Databasesにあるように、テーブルデータ -> オブジェクトというマッピングをし、オブジェクトの更新結果をテーブルデータに正しく反映させるといった、roundtrip制約を入れると、使えるマッピングの種類を限定せざるを得ません。Join演算なんてもってのほかです。

問題を、オブジェクト(Javaのクラスなど)とテーブルデータ(relational database)の構造の違い(impedance mismatch)の吸収に絞ると、すでに世間で実用化されている技術がいくつかあります。Ruby on Rails, EJB3.0 (Enterprise Java Beans), Hibernateなどがその代表でしょう。

それぞれの一長一短(pros and cons)

Rails: テーブルの列名に対応したメソッドを自動追加するので(Person.id, Person.name, ...などでアクセス)、簡単なスキーマ変更(カラムを増やす、など)なら、ソースコードの変更が不要。ただし、実行時に初めてわかるメソッドなので、コンパイラによる静的チェックの恩恵が受けられない。実際に、動かしてみるまでプログラムが正しく動くかどうかわかりません。

EJB3.0: Javaのクラス定義と、テーブルデータをAnnotationなどを駆使して対応させます。テーブル名、カラム名とクラス名、メソッド名が食い違う場合はAnnotationを使って細かい対応付けができるのが売り。Data Access Objectを通して、オブジェクトを更新、テーブルに反映させるという手順。ただし、1つのオブジェクト定義でも、文脈に応じて、別々のテーブルに格納したいことがあります。たとえば、Personクラスを、student, teacherテーブルへ。student(Personクラスに対応)の一部を、alumniテーブルに格納したい、などなど。クラス定義の中に対応するテーブル名やカラム名を含める設計だと、この目的には対応できません。ここはぜひ分離してほしいところ。(Railsも、クラスに対応するテーブル名は決め打ちです。プログラミングはとても簡単な反面、オブジェクトの使いまわしは難しい。一応、オブジェクトに対応するテーブル名は設定可能ですが)

Hibernate: 僕はこのtutorialを読むだけでがっかりしました。こちらにも解説書のサンプルがあります。Javaのクラスと、テーブルデータベースの違いを吸収するのに、XMLで書かれたマッピングファイルが必要なんです。EJB3.0も裏でHibernateを使っているようです。なんだ、なんだ?。これだと、クラスを書き換えたら、XMLも書き換える必要がある。そのXMLファイルをクラスファイルから自動生成できるのかもしれないけれど、Javaのリフレクションを使えばXMLをあらかじめ用意する必要なんてないはず。設定ファイルが多い(ある)という点で、Railsほどの簡潔さ、わくわく感はありません。


明示的であれ暗黙的であれ設定項目を把握するまで動作が理解できないスキーママッピングなら、技術としての重要性は低いように思う。Railsのようにマッピングを決め打ちできる状況は多いと感じるし、テーブル型データとオブジェクト間のimpedance mismatchがそれほどあるとも思えません。現に、Object-Relational Databaseというように、Reational databaseは、様々な形のオブジェクトを保存できるように成長しています。


データベースのデータを扱うのが、プログラム言語中であるなら、プログラム中で使うクラス定義(オブジェクト)がスキーマそのものです。オブジェクトをそのまま保存できれば事足ります。テーブル名、カラム名なんてプログラム中で気にする必要はないはず。それに加えて、オブジェクトをどのような位置(コンテキスト)に保存するかが選択できればよい。たとえば、2007年度のデータ、2008年度のデータなど、フォルダでファイルを管理するのと同じように、データを保存する位置を決める。この2点ができれば、データベースの機能としては十分なんじゃないかと思います。

コンテキストを表す能力が高いのはXMLだし、定型データを扱うのはRelational Databaseの得意技。データベースの研究者として、両者の融合をもう少し進めていきたいところです。

0 件のコメント:

コメントを投稿