Entry

みんなが知ってる SQL と DAO の利点とか

2009年05月02日

個人的に SQL って, HTML と同じくらい基礎的な話だと思ってるんだけれども,こちらの話から。

たいがいの「業務アプリ」は、フロントエンドがWebであろうがクライアントアプリであろうが、データの本体はRDBMSにあり、それを操作するのはSQLです。よって、オブジェクト指向を駆使してクラス設計をして……という作業はまず入ってこない。私は銀行のプログラムを書いたことはないけれど、教科書に出てきそうな「BankAccontクラス」って実在するんでしょうか。BankAccountテーブルを操作するためのユーティリティクラスでもなく、BankAccountテーブルのレコードを表現するための構造体的なクラスでもない、インスタンスが実際の「口座」と1:1に対応してそれに対する操作を公開しているようなものって。

(snip)

実際仕事でWebアプリを開発するのにプログラマを雇うなら、JavaやC#やオブジェクト指向に詳しい人よりSQLのエキスパートを雇いたいです。私は。

業務アプリの業務部分で、オブジェクト指向なんか使わないよね - プログラミング言語を作る日記

Web アプリを作るのに HTML 知りませんっていう人が「何しにきたの?」な人なのと同様に,RDBMS を利用するアプリを作る人が SQL を知らないのは,かなりイタい。

つか,SQL ってのは,もともと EUC(End User Computing のこと。Extended UNIX Code ではない。)の文脈にあったもんで,要するに事務のおばちゃんなんかが,必要なデータを取り出したり登録したりするのに使う問い合わせ言語==Query Language という位置づけだったりしました(プログラミング言語ではない)。んなもんで, SQL なんつのは,開発者だからこそ使いこなせる言語じゃないと思ってたりする。HTML 書けます!とか Excel 使えます!とかいった話と同じ感じ。

と,SQL に対する位置づけがそんなんだから,「オブジェクト指向よりも SQL」なる話も比べる水準が違うんでねいか,と思ったりします。「SQL のエキスパート」ってだけで雇ってくれるところ,あたしも行きたい!「MFC に詳しい人よりも Excel のエキスパートを雇いたい」と言ってるのと同じに聞こえるんだけれども……ん?事務屋募集?

引用に戻ると,「インスタンスが実際の「口座」と1:1に対応してそれに対する操作を公開しているようなもの」ってのは,ちと具体例が思いつかなかったんですけれど,BankAccont クラスみたいなクラスで永続層(データストレージ層)を抽象化することは,よくしている気がしています。要するに,DAO クラスを作るってなことなんですが。反対に,引用にいわゆる話が,ビジネス層(本文にいう業務部分)に SQL を直接埋め込むってなことだとすると,あまりしない。あたしの周りの話だけれど。

永続層の対象を RDBMS にした場合,DAO のメソッドには,直接的であれ間接的であれ,SQL が埋め込まれるわけですけれど,こういうクラス構成にするのには理由があります。つか,この理由を踏まえてないと,デザパタを採用する意味がないし,この理由に当てはまらないなら,直接 SQL を埋め込んだ方が早い気がします。

理由っつのはこゆモノ。

  1. データアクセスをクラスに抽象化することで,具体的なデータソースをビジネス層から隠蔽できる。
  2. データベースの物理構成(テーブル構成)に対して,ビジネス層が依存しないで済む。
  3. 永続層に対するアクセス,DAO のタイミングでデータベースにアクセスできる。
  4. SQL になじみのないプログラマが SQL を意識しないで永続層にアクセスできる。

一般に,O/R マッパや Rails なんかで作られるクラス/オブジェクトの目的は,最後の理由(4)が主たる目的なんだと思います。もっぱら初心者向けの理由なんですけれど,普通のプログラマでも,オープンしたコネクションを閉じないままにしちゃうミスがたまにある。こゆミスを減らすために,オブジェクトの破棄と同時に自動的にコネクションを閉じてくれるような仕組みがあると,システム全体から見て品質(信頼性)は向上します(大抵の DAO は RDBMS のオープン/クローズを親クラスにまとめていて,デストラクタでクローズするようにしている)。つことで,それだけでも,DB アクセスをクラスにまとめる利点はある。

一方で,DAO を作る目的は,もっと重要なところにあります。大抵,上流がグニャグニャなときに有効なんですが。

まず,1 と 2 について。

具体的なデータソースを隠蔽することができるってのは,要するに,データソースが変わっても,インターフェイスさえ決まっていれば,ビジネス層がその変更を意識する必要がない,という意味です。例えば,今は SQLite を使ってるけれど,将来的に Oracle に変更します,とかいった場合でも,ビジネス層がその変更を意識する必要がなくなる。修正点は DAO だけになります。これは,永続層が CSV ファイルや XML-DB のような RDBMS 以外になる場合(ウェブサービスを使うとか)でも,ビジネス層はそれを意識しなくて済むということでもある。

また,データソースのカプセル化は,作業を分担するときにも有効です。ライブラリも含めて10万ステップ程度のシステムでは,それほど意識しないだろうけれども,50万ステップとか100万ステップとかいった規模になると,ひとりふたりでは作業できなくなってきます。データベースを専門的に管理するチームも編成されたりする。このとき,データベースが決まらなかったら,ビジネス層の実装に入れないってなことになるのはあほらしいわけで,適当なスタブを作ることになります。また,特に受託案件なんかでは,客先の環境とまったく同じ開発環境を用意できないこともある。こゆときに,(Java でいうなら)使うインターフェイスだけを決めて implement しておけば,ビジネスオブジェクトだけで作業できるし,単体テストもできるようになります。分担をきっちり分けることができるわけです。

また,カラムを削除しましたとか,テーブルを分割しましたとか,直接テーブルを見ていたけれど view を参照するように変更しますとかいった修正が入った場合にも,DAO で抽象化しておけば,その内部を修正するだけで足ります。反面,ビジネス層に直接 SQL を埋め込んでいると,すべての SQL について修正を加える必要が出てくる。当然,バグを埋め込む機会も増えてしまいます。DAO パターンを使うのは,こういう理由が一番大きいと思います。

最後に 3 について。

RDBMS にアクセスしてデータを取得する場合,更新はあまりしないけれどよく参照されるテーブルを利用することもあります。業務アプリで言うなら,社員テーブルなんつのはほとんど更新されない割によく参照される。で,こゆテーブルにアクセスするときに,本当にコネクションを開いてアクセスするのは無駄です。ほとんどの場合,さっきと同じデータが返ってくるからです。こゆ場合,プログラムのレベルで結果をキャッシュしておけば,パフォーマンスも上がるし,無駄なトラフィックを減らすこともできます。これを,DAO に担当させるってな考え方がある。クラス変数に参照結果を取っておくわけです。

もう少し一般的に言えば,DAO でデータアクセスの要求をフックして,永続層にアクセスするタイミングを制御することができる,と言える。最近の RDBMS は高機能だから,ある程度参照結果を賢く取っておいてくれるけれども,業務に特化したアクセス方法がある場合,アプリケーションのレベルで制御する方が適切なこともあります。ま,そんな便利機能も実装できますよ,と。

今,あたしゃ新人君の教育係をしていて,新人君には OracleConnection から自前でデータアクセスするように課題をこなしてもらっていたりします。DAO を使わない方法も検討してもらったんですけど,結局作ることにしたみたい。こゆ判断の段階から検討してもらった理由は,DAO を作る利点と欠点を実際に感じてもらいたいからだったりします。O/R マッパを使うにしても,要件を自分で判断しなくちゃいけないときに,見るべきポイントが分かるんじゃないかと思ったりします。

ともかくですね。ビジネス層からオブジェクト経由で RDBMS にアクセスすることは,よくある話デスヨ。という話。

Trackback
Trackback URL:
[2009年05月08日 01:14] もぼなもな書房  UNIXプログラミング環境 (海外ブックス) from もぼなもな書房
いまどき、シェルの基本的な使い方から lex+yacc を使ったパーサ作成法にまで広範囲に言及したプログラミングの本はそうそう見つからない。... [more]
Ads
About
Search This Site
Ads
Categories
Recent Entries
Log Archive
Syndicate This Site
Info.
クリエイティブ・コモンズ・ライセンス
Movable Type 3.36
Valid XHTML 1.1!
Valid CSS!
ブログタイムズ

© 2003-2012 AIAN