スケーラビリティをあげるために、処理は極力DBサーバで行うべき
予定を変更して。
わたしの主張は単純ですが、結局、普通と真逆のことになります。一般に信じられていることとまったく逆のことを主張することは大変なことですね。
わたしはブレてないのに、はぐらかすとか……。瑣末な部分にツッコミを入れるのが、はぐらかすことだと思います。「全部、否定する」って、これは現場でもよく言われるのですけれど(苦笑)、反対のことを主張しているのですから、最終的に否定にまわるのは仕方ないでしょう。否定しないことが議論ではないはずで、それを言ったら、地球は平らで太陽が回っていることに……。
私は議論がしたいので、炎上上等です。
一般的な考え方の反対のことを言ってますから、ドンドン否定してください。
基本的な主張はこんな感じ。
- 「上流を担当するならSQLができるようになるべき」
(これは当たり前すぎて反発は少ない) - 「テーブル設計を実装の後にすべき」
- 「スケーラビリティをあげるために、処理は極力DBサーバで行うべき」
少し前に、議論になったのは、テーブル設計を後回しにするために、ロジックをストアドプロシージャで書きましょう、というわたしの主張に対して、「ストアドプロシージャにするとスケーラビリティが落ちる」という反論がありました。前に記事を書きましたが、それでも納得いただけないようですので、もう一度、APサーバで処理する場合と、DBサーバで処理する場合のそれぞれの処理量を考えてみましょう。
■ 条件について
極端ですがJoinまでAPサーバで行っている場合と、DBサーバで処理した場合を検証しましょう。
テーブルは
受注トラン
受注NO(主キー)
得意先ID
受注日(インデックスあり)
・・・
得意先マスタ
得意先ID(主キー)
得意先名
住所
・・・・
処理内容は、1カ月の得意先毎の受注回数の一覧を出力する。
■ APサーバで処理する場合
・APサーバ
SELECT 得意先ID
FROM 受注トラン
WHERE 受注日 BETWEEN (1カ月分)
-- ORDER BY 得意先ID 普通はすると思うけど……。
のSQL文をDBサーバに送信する。
・DBサーバ
SQL文を受け取る。
SQL文のキャッシュを確認する。
キャッシュにあれば再利用し、なければ解析しアクセスパスを決める。
受注トランからインデックスを利用して抽出を行う。
結果セットを返す。
・APサーバ
取得した得意先IDをソートする
結果セットをループしながらカウントアップ
得意先IDがブレイクしたときにSELECT 得意先名
FROM 得意先マスタ
WHERE 得意先ID = 結果セット.得意先IDのSQL文をDBサーバに送信する。
・DBサーバ(得意先の数だけ実行)
SQL文を受け取る。
SQL文のキャッシュを確認する。
キャッシュにあれば再利用し、なければ解析しアクセスパスを決める。
得意先マスタからインデックスを利用して抽出を行う。
結果セットを返す。--増えてますけど、ここを赤くするかは微妙です。
・APサーバ
結果を出力する
■ DBサーバで処理する場合
・APサーバ
SELECT j.得意先ID, t.得意先名, COUNT(*) AS 受注回数
FROM 受注トラン j
INNER JOIN 得意先マスタ t
ON j.得意先ID = t.得意先ID
WHERE 受注日 BETWEEN (1カ月分)
GROUP BY j.得意先ID, t.得意先名
ORDER BY j.得意先ID
のSQL文をDBサーバに送信する。
・DBサーバ
SQL文を受け取る。
SQL文のキャッシュを確認する。
キャッシュにあれば再利用し、なければ解析しアクセスパスを決める。
受注トランからインデックスを利用して抽出を行う。
得意先マスタからインデックスを利用して抽出を行う。
メモリー上で得意先IDをソートする
結果セット用の変数(配列)に展開しながらカウントアップ
結果セットを返す。
・APサーバ
結果を出力する
■ APサーバで処理したらDBサーバの処理が減る?
APサーバはどんなに処理が増えても簡単に増設できるので無視してOKです。DBサーバ側の処理のみに注目してください。
DBサーバの処理が、青い部分はどちらで処理しても同等の部分、赤の部分が、APサーバで処理したら増える部分、緑の部分が減る部分です。
APサーバで処理してスケーラビリティが上がるとしたら、
緑の部分 > 赤の部分
が成り立つ必要があります。
さらに、APサーバが無駄な処理をすることによって、APサーバの台数が増えても(設備費)、その運用コストの増加を考えても、APサーバで処理する方がよい、とお考えの技術者が大変多いわけです。
つまり、
緑の部分 > 赤の部分 + 設備費 + 運用コスト
が成り立つと、多くの技術者は考えているということになります。
TCP/IPのようなCPUを大量消費するオーバーヘッドの大きなプロトコルでは通信していないのかもしれませんし、CPUの処理を肩代わりしてくれるNICも出てきていますけれど、当たり前ですが通信のコストはゼロではないです。ミドルウェアとのやり取りは、DBエンジン内部の処理に比べてオーバヘッドが大きいものになりますし、SQLの実行もオーバーヘッドが非常に大きいです。
つまり、SQLの実行回数が増えるとDBサーバの処理は増えます。
増える処理と減る処理が違う内容になって、実際には、データの重複の具合などの条件が個々に異なる。比較対象がそれぞれ違うので個別に考えないといけないでしょう。
しかし、わたしはほぼすべてのシステムで不等号は反対になると考えますので、式を成り立たせるために左辺に何かを乗せないといけない。わたしには何が乗っているかは憶測するしかないですが、
緑の部分 + SQLの教育コスト + 下手糞がいる + SQLはイヤだ!
> 赤の部分 + 設備費 + 運用コスト
となっているように思うのです。
経営者としては、教育コストにフォーカスしてしまうのは否定しませんけどね。これらは技術者が言うべきことではないでしょう。
わたしはそう思っていますけれど、もし、
緑の部分 < 赤の部分
が成り立つとしたら、かなり多くのシステムで「SQLの教育コスト + 下手糞がいる + SQLはイヤだ!」などという本当の理由? を隠して、「スケーラビリティのために」という、単純かつ、とんでもない間違いでボッタクってることになりはしませんか?(わざとやってたら耐震偽装を超える詐欺です)
少なくともわたしは不等号が反対だと思っていますから、一度でも「スケーラビリティのために」と顧客に説明したことがあるなら、プロとしてのプライドを持って否定してください。
炎上上等です。
■ 簡単な例だから?
簡単な例でひっくり返らないなら、複雑な例でも同じです。
しかし、複雑になれば違うことも確かに起こります。
前に、Martin Fowler氏のブログについて書きましたが、例えば、Martin Fowler氏が例として書いたSQL
SELECT o.orderID, o.date
, sum(li.cost) as totalCost,
CASE WHEN
(SELECT SUM(li.cost)
FROM lineitems li
WHERE li.product = ’Talisker’
AND o.orderID = li.orderID) > 5000
THEN ’Y’
ELSE ’N’
END AS isCuillen
FROM dbo.CUSTOMERS c
INNER JOIN dbo.orders o ON c.customerID = o.customerID
INNER JOIN lineItems li ON o.orderID = li.orderID
WHERE (c.name = ?)
AND (MONTH(o.date) = ?)
GROUP by o.orderID, o.date
ORDER BY totalCost desc
は、lineitemsテーブルの同じデータに2回アクセスしてしまいます。
わたしが考えたSQLでは
SELECT o.orderID, o.date, sum(li.cost) as totalCost,
CASE WHEN
SUM(CASE WHEN li.product = 'Talisker'
THEN li.cost
ELSE 0 END) > 5000
THEN ’Y’
ELSE ’N’
END AS isCuillen
FROM dbo.CUSTOMERS c
INNER JOIN dbo.orders o ON c.customerID = o.customerID
INNER JOIN lineItems li ON o.orderID = li.orderID
WHERE (c.name = ?)
AND (MONTH(o.date) = ?)
GROUP by o.orderID, o.date
ORDER BY totalCost desc
lineitemsテーブルに対して1回のアクセス中に集計処理が入っています。実行計画を取れば分かりますが、Rubyで処理するのとほぼ同じアルゴリズムで処理されます。
ところが、Martin Fowler氏のSQL文をDBサーバで行ったときの内部処理は、ブログのRubyで処理しているアルゴリズムより効率が悪いものになっています。
つまり、SQLで書くことによって、他の言語を使っていたら起こり得ないミスをする人がいるということです。
Martin Fowler氏のSQLは効率が悪いと言っても誤差の範囲(限られた範囲で二重にアクセスしているだけ)ですけれど、同じような間違いを繰り返すとDBサーバの負荷は高くなります。
超高負荷になるシステムで繰り返し実行される処理なら、読みやすさ技術者のスキルと、トレードオフしてよいか考慮が必要になります。
もちろん、電話帳を使うのに、電話帳を1ページ目から順にめくっていくようなSQLを書く人が居たら(珍しくない)、DBサーバは簡単にパンクすることになるでしょう。
■ まとめ
ちゃんと作ればDBサーバで処理した方がスケーラビリティは上がります。
しかし、現実的には、下手糞がいる(多い)ことを認める必要があるかもしれません。
それを変えるのに必要なことは、教育コストと技術者の心がけだけです。特に、既得権を持っている上流技術者の意識を何とかしなければなりません。
いろんな会社の新人教育を見ましたが、Java、C#、VB.NETなどはやっても、SQLはカリキュラムにすら入ってないことも多い。
せめてJavaと同じぐらいの教育コストをかけてから、SQLでロジックを書こうというプロジェクトに出せば、若くてやわらかい頭なんだから、わたしぐらいはすぐに追い抜くはずです。
SQLが高いレベルでできる技術者をそろえたら、工数が減って、パフォーマンスが上がって、運用コストまで落ちます。つまり、SQLを高いレベルで理解している技術者が増えれば、解決することは非常に多いのです(もちろん、十分条件ではなく必要条件です)。
ここ(@IT)を見ている人、さらにコメントをくれる人などは、普通より確実にできる人でしょう。わたしのようなオヤジではなく、あなた方が業界を引っ張らないと行けないのですから、どうか自分の頭でよく考えてくださいね。
神でもないわたしの言うことが全部正しいなんてありえませんから、是非是非、反論をください。いくらでも受けますよ。
できればズバっと
緑の部分 > 赤の部分
について反論して欲しいけれど、枝葉末節の部分でもがんばって受けます。
炎上上等!(笑)
■ 追加です
追加ですが、表示時のソートはAPサーバに任せることも多いです。その方が効率的なこともありますし、UIの要件と言えますから。集計時に内部的に発生するソートは任せようがないので、DBサーバの処理になります。
しかし、本文の例なら、おそらくソートはDBサーバでソートすると思います。その理由はSQLの中でOreder Byの構文が単純だからです(決め付けはよくないけれどわたしが見た範囲ではそうでした)。もし、本文の例でDBサーバでソートまですると、四則演算しかDBサーバの処理を肩代わりしていない。
パフォーマンスが落ちても、工数がかかっても、APサーバのコスト(設備・ランニング)が増えても、確保したいスケーラビリティのはずなんですから、スケーラビリティだけは、際限なく上がるぐらいでないと意味がないのですが、わたしの考え方が正しければ、ソートまでDBサーバでやったら、確実にスケーラビリティは落ちます。
APサーバで処理しているのだから、DBサーバの負荷はなんとなく落ちそうな気になるでしょうが、プロがやる仕事なんですから、なんとなくではなくもっと論理的に考えて欲しいものだと思うのです。
2009年2月12日 (木) 21:12
see http://el.jibun.atmarkit.co.jp/horisusumu/2009/02/post-3689.html
生島勘富 2009年2月12日 (木) 22:26
誰かは知りませんが、コメントどうも。
つまり、パフォーマンスが落ちようと、工数が掛かろうと、運用コストが増えようと、「スケーラビリティが上がる」という顧客には分かりにくい理屈を言って自らのスキルの低さを補うのですね。
分かります。いっぱい居ますから。
技術者なら、理屈で勝負すべきですが、それが出来ない自称技術者もたくさん見てきました。
どうぞ、カスは、カスの技術者として生きてください。
私は微力ながら、あなたの様なカスを全力で駆逐しようとがんばります!!
エネルギーを頂いてありがとうございます。
技術は多数決じゃないですよ。
スキルがない技術者の割合を見て、教育コストを考えて、最終的に方針を決めるのは経営者のすることです。
一介の技術者は技術を追うべきです。
MR.CBR 2009年2月12日 (木) 22:41
> いろんな会社の新人教育を見ましたが、Java、C#、VB.NETなどはやっても、SQLはカリキュラムにすら入ってないことも多い。
→私は製造業で社内SEをやっていますが、私の会社(情報部門)での新人教育の
最初はSQL教育から始まります。(ビジネスマーナとかも当然行いますが)
現場に近い所にいると、圧倒的にSQLに触れる機会が多いのです。
現場の依頼や要望がそのままSQLになっている事も多々あります。
生島勘富 2009年2月12日 (木) 22:49
MR.CBR さん、ども。
IT業界の末席に名を連ねるものとして、本当に恥ずかしく辛い現実です。
IT業界では、とりあえずJavaを教えて現場に放り出すのが普通で、以前は、JOIN禁止とか、GROUP BY禁止とかありましたし、今でも普通にHAVING禁止はありますよ、いわゆるIT企業で。
つまり、顧客(ユーザ)の方が分かっていて、進んでいるということで、本当に、そういう話を聞くと悔しさで身悶えてしまいます。
それで、私は同業者に対して、「プロとしてのプライドはどこにあるのか!!」という思いで、口汚くなってしまいます。
プロ(技術者)ではなく、サラリーマンなら上に従うわけです。
これぐらい不況になっても、それなりに報酬を得れて、それだけがアイデンティティの自称技術者達は、結局、技術者ではなくサラリーマンですから、自分の頭で考えることはありません。
空気が大事ですしね。
それは生き方として、間違っているとはいいがたいけれど、今みたいに不況になったら本物以外は生き残れないと思います。
私としては、くだらないサラリーマンを淘汰するチャンスとして不況は歓迎なのですけれど、私自身が不況に耐えれなさそうで、痛し痒しです(笑)
MR.CBR 2009年2月12日 (木) 23:57
>IT業界では、とりあえずJavaを教えて現場に放り出すのが普通で、以前は、JOIN禁止とか、GROUP BY禁止とかありましたし、今でも普通にHAVING禁止はありますよ、いわゆるIT企業で。
→絶句…。
JOIN、GROUP BY、HAVINGが禁止という事は当然、副問い合わせも禁止
なんですよね…。SELECT文でデータ取ってきてプログラムでグルグル回す
しかないですね。つ、辛すぎます。
このルールだと、現場からの要望の大半であるSQLだけで済む事を
わざわざグルグルプログラムを組むしかないですね…。
弊社でそんなプログラム組んだら大目玉になります(笑)。
というか、プログラム中にループがあると、そのループは本当に
必要なのか?(SQL一発で出来ないのか?)というディスカッションに
発展します。弊社では卓越したSQLアーティスト(笑)はいないですが、
3人ぐらいで考えると、ループせずにSQL一発で出来るケースが多いです。
その甲斐あって各人のSQLのレベルは年々向上しているし、SQLを使うから
保守性が落ちるか?というと、プログラム中にループが沢山登場する
よりかよっぽど保守性が高くなります。(弊社の場合ですが)
ただ、悩みは弊社の場合、動的SQLが多く、各プログラム・テーブルの
CRUDが俯瞰できていないと言う点です。
業務変更により、テーブルに項目追加が発生した場合の影響分析を
現在はVBソース、PL/SQLソース、SQLスクリプトソースからGREP
かけて対象PGを洗い出しています。この辺をもっとスマートにする
事が課題です。何か良いアドバイスを頂ければ幸いです。
saki1208 2009年2月13日 (金) 00:17
いつも楽しく拝見させていただいています。
# 共感できるところが多いんですよね。
# この業界、なぜか苦労したがるひとが多い気がする。
私の周りにもたくさんのなんちゃってSE/PGが大量にいます。
二言めには、「だって、俺できないもん」ですから...
# やらなければいつまでたってもできないんですがね。
>IT業界では、とりあえずJavaを教えて現場に放り出すのが普通で、以前
>は、JOIN禁止とか、GROUP BY禁止とかありましたし、今でも普通にH
>AVING禁止はありますよ、いわゆるIT企業で。
うちでは一時期「UNION」禁止でした。
もちろん、副問い合わせもでしたが。
余計な話ですが、CNETの方はやめられたんですか?
saki1208 2009年2月13日 (金) 00:18
日本語が変でした。
×たくさんのなんちゃってSE/PGが大量にいます。
○たくさんのなんちゃってSE/PGがいます。
ビガー 2009年2月13日 (金) 02:17
ビガーです。
赤と緑の部分への突っ込みが欲しいようなので。
そもそもの話ですが、得意先マスタのようなマスタデータ(更新頻度や
運用要件に依る)は高速性が求められるシステムではAPサーバ内に
キャッシュします。(マスタメンテ時にリフレッシュさせたりする)
したがって、例がよろしくないと思うので受注と出荷などを例にするとよいかと。
その場合について意見しておくと、O/Rマッパの機能でもある程度イけますが、
クエリ言語の仕様にイライラすることが結構あるのでApplicationFramework
(例えばspringベースにしたもの)内でHibernateTemplateとJdbcTemplateを
それぞれ使用できるようにして永続化・簡易検索はHibernateTemplate、
重めの検索はJdbcTemplateを使用してエンティティにマッピングさせたりします。
JdbcTemplateを使用する前提としてSQLを熟知している必要がありますね。
MR.CBRさんの話ですが、失礼ですがこういうのをスパゲッティと一般にはいうのかと。。
解決策は以下のようなアプローチになりますかね。
1. 業務と対応するプログラムを表形式などで洗い出す
2. プログラムとテーブルの対応を表形式などで洗い出す。
3. CRUD表にまとめる。
1.と2.は非常に地道な作業です。たぶん業務中に工数を与えられてやるような
仕事ではないでしょうから、保守案件受注時などに並行して地道にやるしかないでしょうね。
その後のCRUD表メンテナンスが面倒と思いますが、地図が現実と剥離しては
意味が薄れると同様に組織的に重要なことであると認識する必要があります。
→これが一番大変なんですけどね。。
生島勘富 2009年2月13日 (金) 06:13
MR.CBR さん、ども。
御社のシステムを作れるITベンダーは少なくとも上場企業にはないですね。
冗談抜きで、ITベンダーなどが作り直したら100倍遅いものができてくると思います。
動的SQLを使っているとCRUD表は確かに難しいですね。
PL/SQLで静的なものにしておくと、ある程度はSI Object Browserなどで作ってくれますけれど。
あとは1度手作業でしっかりしたものを作って、変更の都度、修正するということになろうかと思います。
生島勘富 2009年2月13日 (金) 06:18
saki1208 さん、ども。
> 二言めには、「だって、俺できないもん」ですから...
これを言われた後、ループして作ってパフォーマンスが出ずに結局作り直しとかありますね。
最近は、ハードがよくなっているから、パフォーマンスの問題が出るときは本当にデータ量が多くなったときで、逆に深刻な問題になることが多いですね。
CNetはさっき少し書きましたけれど、使い勝手が悪くて、なんとなく書きたくないのです(笑)
資金繰り 2009年2月13日 (金) 06:23
APサーバとかDBサーバとかどうでもいい。
とにかくこのシステムを今すぐ動くようにしてくれ。
4月の本番稼動に間に合わないなら、損害賠償を請求する。
と言われ・・・
結局、一部の機能が正常に動かなくて、使い物にならず全てパーに
→ 損害賠償請求(XXX億)
→ 幹部社員が転職しだす
→ 社長が金策に走る
→ その筋の方が会社に怒鳴り込みに来る
→ 会社に泥棒が入る(社長の自作自演?)
→ 社長が行方不明に
→ 会社倒産
これ去年の出来事。
とにかくシステムが動けば神。
SQLだろうがRubyだろうが、動けば神。
APサーバだろうがDBサーバだろうが、動けば神。
生島勘富 2009年2月13日 (金) 07:04
ビガーさん、ども。
> そもそもの話ですが、得意先マスタのようなマスタデータ(更新頻度や
> 運用要件に依る)は高速性が求められるシステムではAPサーバ内に
> キャッシュします。(マスタメンテ時にリフレッシュさせたりする)
確かにキャッシュさせればDBサーバの処理は肩代わりできますね。
考えが固定されていました。
ありがとうございました。
> クエリ言語の仕様にイライラすることが結構あるのでApplicationFramework
> (例えばspringベースにしたもの)内でHibernateTemplateとJdbcTemplateを
> それぞれ使用できるようにして永続化・簡易検索はHibernateTemplate、
> 重めの検索はJdbcTemplateを使用してエンティティにマッピングさせたりします。
> JdbcTemplateを使用する前提としてSQLを熟知している必要がありますね。
重めの検索とか、難しい検索とか、基準を個人にゆだねると人によって変わる。
何をもって簡易検索というかということです。
できない人はいつまで経っても簡易でループに流れますから、UIとSQLを書く技術者を完全に分離した方がいい(もちろん、できる人は両方してもいいけれど)
そのためには、DBサーバで処理させる必要が出てきます。
できる人が作るならばスケーラビリティは関係ないのです。
生島勘富 2009年2月13日 (金) 07:08
資金繰り さん
おはようございます。
大変なことがあったのでしょうね。
何億というプロジェクトでは、個人の力ではどうしようもないでしょうから、早く忘れて技術を磨いてください。
とおりスカリー 2009年2月13日 (金) 09:36
私はPostgreSQLを主に使っていますが、ストアドにビジネスロジックを
作りこむには、ソースが長くなってくると言語仕様が少々貧弱で
いまひとつ踏み切れません。
全ての関数がグローバルだったり、グローバルな定数が無い等・・。
また、ロジックを100%ストアドに収めきれる訳でもなく、
ストアド/Java両方に注意を払いながらメンテしていくのも
ちょっと抵抗が。
ところで、HibernateのようなORマッパーって、「これでSQLが要らなくなる」という
誤解がくっついて広まってるのが不幸ですね。
生島勘富 2009年2月13日 (金) 10:05
とおりスカリーさん
おはようございます。
PostgreSQLのストアドですか、割りと使えますけれどね。
SQLにシンタックスエラーがあっても通ってしまう?つまり、全部、動的SQLとして認識しているとか、すべての関数がグローバルというのは、確かに嫌なところです。
ビジネスロジックのすべてはムリですが、内部、外部(UI)に分ければ、内部はすべてストアドプロシージャで処理できるはずです。
そこにデータがあるのですから。
インドリ 2009年2月13日 (金) 10:10
> ただ、悩みは弊社の場合、動的SQLが多く、各プログラム・テーブルの
CRUDが俯瞰できていないと言う点です
この件ですが、そのためにストアドプロシージャが存在します。
ストアドプロシージャを作って、トランザクションの正規化をしましょう。
正規化は何もテーブルだけではありません。
プログラムやトランザクションも正規化する必要があります。
インドリ 2009年2月13日 (金) 10:21
>ストアドにビジネスロジックを作りこむには
この件ですが、PostgreSQLはORDBMSなので、データ中心アプローチで考えてストアドプロシージャを作らなければなりません。
ですから、ストアドプロシージャにするのは、「データ要件」のあるものだけです。
データの整合性という点に注目すれば、自然と上手く作れると思います。
Javaと同じ感覚でストアドプロシージャを作っちゃ駄目ですよ。
生島勘富 2009年2月13日 (金) 10:52
インドリさん
>> ただ、悩みは弊社の場合、動的SQLが多く、各プログラム・テーブルの
>> CRUDが俯瞰できていないと言う点です
> この件ですが、そのためにストアドプロシージャが存在します。
> ストアドプロシージャを作って、トランザクションの正規化をしましょう。
依存関係までしかわからないから、CRUDにはならないですよね?
CRUDになるツールを作ろうかと何度も思ったのですけれど、すべてがストアドプロシージャになるプロジェクトって世の中にあまりないでしょうから、売れないしな~って、何度も諦めています。
ストアドプロシージャ(SQL)が難しいという前提があるから、最後の手段としてストアドプロシージャになるのでしょうけれど、実は簡単となれば、最初から全部ストアドプロシージャが正しい選択になるはず。
生島勘富 2009年2月13日 (金) 11:38
MR.CBR さんの会社のシステムはVBを使っているとのことですから、10年近い蓄積があるのでしょう。
ストアドプロシージャでやり直せたらよいけれど、そうそう予算も取れないでしょうし、情報システム部で業務が回っているなら十分じゃないでしょうか。
リプレースするときは、是非やらせて欲しいですけれど(笑)
10年前ならOracle8iとかで、8iの頃はEnterprise版でないとOLAP関数が使えなかったと記憶しているのですが、Oracle9i以上ならOLAP関数は結構使えるので、CASE式と組合せばSQLでかなりのことが出来ると思います。
MR.CBR 2009年2月13日 (金) 13:04
インドリさんはじめまして。
>この件ですが、そのためにストアドプロシージャが存在します。
>ストアドプロシージャを作って、トランザクションの正規化をしましょう。
→この件、凄く興味があります。問題解決の糸口をつかめれば嬉しい限りです。
トランザクションの正規化とは具体的にどのような作業になりますか?
弊社ではストアドプロシージャにて基本は静的SQLなのですが、
検索条件多く可変な場合や、どうしても性能を出さないといけない時など
ストアドプロシージャの中で動的SQLを組みます。
生島さんが言われる通り、弊社もObjectBrowserは無くてはならないツールで
利用していますが、相関図機能を使用して静的SQLの相関は判りますが、
CRUDのどれか?と動的SQL(当たり前ですが)は対象外なのです。
ビガーさんが言われる通り、1、2の作業をまめにやっていくしかないのでしょうね。
弊社のシステムはテーブルが446本、プログラム(VB、PL/SQL、SQLスクリプト、
Bat、VBスクリプトなど)が800本近くあり、CRUDマトリックスがExcel2003では
実現できません(笑)。※列最大が256列な為
ビガー 2009年2月13日 (金) 13:26
ビガーです。
MR.CBRさん
1枚のシートでは管理できないでしょうから以下のような観点で
シート分けするなどは必要でしょう。
1. 業務とプログラムの粒度を合わせる。
2. 1.レベルのメインプログラムとサブプログラムの対応をとる。
3. プログラム区分(実装言語やSQLの質(動的/静的)で分割する。
4. テーブル区分(マスタ/トラン/システムなど)で分割する。
これらを実施すると本当に必要な機能やデータがわかり、最も効率良い
機能拡張ができるようになります、私の場合は。
どこまで本気かが重要ですね。
インドリ 2009年2月13日 (金) 14:35
挨拶が遅れました。MR.CBRさんはじめまして。
DBMSを使用したプロジェクトのよくある間違いが「業務イベント」用いる事です。
例えば、商品を発送した、死に筋商品を廃棄した・・・とかの業務処理がこれにあたります。
これが何故間違いなのかと申しますと、こうした視点で作られたプログラムは、ロジックが分散するからです。
そうなってしまっては、何のためにDBMSを使っているのか分からなくなります。
そこで、企業単位で業務手順や用語の統一化を図り、業務処理=トランザクションを細分化し、これを正規化することによりプログラムの重複がなくせます。
コツは安定したデータに着目する事です。
業務手順は時間と共に変りますが、業務に根ざしたデータそのものは企業活動が変らない限り(業種変えなどしないかぎり)変りません。
そのデータを判別し、そのデータの操作をストアドプロシージャ化し、業務手順は別に定義する事により変化に強いシステムが出来上がります。
インドリ 2009年2月13日 (金) 14:38
念のために付け加えます。データの操作というのは、データライフサイクルの事です。
CRUDが把握できない時はトランザクションが正規化されていない可能性大です。
生島勘富 2009年2月13日 (金) 15:18
おそらくですけど、MR.CBRさん自身はCRUDは把握できていると思います。
できてない人は、SQLでやった方が保守性が上がるとは言わないから。
ただ、他の誰かに説明するのにCRUDが必要で、それの保守に困ってらっしゃるのでしょう。
これを解決するには動的SQLが減らないと、ツールではどうしようもないですね。
446テーブルというにワークが含まれているとしたら、それをまずはじくことでしょうね。
私はワークテーブルは、スキーマを変えたり……。
ウソ、基本ワークテーブルは使わない。
ただ、横着者なので
Create Table xxxxx AS
SELECT * FROM YYYYY
とバックアップしたヤツがたくさん残っていることがある。
本番前には消しますが。
インドリ 2009年2月13日 (金) 17:08
おっと失礼。重要な事書き忘れていましたが、トランザクション正規化した後は、絶対にCRUD表は必要ですよ。
此れ書いておかないとデータベース設計としてはミスです。