http://d.hatena.ne.jp/JavaBlack/20061031
ん〜コメント欄がえらい荒れてますな(−人−)
自分のホムペなりブログにでも書いたらいいのに。
ってかストアドプロシージャと単なるSQLを混同してたりしてまいか。


それはさておき。


JavaとOracleを使って業務システムを開発しています
ストアドプロシージャ(めんどいから以下PL/SQLと記)は特性をもった武器。
そんなクセの強い武器を使いこなすか振り回されるかそもそも使わないか3つに1つだ。
構成次第で薬も毒に変わる。逆もまた真なり。


明確な目的を持たないままであれやこれやと議論しても、
結論なんざでる理由が無い。
PL/SQLを使う目的はなんだーというと
 (1) パフォーマンスがほしい
 (2) 記述の容易さがいい
 (3) 適材適所の政治的判断のため
こんな感じ。
それとは別で、ビジネスロジックをいれるかどうかの問題は
プログラム構成にも関わってくるけれど、
ふつーUI側にあるのが望ましい。


シンプルな構成でシンプルなコード作るのが一番ですよと思いつつも、
個人的見解は以下へと続く。

パフォーマンスと記述について

例えば
「3つのテーブルからあれやこれやとデータを取って項目と一部の計算結果を取得する」
というお題があった時に、どう実現するかは技術者次第になるもの。
 (1) Javaだけ
 (2) JavaPL/SQL
この選択肢になるのだけれど、もちっと詳細化すると
 (1)-1 1本のSQL文作成 → 発行 → 1撃で取得
 (1)-2 何個かののSQL文作成 → 都度発行 → 都度取得 → ロジック内でデータ作成(集計)
 (1)-3 Viewを作っておく → 1本のSQL文作成 → 発行 → 1撃で取得
PL/SQLを使用する際にはワークテーブルとかテンポラリテーブルの存在がこっそり欠かせません。*1
 (2)-1 PL/SQL内で(1)-1みたいなことやる
   ※ワークテーブル作成(初期化)
    → 1撃でデータをInsert
 (2)-2 PL/SQL内で(1)-2みたいなこと
   ワークテーブル作成(初期化)
    → メインのテーブルからデータをInsert
    → サブのテーブルその1から特定の項目Update
    → サブのテーブルその2から特定の項目Update
    → その他計算するところをUpdate
 (2)-3 Viewを作っておく → PL/SQL内で(1)-3みたいなこと


世の中のプロジェクトは数あれど。
(1)-1で問題がでないことなどゼロだゼロ。
作りにくいしメンテしにくいし改変なんざ神頼み。
(1)-2がよいかというとそんなことはもちろんない。
(2)-1はそれならView作れやとなるし、
(2)-3など何の意味もなく、
選択肢として残るのは(1)-3か(2)-2。


余談だけど、(1)-1でやるのと、(2)-2でやるのとの実測値の差を測ったことがあって。
イメージ的に(1)-1のが早そうに思っていたけど現実は圧倒的に(2)-2のが速かった。
PL/SQLすげーと思ったものですよ。


(1)-1と(1)-3は実測的にはたいした差は無く、
複雑なSQLJavaに書くかView定義に書くかの違いが主。
SQL大好きなら(1)-3でいいんでないかなと思わなくも無い。
記述だけでみるなら断然Viewの方が楽に書ける。


ちなみに。
1開発者としては、状況が許す限り(2)-2を選ぶ。
速度で早く、開発が楽で、メンテナンスが容易だから。
速度は上記の通りで、
開発が楽なのは複雑怪奇なSQLに頭を悩ます必要がないから。
データを如何にして取ってくるかを悩んで試行錯誤するのと、
右から左に動かしてそれを確認するのとどっちが楽でしょうってのの解が理由。
頭を悩ます必要がなくなればメンテナンスも容易ですよとそーゆーことですよ。

*1:UIから呼ばれてデータ表示する処理において、データを取得するための場所はいらないはずがない

適材適所

SQLとは難しいのです。
変なテーブル構成があったりするから。


ドメインロジックとSQL

SQL内にロジック(Logic in SQL
では、SQLの機能を目一杯使ってみよう。
(中略)
これを「複雑なクエリ」と呼んだが、あくまでも先ほどの例で使った簡単な select と where だけのクエリと比べて複雑だ、という意味だ。

おいらには十分複雑なクエリに見えますが何か。

SQLクエリはもっと複雑なことが出来る。ただ、アプリケーション開発者はこれくらい複雑なだけでも避けちゃうんだよね。

出来るのと現実的かどうかはまったく違うぞ。
そんな複雑なことが何個でてくるかまで考えているのかこいつ。
数回試してみるのと百回にたようなのを書く必要がある場合では必然としてアプローチは違うから避けようとするの。


っつかこの実験は上記でいうところの(1)-1と(1)-2の比較であって、
ストアドプロシージャを利用した解ではない。
実績値で語れば(1)-1より(2)-2のが速い。
SQLだけでわーい3倍速い〜と喜んでみたところでストアド使えば100倍くらい速い。
実行結果時間の単位を秒単位から1/100秒単位に落としたら20倍も3倍も誤差の範囲みたいなもんだ。
ま、いろいろやりようはあるということです。


そもそも。
注文テーブルと注文明細のテーブル構造がある中で
注文テーブルに値段の合計が無いのがおかしかないかい?*1*2


ってなことがあるもの。
SQLは作り手によって千差万別の形を遂げる。
プログラムもそーだしな。
ゆえに記述の統一や、最適解の有効活用を行うためには
「できるやつがやる」のが一番いい。
10人いたら10人にSQL文を考えさせる必要などないのだ。


っという観点から物申すとDB専任者はいた方がいい。
10人規模じゃムダとかいう意見があったように思ったけれど、
10人もいたら入れとけと思うおいらがいてます。


UI側とPL/SQLならソースも違えば環境も違う。
ってことはまったく別の人がそれぞれ開発〜テストが行えるということ。
これはこれでアリな選択肢です。
適材適所は大事。

*1:少なくともそれが解決されれば複雑なSQLがひとつ消える。

*2:集計なんざUpdate文一つでできるからあらかじめやっとけや!と思う今日この頃。

まとめ

技術者レベルがみんな低かったらそもそもストアドなんざつかえないわけで。
Javaのソースも統制とれるはずもないわけで。
それでもなんか作ろうと努力するなら(1)-1になるでしょう。
テーブルやViewも数を増やすことに頑ななる抵抗を覚える人がいるならその手も使えなかったりするでしょう。
この手の開発の方針は「重たいことはみんなPL/SQLJavaは単一テーブルの検索とプロシジャーコールだけ」
ってのがいろいろ都合がよかったりします。
それゆえの(2)-2ですが、政治的判断とかミスリードによってよく潰されたりします。
開発の苦労は開発始まる時に自ら作っているのです。くわばらくわばら。
やっぱり
シンプルな構成でシンプルなコード作るのが一番ですよ。