« ショボいDB設計で突っ走るための50の方法 | トップページ | マスターテーブルと「有効期間」 »

2012.02.22

開発基盤のトリガーとDBMSのトリガー

 初めて「トリガー(トリガーファンクション)」を試したのは、90年代の初頭だった。テーブルの追加・更新・削除の前後で自動実行されるコードを自在に組み込める。たとえば「出荷実績エントリー」等のアプリにおいて、取引履歴の書き出しや売掛・在庫残高の更新をトリガーで実行させてみた。それまでアプリ上にごちゃごちゃ乗っていたコードが消えて見通しが良くなった。

 試行錯誤するうちに、アプリが抱えるべきコードはもっと少量で済むことに気づいた。一次テーブルを更新したときに他の関連テーブルに対してどんな更新処理がなされるかについては、アプリ上ではなく一次テーブル上の記述とみなせる。フィールド値の妥当性検査や導出フィールドの設定といった仕様も、それを含むテーブル固有の記述とみなせる。ようするに多くのアプリは、醜怪なほどに個性的な太りかたをしている。業務システムのアプリは、本来もっと「薄っぺらでありきたり」で済む。

 ここらへんは一般に「記述の凝集度(cohesion)」として知られる問題だ。たとえば文章において、パラグラフの内容をひとつのトピックに限定することで、各パラグラフの凝集度が高まり読みやすくなる。いわゆる「MECE(相互にヌケなくダブリなく)の原則」に似ている。システムの記述要素も同様で、以前にも書いたように「カエサルのものはカエサルへ、テーブルのものはテーブルへ返しなさい」である。その目的のためにトリガーは好都合なしくみで、たちまち私のお気に入りとなった。

 さて、私が愛用していたトリガーは開発基盤上で実装されたものだったが、一般によく知られているトリガーはDBMSの固有フィーチャとして搭載されているほうだろう。つまりトリガーには「開発基盤上のトリガー」と「DBMS上のトリガー」の2種類がある。使い勝手はどう違うのだろう。

 開発基盤上のトリガーに馴染んだ身には、DBMS上のトリガーはいくつかの点で使いにくい。まず、RDBMS毎にやれることが微妙に違うので、どのDBMSを使うかによってアプリ側の記述が変わり得る(トリガー以外の固有フィーチャを使う場合にも同様の問題が生じる)。異種DBが連係するシステムではいかにも面倒なことになろう。また、アプリとトリガーとの相互通信が制限される点も辛い。

 とくに気になる問題が、「アプリの仕様」と「テーブルの仕様(トリガー定義を含む)」とが、システム記述として「分断」される点だ。この指摘は「アプリの仕様とテーブルの仕様はそれぞれより凝集されるべきである」という主張とは矛盾しない。それらは凝集されつつも、システム記述としての「連続性」や「透明性」が確保されていなければいけない。

 どういうことか。システムというものは巨大な「言葉の構築物」であって、それを確実に読解することでしか保守できない。ゆえに、さまざまな仕様要素やそれらのクロスレファレンスを「ワンストップ」で眺め回せるようでなければいけない。あるアプリが一次テーブルをどのように操作するか、そしてその操作を起点としてどんな処理が起動されるか。トリガーで記述された仕様を含め、そこらへんの局面全体を把握しない限り、関連する仕様要素をMECEに配置できない。

 ようするに私にとってトリガーの利便性の要(かなめ)は、「仕様の凝集性」とともに、逆説的ながら「アプリとの連続性」である。アプリ連係としての連続性だけでなく、システム仕様の連続性を確保する。そのためには開発基盤上で実装されたトリガーのほうが都合がよい。「実行可能な仕様書」を実現するための開発基盤を自作するにあたって基盤上のトリガーの実装にこだわったのは、そんな経緯からだった。

本ブログでの参考記事
妥当性検査をDB側に集約する

|

« ショボいDB設計で突っ走るための50の方法 | トップページ | マスターテーブルと「有効期間」 »

コメント

DBMSで提供されているトリガーを採用しなかった理由が分かって勉強になります。
ただ処理速度という点では、どうなんでしょうか?
DBMSのトリガーで行う場合と比べて遜色ないのでしょうか?
(エンドユーザーにとって問題になるのは処理速度だと思うので)

投稿: 久保田英雄 | 2012.02.24 15:03

渡辺様ごぶさたしております。XEAD超マニアの伊藤です。http://incomesoft.net

 データベーススペシャリスト国家試験に14回?落ち続けている脳みそを持っていますが、
今回の記事で開発基盤のトリガーの内容がわかり易く、理解が深まりました。

 XEAD Modeler から Windows 8 、Windows Embedded 、Windows Phone 7、Kinect 、LightSwitch、MVC4(マルチディスプレイ用)など
の対応した実装のデモライブラリサイトなどを作る時、
開発基盤のトリガーっぽいものを用意しておけば、
私の思うプラモデルが簡単になり、XEAD Modelerファン増加に繋がると感じました。

 まだ大した成果も出せておりませんが、15回目も落ちる?者の発言としてお許しを。

投稿: 伊藤秀樹 | 2012.02.25 09:06

あっ、HTML5とAzure 対応が抜けてた!
すいません、追加させて下さい。

投稿: 伊藤秀樹 | 2012.02.25 09:23

久保田さま

短い処理だろうが長い処理だろうが、そのロジックがどこに置かれるかだけの違いなので、トリガーにしたゆえに遅くなるということはありませんね。

ただ、「バリデーションの双方向性問題を解く」の記事で書いたように、開発基盤のトリガーとすることで、更新時の「逆方向バリデーション」の自動化が可能になります。テーブルによってはこの処理に時間がかかるのですが、いろいろと工夫のできるところでもあります。

伊藤さま

さすが、手広くやってはりますねえ。感心します。

開発基盤でトリガーを実装するほうが、よほど柔軟にやれますよね。たとえば、数値フィールドが1000以下ならアプリ上ではこの色で表示させる、なんて仕様さえトリガーで書けます。DBMSのトリガーなんて使えなくなりますよ(><)

投稿: わたなべ | 2012.02.25 11:14

開発基盤のトリガーの例として
渡辺さんのOSS、XEAD Driverの仕掛けをのぞいてみると、
サンプルシステムのFT010(発注見出し)のスクリプトが良い例ですね。

実行タイミング、(読込、追加、更新、削除)の(前・後)のチェックを指定することで
記述したスクリプトを指定のタイミング動作することができる。

このスクリプトは、java scriptで記述しているが、
XEAD Driver内の関数を呼び出すことにより、他テーブルのCRUD処理もできる。

createTableOperator('Select', 'FT011');のような関数が用意され、
ORマッパとしての機能も仕組まれている。

xeafファイル上にテキストリソースとして記述されているjava scriptが
Rhinoを利用することで本体とシームレスに連携し
異種のデータベース間をシームレスに接続しています。

良い素材を取り揃えて、旨い料理をスピーディに仕上げる料理人のようだ。

投稿: 黒麹 | 2012.02.25 11:47

コメントを書く



(ウェブ上には掲載しません)




トラックバック


この記事へのトラックバック一覧です: 開発基盤のトリガーとDBMSのトリガー:

« ショボいDB設計で突っ走るための50の方法 | トップページ | マスターテーブルと「有効期間」 »