OracleでNULL可能数を使用しない理由は?


12

私たちの会社は、共同プロジェクトのために他のソフトウェア会社とインターフェイスをとっており、特定の値を表示しない場合は、-5000(任意のセンチネル値)を渡す必要があると言われました。その理由は、(以前の)Oracle開発者の推奨により、Oracleデータベースの数値列がnull値をサポートしていないためです。また、この会社はコードの大部分をVB6で記述しています(VB.NETへの移行はゆっくりと進んでおり、これもまた別の日のトピックです...)。純粋な好奇心から、この推奨事項の正当な理由はありますか?私の側に何も考えられません。

---編集

すべてのフィードバックをありがとう。CodeProject.com(link)で同じ質問を投げかけ、非常によく似たフィードバックを受け取りました。この方法が外部キーに関連していることを正当化できる可能性があるのは唯一のようであり、システム内のどこでも外部キーを使用しないと述べることができます。この決定をした開発者(私は以前その会社で働いていた)は、私よりもはるかに多くの経験を持っているので、ris笑が起こる前に、これに対する正当な理由がないことを確認したかった。


2
「それは彼らのAPIが指定するもの」以外のことですか?
ロバートハーベイ

はい、私は彼らのAPIがそもそもそれを指定する理由についてもっと興味があります。この練習の理由はありますか、それとも単なる狂気ですか?

3
最高位のルナシー!
フィリ

回答:


17

現実には、要件はクレイジーです。しかし、すべての素晴らしいクレイジーなアイデアと同様に、それはおそらく、根本的な理論的根拠を理解していない人々によって文脈から大きく外れた潜在的な合理性のナゲットに基づいています。

NULL値が許可されないようにデータベーススキーマを設計することは合理的です。ただし、そうする場合は、すべての不要な要素が適切な外部キー参照を含む別のテーブルに分割され、親に戻る正規化レベルにコミットします。実際に行われることはあまりありませんが、意味がある場合には利点があります。

NULL値が許可されないようにデータベーススキーマを設計する場合、未知のものであることを示すために魔法の値を必要とするのは言うまでもありません。NULL値を許可することで生じるすべての問題に加えて、場所全体で繰り返される必要がある魔法の値をチェックするためのコードが追加されます。データベースの設計に関係なく、マジック値を渡す必要があるAPIを開発することは意味がありません。マジック値のチェックでコードを妨害する場合、その狂気を他のシステムに広めるべきではありません。


+1と魔法の値をチェックするための追加のコードは、次のようなよく知られた関数を使用できませんCOALESCE()-そのため、さらに複雑になります。
ypercubeᵀᴹ

そして、その列のインデックスに値を保存する必要があります。インデックスにnull値を格納する必要はありません。
トリップキネティクス

15

NULLの代わりにマジック値を使用する有効な理由はありません。これは、この混乱を作成する誰かの思考プロセスかもしれません。彼らは次のように書きます:

 SELECT c1, c2 FROM t1 WHERE c3 < 30;

これが期待する結果を返さない場合、彼らはそれがNULLを含まないことを理解し、これを書く必要があるでしょう:

SELECT c1, c2 FROM t1 WHERE c3 < 30 OR c3 IS NULL;

これを書いたり、将来これを書くことを忘れたくないので、すべてNULLS -5000を作成するソリューションを考え出します。魔法のように、元のクエリは変更なしでNULLを処理します。彼らが気付いていないのは、これらの値を除外したい人がこれを書かなければならないということです。

SELECT c1, c2 FROM t1 WHERE c3 < 30 AND c3 <> -5000;

または、これらの値が必要で、より高い範囲を検索している場合:

SELECT c1, c2 FROM t1 WHERE c3 > 40 OR c3 = -5000;

また、次のことがもはや意味がないことを認識していない場合があります。

SELECT c1, c2 FROM t1 WHERE c3 IS NULL;

代わりに、人は魔法の価値を覚えなければなりません。使用される各データ型では、1/1 // 1900、 "Z"、-5000など、より多くのマジック値を覚えておく必要があります。さらに、マジック値がデータ内にある場合、代替のマジック値も記憶する必要があります。

そのため、ある特定のケースでは、ディスク容量、インデックスサイズ、クエリ解析、一貫性などは言うまでもなく、他のケースを犠牲にしてコードを単純化します。


8

それは完全な狂気であり、それを正当化する理由はありません。NULL値がないことを表すために作成され、-5000などの実際の値を使用するのはおかしいです。

通常、これほど短い回答は書きませんが、質問はdba.seで最も目立つものの1つであり、回答が多いほど良いと言えます。


5

私はこれを少し肯定的にしようと考え、nullの代わりに任意の値を使用する必要性を正当化し、おそらく少なくとも閉じたデータマイニングデータセットを除いて、これの正当な理由はないようですパフォーマンスとクエリを改善および簡素化し、数値がデータを歪める可能性のある値ではない場合のみ。これでも慎重に検討する必要があります。すべての実際の状況では、nullに値を与えることは良い習慣ではありません。これは実際には正しくないため、NOT NULL列の定義を友人から敵に変えます。

アプリケーションが一部の(またはすべての)カラムに対してNULL値を受け入れてはならないということは、まったく異なります。これは賢明で優れた実践であり、null(キーやインデックス、統計計算など)を許可しないことによる利点は十分に文書化されています。ただし、nullの「その場所に座って」に値を割り当てることはまったく同じではありません。これはあなた自身の背中のロッドです。最初に使用されることのない値を選択し、nullのようにこの値をフィルターで除外し、計算や集計で使用しないで、外部データフィードから削除することを忘れないでください。これは、少なくとも実際の値を表すためにnullを使用するのと同じくらい悪いです。

nullが原因のほとんどの問題は、一度理解されると、対処できます(より良い正規化、関数ベースのインデックス、ビットマップインデックス、または単純なWHERE x IS NOT NULL)。大規模な電話会社やアマゾンで、毎月のパフォーマンスミーティングで、DBAは巨大なデータセットに対するクエリを少し高速化するというこの素晴らしい計画の概要を、「nullを-5000などの任意の値に置き換えることで-私はその価値に心を開いています...」。または、不要なヌルを除去するためのより良いアプリケーション設計と、与えられ実際のデータに基づいたクエリ最適化とに時間を費やしていると思いますか?毎月の会議は少し楽観的かもしれませんが、それが起こるたびに「nullを-5000(または何でも)でより良いAPIに置き換える」ことは議題ではないことを保証できます。

私にとっては、不足しているデータ(年齢、価格、地域コードなどが必要です)を受け入れないと言うことは問題ありませんが、この列にはデフォルト値があり、あなたは他のものを入れません。nullを意味する値を別にしておくのは問題ありません。例としてミドルネームのフィールドを考えてください。両親はすべてのボックスを埋めるのが面倒なので、時々これらは存在しません。検索を改善するために、データに「なし」または「欠落」または「不明」を追加しますか?いいえ、名前をこれらの値に変更する奇妙な人がいる可能性があるため、データを印刷するときに、含める必要があるかどうかわかりません。これは単純ですが、広範囲に及ぶ例です。NULLについて知っており、それに対処するための予測可能な組み込み関数があります。これをより良くコーディングすることはできません。

回答がない(またはNULL)が入力要求に対する有効な応答でない場合、アプリケーションまたはデータベースで許可しないでください。適切な応答である場合は、アプリケーションとデータベースの両方で許可し、対処する必要があります有効な応答として。有効な応答のセットの一部である場合、データベースはそれを格納するように設計する必要があります。結局のところ、数値フィールドは退屈なので、数値をblobに保存し、野生動物の写真を使用して各数値を表すことができます。また、文字Bが気に入らないと判断したり、セサミストリートの悪夢のようにデータの#に置き換えたりすることもありません。Bが応答でない場合、ユーザーに「ねえ、ここにBを置くことはできません」と伝えます。それでは、なぜnullを異なる方法で扱うのでしょうか?

したがって、アプリケーションレベルで不要なnullを回避し、giraffe + giraffe = hippoのようにそれらを受け入れるデータベースでそれらを処理します。


2
私の両親は怠け者ではなく、ちなみにミドルネームはありません。すべての人が米国に住んでいるわけではありません。
ypercubeᵀᴹ

1
それは気楽な例であり、犯罪を意味するものではありませんでした。もちろん、多くの正当な理由(主要なポイント)からミドルネームのない人(最初のポイント)がたくさんいます。この列のヌルは、それが欠落していた理由については何も伝えません。あなたの地政学的な角度についてはわかりません-私はアメリカに住んでいませんが、実際にはミドルネームを持っています。私が推測する欠落データに基づいて推測することは困難です。

犯罪なし。私はあなたの答えを実際に支持しました。データベースでNullを受け入れない/許可するのと、Nullを魔法の値で置き換えるのとでは違いがあるという主な点で、あなたは釘を打ったと思います。
ypercubeᵀᴹ

5
私のミドルネームが「-5000」だったら、それが大好きです!:D
フィリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.