制約っていらなくね?
あ、煽ってる訳じゃないです。
制約に対する偏見なのかなあって
ちょっと思ってきては居るんで
背中押してもらいたいというのが本音。
>61の連鎖削除・更新も
業務要件だからアプリで実装したいんですよねぇ。
トリガーもそうなんですが。
ださいのかなー。
あっ、でもレスポンス向上の一手に使えるってのは
いいっすね!そういうかわいい悪どさは好きです。 >>63-64
直接引用じゃなく、要点絞って記述するね。
>アプリで実装するほうが判りやすくて楽
1つのテーブルに対する処理が10個も20個もあるアプリで、
全ての処理が正しく動作することを補償するのは楽でしょうか?
NOT NULLの制約もないDBとか最悪ですよ。
>制約をつけると再実装
逆です、制約がまず実装でアプリ側が再実装。
アプリ作るのに、DB設計もせずに始めるのでしょうか?
で、トリガーと制約は別問題。
論理的制約をトリガーで実装するってのはあるけど。
主キーもない、NULL制約もないDBなんて、DB使わないでファイルに書けばいいじゃん。w
>>65
まず具体的にNOT NULL制約に話なんですが、
業務要件としてNOT NULLなものって
アプリ側で入力チェックしますよね。
アプリ側の実装はどうしても必要になっちゃう。
で、そういうチェックはユーティリティクラスとかヴァリデーターとか
そんな風に共通化する訳です。
1つのテーブルに対して10個も20個も処理があったとして
アプリ側の設計で実装は1つにまとめられると思います。
で、ままあるんですが、当初NOT NULLだと思ってたのが
実はNULLもあるんだよーなんて突然お客様に言われた時に
アプリ側で仕様が把握し切れればいいんじゃないかなと思っちゃう。
>アプリ作るのに、DB設計もせずに始めるのでしょうか?
DB設計は事前にしますよ。ER図も書きます。
でもそれは論理設計と言うか概念設計です。
実際にDBを構える時はまた考え直します。
概念設計において業務要件を反映した制約を
そのまま実装としてDBに入れるか、
アプリでやるかって所だと。
ちょっと話はずれますが、
概念設計と実装で構成が違うのは当たり前にやってます。
特に識別子の考え方。概念では識別子は業務に沿って考えます。
だから「注文番号 + 行番」なんて複合キーもガンガン使います。
でも実装では、「注文明細ID」をキーにします。
勿論、一意制約とインデックスは「注文番号 + 行番」につけますけど。
だから、参照整合やNOT NULLに関しても
実装ではぶいてアプリで実装ってのにあまり抵抗がないのかも
知れません。
うーん、書いてて自分の強い優位性が見出せぬ。
過去の振り返りにしかなってない・・・わはは。
レス有難う御座います。長文失敬でした。 >>67
> 業務要件としてNOT NULLなものって
> アプリ側で入力チェックしますよね。
> アプリ側の実装はどうしても必要になっちゃう。
> で、そういうチェックはユーティリティクラスとかヴァリデーターとか
> そんな風に共通化する訳です。
アプリでの入力チェックとNotNull制約では、後者のほうが広い意味です。
入力チェックしても防げないバグデータでも制約で防げます。
それに、アプリを通さないDBテーブル同士でのデータ登録とか更新もありますし。
> 1つのテーブルに対して10個も20個も処理があったとして
> アプリ側の設計で実装は1つにまとめられると思います。
クラスなど実装が1つにまとめられることと、SQLの種類が複数になることは別問題ですよ。
その各パターン毎の更新などに対して、不慮の事故などをどのようの防ぐのですか?
全てのパターンを1つの汎用SQLで行った場合にしても、それらのパターン毎の試験は必要です。
> 概念設計において業務要件を反映した制約を
> そのまま実装としてDBに入れるか、
> アプリでやるかって所だと。
DBの責務としての制約はDBでやるべきだし、アプリの制約はアプリでやるべき。
それに、DBが常にアプリを通して更新されるとは限らないし。
メンテとか、後の修正や他システムとの連携などで、そのアプリに対する制約を相手に望めますか?
> うーん、書いてて自分の強い優位性が見出せぬ。
> 過去の振り返りにしかなってない・・・わはは。
だって、便利な機能を否定して茨の道を歩んでるから。
両方制約すればいいんですよ、DBとアプリの独立性を高めて考えて、それぞれの責務を課す。
DBは自分の入れられたくないデータを制約し、アプリは他に出せないデータは出さない。 >>68
うーむ、茨の道、耳が痛いです。
やっぱりやった事ないから恐いってだけなんでしょうかね。
有難う御座います。
確かに、アプリを経由しないデータ連携などではお手上げですね。
最初からそんな要件なければいいですが
案件ごとに制約の実装方法がDB or アプリで
バラバラになっちゃうのも気持ち悪いですし
ポリシーとして最初から統一しちゃう方が、確かに安心。
あと、DBからの制約のエラーと
アプリでのエラーメッセージのマッピングで
困った事とかないですか?
DBからのエラーコードじゃ判りきらんよ、とか。
それも気になる所なのです。
柔軟にメッセージを対応させたきゃそれこそアプリの責務で、
アプリ側でチェックすれって所でしょうか。 DBから見たら制約を課すことまでが責務であって、その結果を返すだけだよ。
そのエラーをアプリがどう料理するかはアプリの実装の問題。
特定のエラーコードに意味を求める(キー重複など)場合はそのコードで分岐して処理すればいいし。
NULL制約違反ってのはあまり出したくはないよね。
やっぱ、アプリで事前チェックして、そもそもINSERTなどを投げないようにしたい。
Oracleとかだと、どのカラムで何のエラーってメッセージはもらえるけど、あくまで文字列情報だし、
貴方が悩むところはなんとなくは判ります。
そもそもとして、DBに制約をつけるのってそんなに大変か?w
Check制約にしても、そんなに手間じゃないでしょ。 おっしゃる通り、別に大変でもないですよね。わはは。
飛ぶのが恐いわけじゃない、落ちていくのが恐いんだ
by 寺山修司
って心境です。
派手にバグを出してデータパッチわんさか当てなきゃーとか
なった時に、参照整合とかで苦労しないかなーとか
勝手に妄想してるのです。
次は飛んでみるかな。 >>71
想定してる場面が発生する原因は・・・。
1)システム分析が甘く、DB設計が間違っている為、実情に合わない制約をDBに課した
2)そもそもの業務がフレキシブル(w、なので、その時点での制約が邪魔になる。
のどちらかだと思うが。
前者であれば技量を磨くしかないし、後者はそもそも制約を付与する設計がやっぱり間違っているともいえる。
制約って基本的にはきつく課しておいて、緩めるときに本当に緩める理由があるか考えるほうが安全だよ。 >>64
連鎖削除・更新は、注文-注文明細とかで考えると、
業務要件では無くRDB側の物理実装時の都合だと思う。
と、言いつつも管理が面倒なので、アプリ側に実装させて
自分がDBを直接弄る場合にのみ、一時的に有効にするのが
オレサマのやり方だな。 NOT NULLの制約については、文字型について
Oracleと、SQLServerで扱いが微妙に違うのがイタイな。
Oracleは、NullとEmptyの違いが無いのに対して
SQLServerは、NullとEmptyを明確に区別する。
そのため、ほとんどのフィールドは、Nullを許可しているな。
考え方は、SQLServerの方が好きだな。
他の、DBってどうなのだろう。。? さんざん書かれているけど、基本的な考えとしてアプリケーションありきの
モデリングを行うのは、後々の拡張性とか考えると嫌だな。
↓ちょうど良い記事を見つけた。
データは安定している 〜POAからDOAへ
ttp://pcweb.mycom.co.jp/series/stratesys/010/
所で、
制約の管理とか、モデリングツールにより
かなり効率が違ってくると思うのですが、
何かつかってます?
漏れの場合は、Erwin3.5使ってて
最近は値段の関係から、ER/Studioに移行させられそう。。。
うちはOBERです。
そーんなに使い勝手いいとは思えないかな・・・。 >>74
DB2もPostgreも区別するよ。
つーかOracleが特殊なだけな気がする。 >>78
日記の裏でなくて
モデリングツールなぞ
チラシの裏で十分です
って話でそ。 >>80
そういう意味か。。
制約の保守が〜、といった話が出ていたので、
その流れのつもりだったんだけどな。
漏れは、Erwin様にDDLだとか、管理してもらっているので、
モデリングツール無くなると、作業効率がた落ちなんだな。
DB自体と物理モデルの完全比較とか、使いこなすまでが
大変だけ使いこなすとスコブル便利だよ。
もう、手動で管理する自信ありませんぜ。 >>81
モデリングツールは設計ツールじゃなくて保守ツールと考えると納得いく。
設計は紙と鉛筆が基本だけど、後のことを考えてあえて手間ひまかけてツールを使う。
だから保守をやらない開発メンバーには評判が悪かったりする。 そうなのか、評判悪いのか。。
漏れは中小規模な案件が多いせいか、
引き継ぎと言う事例が少ないだけで(~-~;
しょうがなしに保守や改善対応している
開発よりのタイプなんだけどな。
そういえば、UMLっぽい物をVisioで
書こうとした時はメンドクセと思った。
あんな感じなのかな。 「保守を行わない開発メンバー」という
箇所を見落としてた。
とはいえ、統一したフォーマットの
DDL書いてくれるだけでも便利だと
思うのだけどな。
そういった観点か既に保守する立場と(略 チラシの裏書いた本人だが、終盤はモデルツールでやりますよ。
ただ、概念から順次ツールに合わせて落としていくっていうのがどうも制限になって嫌で。
手法の1つとしてはツールの手順でもいいけど、設計ってそこまで理想的に出来ないこと多いし。
とりあえずの概念設計とかはチラシの裏というか裏紙が一番いい。
そのままの意味だったとは。。。
そいつぁ 盲点だたよ (^ ^ ; ここで書き込んでいる人たちはずいぶん専門的な話題が多いようですが、
具体的にいったいどんな規模のどんなシステムに関わってるんでしょうか??
ここでいう「中小」とはどれくらいのものを指すんだろう・・・。 中…1000万行程度、数十テーブル程度で同時接続ユーザ数100人程度
小…100万行程度、数テーブル以下で列数最大20-100列、同時接続ユーザ数数名程度 今やってるのは
100万行程度、数百テーブルで列数最大100列、同時接続ユーザ数数名程度
ですが・・・ >90
あまり細かい事を気にすると頭髪的にチャレンジされている方々の仲間入りしちゃうぞ。 プログラム側でわかりやすいエラーを出すのはもちろんだけど
制約があればプログラムがバグってても間違ったデータは入らないので
フェールセーフにはなるよね。プログラム側の制御はフールプルーフということで。
制約の付け方が間違ってたら設計者を死刑で。
制約は、Not Null、主キー、一意制約くらいいしか使わない
>>94
自分もそう思って、可能な限り設計通りに参照整合性制約とか実装してる。
最近はマシンの性能も追いついて来た感じがあるし、設計と実装の乖離が
なくなってイイ感じ。
>>74
確かに実装レベルでは、Oracleが特殊だが、SQL標準からすると、Oracleが正解。
でも、Oracle8とかOracle9のせいでOracle嫌いになってしまったけどね。
(バグが多いくせにパッチ当てるのも一苦労だし)
で、制約に関しては、参照整合性制約以外は、つけたほうがいいと思う。
参照整合性だけは微妙だと思うけどね。
でも、制約にすべてのエラーチェックを任せるのはいかがなものだと思うよ。
アプリ側でチェックして、最後の砦として、制約を使うのが正解だと思う。
昔みたアプリで、とりあえず、INSERTしてみて、エラーが出たら、制約違反です
とかの処理のがあったけど、言語道断だと思う。
後、デフォルト値(制約じゃないけど)も付けといてもいいと思う。
でも、デフォルト値に設定したいがために、INSERT文で指定しないってのは
言語道断だと思う。 保守ついでに。
ITアーキテクトの「やってはいけない」
[データベース設計編]参照整合性制約機能を多用してはいけない
http://itpro.nikkeibp.co.jp/article/COLUMN/20090512/329851/
はてブでは否定的なコメントが多いが、このスレの住人的にはどうなんだろ? データベースの目的によるんじゃないか
ただのストレージとしてなら、参照性合成制約なんか邪魔なだけ
モデルをあらわすものなら、制約付けとくほうがいいのかな >>102
「参照制約を多用してはいけない」とは思うけど、
それは主にレスポンスの問題だな
こいつの挙げてる理由はどうでもいい
・移行時に時間がかかる
→移行なんてそうそうやるもんじゃないし、別に時間かかってもいい
・マスタにないデータが登録できない
→それが正常だし、アプリで制約実装しても同じ問題が起こる 藤塚 勤也(ふじづか きんや)
NTTデータ 基盤システム事業本部 システム方式技術ビジネスユニット OSS技術統括 エグゼクティブITスペシャリスト(データベース)
日頃はオリジナルOSSを中心に,技術開発やそのビジネス化に従事。
特にシステムの中核であるRDBMSには常に着目し,ITスペシャリストとして後進の指導にも注力している。
「RDBMS解剖学」(翔泳社)を共著。
データの人間ってこんなレベルのやつらばかりなのか?
こんなレベルで後進の指導に注力されてもこまるんだがw > 通常業務処理の中でも問題になるケースがある。
> 例えば,1週間後に発売を予定している商品を先行して仮受注するような業務処理があった場合だ。
ふむふむ。
> まだ発売していないので商品テーブルにはその商品番号のレコードが存在しないとしよう。
ああそうですか。
>仮受注のデータも受注テーブルで管理しようとしても,商品テーブルにない商品番号のデータは追加できない。
まあそうですね。
>このような業務処理は実行できなくなってしまう。
えええ?
>仮受注のときのみ,一時的に参照整合性制約を解除するといった方法は良い設計とはいえない。
はぁぁぁ?
お前が設計してはいけない。 >>102
>データを移行する際、先に受注テーブルを移行させようとすると
>参照整合性違反となり、RDBMSはエラーを返す。
>必ず、商品テーブルのデータ移行後に、
>受注テーブルのデータ移行を行わなければならない。
参照元-参照先という関係は半順序だからDAG(非循環有向グラフ)で表現できる
このDAGをトポロジカルソートすれば、
参照整合性違反にならないテーブルの移行順序を機械的に導出できる
これはグラフ・アルゴリズムの初歩的な応用だ(makeコマンドを知っていれば合点がつくと思う)
>仮受注のデータも受注テーブルで管理しようとしても、
>商品テーブルにない商品番号のデータは追加できない。
>このような業務処理は実行できなくなってしまう。
これは業務分析なりDB設計のミス
もし業務ルールにおいて受注より(時系列上で)先行して受注が発生する可能性があるなら、
受注テーブルに商品番号カラムを設けてはならない
代わりに受注番号カラムと商品番号カラムを持つ受注.商品.対応テーブルを追加し、
両カラムのペアにはユニーク制約を、各カラムには参照整合性制約を設定する
この設計は、できれば業務分析時に判断してあらかじめDB設計に盛り込むのがベストであるし、
あるいは分析漏れがあったのならば(分析ミスを認めて)バグを作り込んだDBの再設計に立ち返るべき
こうした上流工程での間違いを正さずに下流工程のアプリ側で整合性検査処理を組ませるからバグが多発する
いいかえると、上流でのミスを下流の小手先で誤摩化そうとする傲慢さがプロジェクト炎上の原因になる
システム設計の基礎である初歩的なアルゴリズムの知識が無く、DB設計の基本や品質保証の定石も知らず、
これでもNTTデータ様のITスペシャリストを名乗れている(>>107)という現実に驚かされる
そして、これほど無能な自称スペシャリストに記事を書かせたITproの見識にも、疑いをいだかざるをえない >>112の「....」の部分を訂正
誤: もし業務ルールにおいて「受注」より(時系列上で)先行して受注が発生する可能性があるなら、
正: もし業務ルールにおいて「商品(の登録)」より(時系列上で)先行して受注が発生する可能性があるなら、 誰でも簡単にパソコン1台で稼げる方法など
参考までに、
⇒ 『宮本のゴウリエセレレ』 というブログで見ることができるらしいです。
グーグル検索⇒『宮本のゴウリエセレレ』
8IA9EN4TR2