• ベストアンサー

主キー以外の項目にNotNull制約をつける理由について

あるプロジェクトで OracleにアクセスするJavaのプログラムを書いています。 使用しているテーブル定義は、 主キーでも何でもない項目ほぼ全てにNotNull制約が付いています。 別にNotNull制約を除けば主キー以外の制約は何もありません。 これからつく予定もありません。 そこでふと、 各項目の入力値は全てプログラム側でチェックしていますので プライマリキーや共通のフッタ部分(登録日、登録ProgramIDなど)を除けば Not Null制約は全くいらないんじゃないかと思いました。 このような場合、NotNull制約は何の為についているんでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • entree
  • ベストアンサー率55% (405/735)
回答No.5

> もうちょっと正規化して、別テーブルにしてもらえませんか?とお願いもしましたが、 > もう決まっているから駄目と言われました。 > それで一体どうすればいいのかわからなくなって、 > 全項目NotNullを外せばいいんじゃないか?と思って質問してしまいました。 > > こういう場合、どういう対処が望ましいのでしょうか? 正規化できるのであれば正規化するに越したことはないですが、できないのであれば仕方がないでしょう。 NOT NULL 制約の有無はソート列として指定された列以外ではあまり影響を与えることはありません。ましてや、WHERE 句の条件にもならないような列ではなおさらのことです。 ただ、NOT NULL 制約を好き勝手に外す権利があるのであれば、好き勝手に正規化する権利が jack_s さんにあるような気がしなくもないですが・・・。

noname#53515
質問者

お礼

DB管理者にDB変更依頼を提出し、 無事NotNull制約を外す事ができました。 正規化してくれないのは 汎用機出身の方だからでしょうか? でも無事解決できてなによりです。 みなさまのアドバイスのおかげで助かりました。 ありがとうございました。

その他の回答 (4)

  • dee_honda
  • ベストアンサー率53% (26/49)
回答No.4

たとえばVB6.0やAccessのVBAのように、 NULLがあるといちいちIsNull関数を使用して処理分岐を行う必要がある プログラミング言語を使用する可能性があれば、そういう設計にする のもアリだと思います。 今はもう少数派かもしれませんが、 NULLという概念が薄かった汎用機のネットワーク型DBの名残で、 そういう設計をされる方も以前は多かったか。 #要するに設計がRDBでないという:-)

回答No.3

自分側で初期値も入れられない、さらに正規化も不可ということでしたら、 選択としては、 ・NOT NULL制約をはずす ・自分の処理の部分を行わせる前に、サブシステム側でレコードが初期化されていることを保証してもらう このくらいじゃないでしょうか。 ダメというなら解決策を説得するしかないでしょうね。

  • entree
  • ベストアンサー率55% (405/735)
回答No.2

プログラムのバグ等により、データに間違って NULL が入ってしまわないようにするためです。 そして、最大の目的はデータとプログラムを切り離すためです。(DOA の概念。データベース内のデータは単独で意味を持つ。そもそも、データベースとは単にデータを入れる箱ではない) 一意制約やチェック制約、参照制約についても同様です。 特に、Oracle の場合は制約の有無によって実行計画が変わる場合があるので、そういう意味でも意味があると思います。例えば、ORDER BY 句で指定された列に索引が張られている場合、NOT NULL 制約がなければソート処理が行われますが、NOT NULL 制約があれば索引が使用できるためソート処理は発生しない可能性があります。(NULL のデータが索引にはないため。NOT NULL 制約がないと Oracle は ORDER BY でのソートに索引が使えることを理解できない)

noname#53515
質問者

補足

回答ありがとうございます。 データとプログラムを切り離すという 概念はわかりました。 今回なぜこういう質問をしてしまったかと言いますと、 ユーザからいただいたテーブルファイル定義では、 関連がないだろう?という項目が色々1つのテーブルに定義されていて、 その項目ほぼ全てにNotNull設定されていたからです。 そのテーブルに対するレコードは、私が作成する画面で登録します。 ウィザード形式のような画面でしたら セッション上に蓄積したデータを最後に一気に書き込むという事ができます。 ですが今回のケースではこちらの作業範囲ではない 別のサブシステムから更新される項目で、 私が作成する画面では初期値を設定できないのです。 仮にフラグ類や金額だけでしたら 『0』を初期値とさせてもらうことで対応できるかとも思ったのですが、 それ以外の各種コード類にまでNotNull制約が張られている始末です。 もうちょっと正規化して、別テーブルにしてもらえませんか?とお願いもしましたが、 もう決まっているから駄目と言われました。 それで一体どうすればいいのかわからなくなって、 全項目NotNullを外せばいいんじゃないか?と思って質問してしまいました。 こういう場合、どういう対処が望ましいのでしょうか?

回答No.1

プログラム側でチェック処理が常に完全に行われればよいですが、 その保証はありません。DB側でNOT NULLであれば、NULLであった 場合例外が発生しますので、絶対的なチェックの保証ができます。 チェックはプログラム側のみでよいというのであれば、それは 個人の判断になると思います。 プログラムとDBのほうでチェックを2重にすれば完璧です。

noname#53515
質問者

補足

回答ありがとうございました。 また、今回の質問の意図からずれてしまうのですが、 上記の内容について教えていただけたら幸いです。