オブジェクト指向と RDBMS
オブジェクト指向と RDBMS のインピーダンスミスマッチの件についてはもういろんなところで書き尽くされていて、ここで書くようなことでもないのですが、後で「あのころは若かった」とか思えるので自分用にメモしてみる。
オブジェクト指向というのは、クラスと呼ばれるくくりの中に、データとそれについての処理をパックして記述できるプログラム言語仕様のひとつです。 PHP でも一部実装されています。
この設計の根底にある思想は “それに関する処理は同一箇所に書こう” だと思います。 オブジェクト指向を使うと、手続き型では実現できない部分まで “それに関する処理は同一箇所に” まとめて書くことができます。
趣味でやっていると、手続き型は分かるけどオブジェクト指向は分からないという人も結構いると思いますが、まずは使いどころをこの “それに関する処理は同一箇所に書ける構文” として考えればスッと入れるです。 よく”果物”基底クラスをつくって、それを継承して、”りんご”クラスと”すいか”クラスをつくる、、とかって解説がありますが、あれは分かっている人しか分からない説明…。 そんなプログラムつくらんって(笑
これならきっと分かる。
たとえば、サイト管理者が入力するエントリと、読者が入力するコメントを例に。 両方ともいろいろデータ要素はありますが、それぞれ似たような情報を持ちます。 名前、入力日付、等々基本的なものはいっしょ。 逆に差異を考えると、たとえばエントリにはタイトルがあったりカテゴリがあったり。
じゃー共通部分を”基底”クラスにしよう。 いっしょなんだし。 で、クラスはデータだけじゃなくて処理も一緒に書けるので、投稿のタグのチェックとか今の日付の取得いれちゃえ。 そんなの一カ所にしか書きたくない。 クラスの名前は BlogDocument クラスだ。
- class BlogDocument {
- // データ
- var $content;
- var $date;
- var $auther;
- // 処理
- function setContent($content) {
- $this->content = タグ処理しろ($content);
- }
- function setDate() {
- $this->date = 今の時間();
- }
- ...略
- }
とこんな感じに。 で、実際のエントリクラスとコメントクラスを BlogDocument から”継承”します。 差分があれば追加。
- class BlogEntry extends BlogDocument {
- // データ
- var $title;
- var $category;
- // 処理
- ...略
- }
- class BlogComment extends BlogDocument {
- // BlogDocument と同じだからからっぽ
- }
とか、ね。
似たような性質を持つものの処理を分散することなく記述できるのがオブジェクト指向の強みです。 で、これらのオブジェクトを必要な数だけ(エントリとかコメント数ぶん)実体化(インスタンスをつくる)してあげれば、ブログの内部構造はできて、これに入出力をしてあげれば動き出します。
もうちょっと書くと、処理で2つのクラスの差分を意識しなくていい場合はそれぞれは基底クラスとして処理ができる。 要は見た目違うものなのに、同じループで BlogEntry も BlogComment も BlogDocument として処理できるというトリックも使えます。(ならではの格好いいトリックは他にもまだまだあるです)
上はあくまでイメージで、たとえば BlogDocument には親子関係を持たせないと、どれがどのコメントかわからんとかいろいろでてきます。 じゃー、BlogDocument の中にさらに子になる BlogDocument もたせちゃお、とか。 クラス設計していると結構楽しいのですが・・・。(ちなみに WP は、エントリとコメントは別扱いです)
こんなことをやっていると、ひとつの大きな壁が立ちはだかります。
リレーショナルデータベース。 WP なら MySQL。
プログラムで作られたオブジェクトというのは、メモリ空間に存在します。 ということで、プログラムが終わったらぜんぶ、ぱー。
PHP/Web 環境は、アプリケーションコンテナを持たないので、Web アクセス終了と同時にオブジェクトは破棄。消失。 せっかくシステムが動いたのに、ひとっつもエントリを保存できないで終わります。 とほほ。
Java 環境とかだと、アプリケーションコンテナが使えるのでアプリは起動しっぱなしにできる。 なので、起動している間は覚えておけますが、それでも終わらせればなくなってしまいます。
どちらにしろ、なにかしら保存する手段が必要ってことで、RDBMS が登場してきます。
つくったオブジェクトをそのまんま RDBMS に保存(永続化)できればいいのですが、データベースはご存じの通り2次元のテーブル構成。 書き込む処理系は SQL。
オブジェクトは、継承ができたり、その中にさらにオブジェクトを持てたりしてツリー的なときもあって、そもそも2次元にそのまんまはいらないし、そうでないときもわざわざ SQL を生成して RDBMS のテーブル構成に合わせて保存処理をかかなきゃいけません。 これが、インピーダンスミスマッチ。 異なるものの対応処理をしなければならないのです。
ぼく的には、オブジェクトの管理はメモリでやっとけ。 足りなくなったらいい感じに仮想メモリつかえ。 アプリ落ちるときは、適当にシリアライズして保存しとけ。 起動するときは元に戻せよ。 みたいになってくれると嬉しいのですが、まぁまぁそうもいかない事情があります。
というわけで、保存処理を簡略化しようという動きが O/R マッピングツールというやつです。 有名なのは hibernate とか。
O/Rマッピング(=Object / Relational Mappingの略称でORMと略されることもあります)とは、オブジェクト指向言語で扱う「オブジェクト」と「リレーショナルデータベース(RDB)のレコード」をマッピング(対応付け)することです。アプリケーションにO/Rマッピングを導入することで、オブジェクトへのデータ取得やオブジェクトデータの永続化といった処理を透過的に行うことができるようになります。またO/Rマッピングはプログラミングでのデータベース操作にかかわる煩雑な作業を軽減し、拡張性・柔軟性を持ったアプリケーションの構築をサポートします。
データベースには SQL を発行せず、いくつかのマッピングを書くことで永続化が可能。 データ検索も、(みため)オブジェクトに対して HQL とよばれる SQL に似た検索クエリーをなげると、ちゃんとオブジェクトに返ってきます。
弱点は、マッピングを作らなければいけないことと、やっぱりなにより RDBMS の制約、2次元を意識しなければいけないので、データベースよりのオブジェクト設計を強いられることです。 自由には行かない。
ってことで、ちょっと前に流行りかけたのがオブジェクトデータベース。 RDBMS じゃ無理だから、オブジェクトそのまんま永続化してあげるよってのがコンセプト。 まだちゃんと開発が進んでいるのに、db4o というのがあるようです。
IBM 多忙な Java 開発者のための db4o ガイド: 紹介と概要 – Japan
しかし、たとえ Hibernate (あるいは JPA や JDO、Castor JDO、Toplink あるいはどのような ORM ツール) を使ったとしても、マッピングの問題がなくなることはなく、単に構成ファイルの中に問題が移動するだけです。しかも、不適切なツールを無理やり使っているという感覚が避けられません。例えば、適切に階層化された継承モデルを作成しようとする場合、そのモデルを 1 つあるいは一連の表にマップするためには、どれも醜悪な選択肢を比較検討して 1 つを選ばなければなりません。クエリーのパフォーマンスと通常のフォームに違反することのどちらを重視するかをめぐって、どこかの時点で DBA と開発者が戦う羽目になります。
IBM のこの手の記事は読んでいておもしろいですね。 🙂
で、これを使えばハッピーになれるかというと、やったことないけど、方式的な不具合がない限りはそのアプリケーションにとってはハッピーなんだと思う。
ただ、ぱっと思いつくのがそのアプリ以外のインターフェースを使った検索やデータの修正がある場合。 そして、これはよくあるケース。
やっぱり、2次元の RDBMS は管理しやすいじゃないかなとか。 データのパッチとかいくらでもできるし、SQL からの検索は枯れたものだし、直感的です。
うーむ。
—
なんて考えている時間が案外好きだったりするんですが、、 うわ、なげっ。 って朝だ。 😛
5 Comments
Trackback
Comment
-
From: Sa・Ga - 2007/6/10 Sunday (Comment)
うっ! 「Hibernate」とは!
先月入社した会社でこいつに悩まされています。
前任者がこれを導入していたのですが、正直ワケワカメですね。Web上でも、少なくとも日本語による解説はほとんどないし。
あまりにワケワカメですので、自分の担当箇所では結局SQLを投げています。ダメじゃん!
-
From: ひろまさ - 2007/6/10 Sunday (Comment)
> あまりにワケワカメですので、自分の担当箇所では結局SQLを投げています。ダメじゃん!
わかりますー。
DB 先に設計するパターンだと、Bean につめる機能だけ使って、結局 SQL なげることになるんですよねー。(笑)
-
From: Richard the Boyce‐Codd normal form - 2007/6/12 Tuesday (Comment)
RDBへのアクセスも、DBMSのファンクションやプロシジャ経由のアクセスに限定する!という自分への十字架を課すことにより、気持ちだけでもカプセル化できたりします。
Oracleなんかでもいつの時代からか「更新可能なビュー」がサポートされるようになったので、これだとクラスインヘリタンスなんかも擬似的に再現できるよね。
カプセル&インヘリで隠蔽した内部で、2次元×Nの処理を実装する事により、多次元オブジェクト指向DBは可能かも。
健闘をお祈りします。
-
From: ひろまさ - 2007/6/14 Thursday (Comment)
なるほど。 💡 ビューって手がありますね。 テーブルつなげて、継承っぽくできるんだ。 Oracle だと再起の SQL 使えるからツリーも表現できそう…。
そっか、どこのレイヤーでデータ処理するのかという問題もあるんですよね。。 うーむ、眠れなくなります。。 😳
-
From: Sa・Ga - 2007/6/10 Sunday (Comment)
うっ! 「Hibernate」とは!
先月入社した会社でこいつに悩まされています。前任者がこれを導入していたのですが、正直ワケワカメですね。Web上でも、少なくとも日本語による解説はほとんどないし。
あまりにワケワカメですので、自分の担当箇所では結局SQLを投げています。ダメじゃん! -
From: ひろまさ - 2007/6/10 Sunday (Comment)
> あまりにワケワカメですので、自分の担当箇所では結局SQLを投げています。ダメじゃん!
わかりますー。
DB 先に設計するパターンだと、Bean につめる機能だけ使って、結局 SQL なげることになるんですよねー。(笑)
-
From: Richard the Boyce‐Codd normal form - 2007/6/12 Tuesday (Comment)
RDBへのアクセスも、DBMSのファンクションやプロシジャ経由のアクセスに限定する!という自分への十字架を課すことにより、気持ちだけでもカプセル化できたりします。
Oracleなんかでもいつの時代からか「更新可能なビュー」がサポートされるようになったので、これだとクラスインヘリタンスなんかも擬似的に再現できるよね。
カプセル&インヘリで隠蔽した内部で、2次元×Nの処理を実装する事により、多次元オブジェクト指向DBは可能かも。
健闘をお祈りします。 -
From: ひろまさ - 2007/6/14 Thursday (Comment)
なるほど。 💡 ビューって手がありますね。 テーブルつなげて、継承っぽくできるんだ。 Oracle だと再起の SQL 使えるからツリーも表現できそう…。
そっか、どこのレイヤーでデータ処理するのかという問題もあるんですよね。。 うーむ、眠れなくなります。。 😳
From: 2mg xanax bars on line. - 2008/11/1 Saturday (Trackback)
What are xanax bars….
Illegal xanax bars. Pictures of xanax bars. Xanax bars images. Buy xanax bars online. Xanax bars….
[続きを読む]