3層型フレームワーク | HATのブログ

HATのブログ

IT関係のニュースを中心に記事を掲載します。日経コンピュータで重要だと感じた記事とコメントを2010年9月1日号から書いています。
このブログは個人的なものです。ここで述べていることは私の個人的な意見に基づくものであり、私の雇用者には一切の関係はありません。

RDBを使うに当たって、可変長型(VARCHARやNUMBERなど)を使用禁止にしているプロジェクトがあるそうです。CHAR型とDATE型だけで全項目を定義するのです。シビアなRDBの開発現場の実態はこんな事になっているのでしょうか。ビックリです。

1.「Join禁止」と「固定長DB」

(1)賛成派
新しく参加したプロジェクトの開発ルールが「Join禁止」「固定長DB」になっていた。猛反対したが最後には納得したというブログ がありました。固定長DBというのは、可変長型(VARCHARやNUMBERなど)を使用禁止にするという事です。レコードをUPDATEした時に項目長が延びて1レコードが複数のブロックに分割される事(行移行)を避ける目的です。

条件は相当厳しそうですが、見たことがないほどのレベルではありません。
>100万人の契約ユーザが使い、
>1テーブルに1億レコード以上のデータを貯め、
>24時間止めることが許されず、
>要求から応答までのターンアラウンドタイムが1秒以内

コンシューマ向けのシステムなら、個人ID別にデータが発生することが多いので、1億レコードを複数テーブルにわけられないのかなという疑問はあります。

(2)中間派
それに対して、Oracleの中家さんは、特殊ノウハウだからお勧めしないとブログ で書かれました。とは言え完全否定ではありません。
<こういったトリッキーな設計に必要なのは、それによるリスクを、避ける努力はしつつも最終的には受け入れるという覚悟>が必要

(3)反対派
この関係で生島 勘富(いくしま さだよし)さんという大阪のSEさんが書かれたブログ を知りました。なんだか熱くて大変面白い(笑)
<巨大システムは「固定長カラムがいい」「JOINは使わない方がいい」という技術的な間違いを認めるわけにはいかない

2.アンチパターン

この生島さんのブログエントリには、アンチパターンが羅列されています。

・配列禁止
・エクセル方眼紙
・ウォーターフォール
・JOIN禁止
・固定長カラム
・集計関数禁止
・サブクエリ禁止

これらは
<技術的には全部、目を覆いたくなるほどおかしい。>
<技術的におかしいと思わないモノがある人は、文化として受け入れて思考停止になっている。危険な兆候です。>
と一刀両断です。なんだかすがすがしいです。

この方は「SQLのプロ」として起業されているようですので、私とはジャンルが違うのですが仰ってる事は納得出来ます。

このアンチパターンで、「配列禁止」、「固定長カラム」には遭遇したことがありません。「エクセル方眼紙」と「集計関数禁止」は嫌ですが、そう開発標準が定められているのなら唯々諾々と従います(そういうプロジェクトは多いです)。

ウォーターフォール、JOIN禁止、サブクエリ禁止は私がプロジェクトを任された時にやる事が多いです。ここにはありませんが、UNION禁止、動的SQL禁止というのもやります。

3.複雑なSQL禁止の理由

私の言う禁止は厳しいものでなく、それが最善なら使います。適当なんですね。技術者じゃないと叱られると思います。これらを使う時には「一声かけて私に必要性を認めさせてね」というゆるいルールです。いわゆる「バカ基準」でルールを作っているわけです。

私が主にやっている基幹システムでは、大量データもめったに扱いませんし、レスポンス要求もそれほどシビアではありません。そういう時には見通しが良く間違いにくいという事を重視します。SQLで処理していると1項目NULLが入っているだけで結果を誤る事があります。これはテストでみつけにくいです。

サブクエリでSQL1文になったとしても、RDBMSは内部テーブルをこねくり回してマッチングしますから単純にプログラムで検索しても処理速度は変わりませんプログラムならindexの存在を意識して書けますからそちらの方が速くなる事も多いです。(もちろんSQLのプロならSQLもindexを意識されるでしょうが)

SLAがシビアなシステムだと事前に全てを見通す事は困難になります。かといって試行錯誤する時間もありませんから何かにすがる事は精神衛生上正しい事なのでしょう。そういう視点では「固定長DB」を完全否定する事にはためらいがあります。

4.いろいろな解決案

ある超大手企業では「SQLがわからないSEはいらない」と断言されていました。またそこでは、外部制約などもすべて実装されます。「どんなバカなプログラマが混じっているかわからないからDBの整合性をくずされないための自衛策」だそうです。

生島さんは、SQL処理を全てストアドプロシジャーで行い、UI設計/実装とDB設計/実装を完全に疎結合にする事を提案し実践されています。しかも「ユーザインターフェースを確定した後で、テーブル設計を行う」という順序です。といっても良く読めばわかりますがUI→DBという順序というよりは、UIで発生する試行錯誤(スパイラル?アジャイル?)にDB側が巻き込まれないようにUIが確定してから微調整を行うという程度の意味です。

実は私が大好きで会社員時代良く使っていたフレームワークも考え方は同じでした。SQLクラスは設計者(上級SE)だけが作り、業務画面のプログラマーは基本的にSQLを触らないという作りになっています。DOAで設計する時には、そのテーブルがどう読まれるかも考えながら最適な設計にします。つまりどういうSQLが必要なのかは設計時点でおおよそわかっているのです。

5.フレームワーク

そのフレームワークは、新日本ニーズさんの.NETデータベースライブラリー と、ザ・ヘッドさんのHeadPro
 です。

HeadPro(旧称JDIフレームワーク)を例に説明します。これは3層構造のjavaフレームワークです。

HATのブログ-JDIフレームJワーク

この図のインターフェースという所が大変重要です。これはPC側とサーバ側とをやりとりするためのパラメータですが、重要な設計要素です。例えばマスタ一覧の画面表示の場合、PC側で10行までしか表示できないなら次のようになります。

上りMSG:プログラムID、KEY
下りMSG:データ1、データ2・・・データ10、nextKEY

PC側で次画面ボタンを押されると、下りMSGに入ってきたnextKEYを上りMSGのKEYにセットして送信します。PCとサーバがこのインターフェースだけで疎結合されていますから、PC側/サーバ側が独立してテスト可能です。テキストエディタでメッセージを作るだけですし、フレームワーク自体にその機能が入っています。

基本はステートレス(サーバ側プログラムはPC側の過去の動きを知らないで動く)ですが、必要に応じてステートフルにも出来ます。サーバ側のスレッド多重度は起動時に指定出来ます。空いているスレッドがない時には即時に「込み合ってますのでしばらく経って送信して下さい」とPCの画面に返します。再度送信ボタンを押すだけで処理が継続出来ます。ステートレスですから、サーバを再起動したとしてもPC側の再入力は不要です。

SQLクラスも基本的なCRUDは自動生成ですし、SQL自体のテストコーディングも自動生成されます。基本的なSQL以外は業務画面単位にSQLクラスを作ります。原則的に他のプログラムと共用しません。

一般的な2層型のアーキテクチャだと、UIからSQLをそのままDBサーバに発行します。DBサーバ負荷、ネットワーク負荷が大きくなり中規模以上のシステムは厳しいです。生島さんのストアドプロシジャー方式は、2層型アーキテクチャに見えますが、実際にはこのJDIフレームワークと同じ発想です。

技術がわかってる方はO/RマッパーだとかSOAだとかに騙されず、同じような事を考えるんだなと感じました。ただ、全ビジネスロジックをストアドで実装する事が保守性という意味から良いのかが疑問でした。もしUI側にビジネスロジックやビジネスルールが残るならUIとDBとの分界点が曖昧になると思います。

以上