SQLの列がデフォルトでnull可能であるという説得力のある理由はありますか?


8

私はCSの学生として、長年にわたってまともな数のプログラミング言語を学びました。そのほとんどは、「null可能」または「オプション」タイプの概念を持っています。ここでは、nullポインターや参照、JavaScriptのような弱く型付けされた言語については触れていませんnull。私が話していることの例には、boost::optional(C ++)、java.util.Optional(Java 8.0)、prelude.Maybe(Haskell)、およびすべての「?」種類(例えばint?float?、C#やKotlin)。これらは、厳密な静的型システム内で、以前はnullにすることができなかった型にnullの可能性を追加する構成体です。

SQLにも同様の概念があります。たとえば、INTEGERnull可能またはnull不可にできるような型ですが、ひねりがあります。SQLでは、INTEGERデフォルトでnull可能であり、null INTEGER NOT NULL不可になるように明示的に記述する必要があります。

NULLをデフォルトの動作にすることを許可することは非常に直観に反し、潜在的に危険であると私は思います。明らかに、SQLはこの時点で非常に長い間存在しており、(ほとんどの)SQL開発者はNULLの落とし穴について健全な認識を築いています。しかし、私は仕方がないのですが、初期の頃、NULLが予期せず問題のある場所に忍び込んでいたことを想像してみてください。

SQLは私が提供したすべての例よりも古いため、これは単に歴史的な進化の問題である可能性があります。それでも、私は尋ねなければなりません、言語がこのように設計され、型がデフォルトでnull可能であるという正当な理由はありますか?

もしそうなら、それは単なる歴史的な理由でしょうか、それとも今日のデータベース設計にロジックは耐えますか?

編集:なぜNULLがSQLの一部であるのか、またはNULL可能列がなぜ有用なのかは尋ねていません。列がデフォルトで null可能である理由を尋ねています。たとえば、次のように書くのはなぜですか。

column1 FLOAT,
column2 FLOAT NOT NULL

のではなく:

column1 FLOAT NULLABLE,
column2 FLOAT

2
この答えを受け入れることを学んでください:「理由はありません。それは私たちのポリシーです。」

2
なぜなら、「私にはわからない」という概念は、データベースで明確な方法で表現する必要があるためです
Newtopian

NULLが言語に含まれている理由を説明する@Newtopian。デフォルトでNULLが許可されている理由を尋ねています。
への接近

4
「知らない」はデータベース情報で意外と多いからです。この点を例を挙げて説明します。すべてのフィールドがデフォルトで必須であるWebフォームと、それがいかに煩わしいかを想像してください。データベースでは、常にすべてのフィールドに何かを入力する必要があります。ただし、ドメイン表現では、この情報の多くは必須ではなく、「不明」のままにして、悪影響を及ぼさないようにすることができます(コードを適切に保護している場合)。実際、私はほとんどのアプリケーションでほとんどの情報がこの必須ではないカテゴリに分類されることを期待します。したがって、デフォルトが表示されます
ニュートピア

@Newtopianよし。その答えを作ってください。
DarknessFishへのアプローチ

回答:


24

ユニで私は反対が真実であることを教えられました。not null理由なく何かを作ることははるかに危険です。null可能フィールドを使用すると、発生する可能性のある最悪の事態は、データにアクセスするアプリケーションをつまずくことです。 ああ、戻ってアプリを修正して...

null以外のフィールドを使用すると、一部の任意のフィールドが使用できないため、レコードを追加できなくなります。 ここで、データモデルを変更し、さまざまな場所のLOTで結果を潜在的に修正する必要があります...

null「不明」と考えるのは良いことです。何かを知らずにレコードを入力したい理由がある場合は、nullにすることができます。

私の大学の講師の1人が次のように説明しています。

申し訳ありませんが、顧客の社会保障番号を要求して販売を行う米国の販売システムについて聞いたことがあります。外国人がレジに来たときにすべてのレジオペレーターが行ったのは、000-00-0000でした。しかし、他の人は123-45-6789と入力します。これにより、ジャンクを識別することができなくなります。強制的にジャンクを含めるよりも、フィールドを空白にすることをお勧めします。

または別の話。電話番号が2つないので、自動車保険を拒否されました。彼らが私に2つを与えない限り、彼らは絶対に私に保険を与えません。営業担当者は、私が間違ったものを与えることを提案しました。結局、保険会社に嘘をつくことを拒否し、別の会社と一緒に行きました。

実際にnot nullは、レコードの意味を理解するために必要なフィールドを予約してください。例えば:

フィールド(ID、場所名、国、経度、緯度)を持つ場所のテーブル...「経度」「緯度」は、場所がどこにあるかがわかる前にその場所の存在を保存できるように、nullにすることができます。

しかし、フィールド(Item_id、経度、緯度)を持つ地理的座標を格納することだけを目的とするテーブルがある場合、経度と緯度がnullの場合、レコード全体は意味がありません。したがって、このインスタンスでは、それらはnullではないはずです

ユニからの私の専門的な経験では、必須である必要があるよりもオプションであることができるフィールドがはるかに多くあります。


上の引用ブロックで誰を引用していますか?
Robert Harvey

大学教授。
Philip Couling

8

直感に反しているように感じます...

直観は見る人の目にあり、それに対するあなたの意見は、あなたがさらされてきたものによって形作られます。私はそのような安全性が標準的でなく、あなたが間違えたときにツールが指摘しなかった時から声をかけます。私はブレードガードなしでチェーンソーを使用してきましたが、直感を完全に回避し、DDLに戻って、スキーマによってデータについてどのような仮定ができるかを正確に理解するのが最初の本能でした。

...そしてNULLをデフォルトの動作にすることを許可することは潜在的に危険です。

あなたは相対的な危険を過大評価していると思います。 NOT NULLには、同じように潜むバグにつながる可能性のある独自の落とし穴があります。(それらを列挙すると、別の質問の飼料になるでしょう。)

テーブルの設計者は、常に列を制約するオプションを持っているNULLか、NOT NULLそれが何であれ、デフォルトを回避するために、1つまたは他の操作を行います。列を正しく制約しないことは、開発者がビジネスルールに従わないことです。列の定義に基づいて他の場所で正しいことを行わないことは、開発者が渡されているデータを理解できないことです。どちらにも技術的な修正はありません。

それでも、私は尋ねなければなりません、言語がこのように設計され、型がデフォルトでnull可能であるという正当な理由はありますか?

いいえ、ありません。どちらにも危険があるため、言語を逆に設計する正当な理由もありません。それはあなたの毒を選ぶことです。


6

外部結合(左結合または右結合とも呼ばれます)のため、SQLではNULL可能列が必要です。結合の片側の行が反対側で一致しない場合、反対側のフィールドにはNULLが必要です。結合の出力にはnull値を許可する列が含まれる可能性があるため、リレーショナルクロージャの原則により、ベーステーブルもそれらをサポートする必要があります(基本的には、クエリまたはビューの結果はベーステーブルと区別できないはずです)。

このため、SQL null許容列をサポートする必要があります。一方、null不可の列は二次機能です-SQLは列なしでも機能します。


4

それを裏返して、あなたが正しいと言いましょう。整数がデフォルトでnullではないとします。

つまり、デフォルトで値を設定する必要があります。知らない時でも。

したがって、personsテーブルを更新し、2つの選択肢がある場合:体重を入力しなかったため、テーブルを更新することは不可能です。あるいは、あなたが未知数であるとき、それが標準の「-1キロ」に入れた重量引数を与えなかったとき。

どちらの状況も望ましくありません。顧客の体重がわからなくても、顧客を追加できるようにしたい。しかし、また、「プロキシ」値を持つ必要はありません。プレースホルダーであるが実際の意味を持つことができる値。たとえば、「平均」などの数学関数で使用できますが、実際の値ではありません。

つまり、平均重量を計算する場合、-1は数学平均関数で有効な値ですが、人の重量としては有効ではありません。nullを使用すると、平均関数はその値を無視するようになります。

また、nullについて説明するとき、SQLをプログラミング言語と実際に比較することはしません。それらは本質的に異なり、SQLのnullはリレーショナルデータベースの設計理論の大部分を占めています。


3

いいえ。SQLがデフォルトでnull許容に設定される理由はありません。実際、リレーショナルデータベース理論の著名な研究者の多くはこの設計の決定に同意していません。おそらく最も重要なのは、リレーショナルデータベースの元の設計者であるEdgar Coddと頻繁に協力しているChris Dateです。(共著者ヒュー・ダーウィンと一緒に)日付は、リレーショナル理論(」上の有名な著書に公開第三のマニフェスト『と呼ばれる例などの言語と一緒に、彼らは『D』と呼ぶリレーショナル言語の家族のための代替設計のための原則を説明します』)チュートリアルD "。

D言語は、NULL値のサポートを明示的に禁止されています(「Dには、いくつかの「タプル」に、値を持たない「属性」が含まれる「関係」の概念は含まれません。」)代わりに、オプションの値は、プレースマーカーの「存在しない」または同様の値を含む代替データ型を持つことでサポートされます。D言語は、ユーザー定義型の豊富なモデルを提供します。これにより、任意のネイティブ型をそのような追加の値で拡張できます。

これが良いアイデアである説得力のある理論的な理由があり、Date&Darwenは、これと、設計で行った他の決定について多くのことを書いています。このトピックに関する彼らの作品を読むことを強くお勧めします。


1
私はあなたの論理に従いません/同意しません。私はあなたが2つの別々の問題を融合していると思います。問題a)言語はnullを表す必要がありますか? 問題b) nullを使用して「存在しない」ことを意味する言語では、フィールドはデフォルトでnull(存在しない)を許可する必要がありますか?おそらく、あなたはあなたの答えのステップを見逃している... あり、項目C) Dには、属性は、デフォルトではない-存在を許してはなりません....これは、<ここに引数の挿入>
フィリップCouling

2
私の最初のコメントは理解するのが難しいので、簡単に説明します。それ Representing x with null is a bad ideaは推測されませんallowing x by default is bad。エルゴはそれを意味するものではありませんallowing null by default is bad where null is the only available representation of x
フィリップ・クーリング

1
@jules int-fieldがnull可能であることと、別のデータ型を持つint-fieldの概念的な違いは何ですか?「存在しません」?同じ名前で違うのではないですか?nullは、intの代替データ型でもあります。
Pieter B

1
@PieterBはい、いいえ。nullの基本的な問題は、nullが多すぎることを意味するために使用されることです。SQLでは、「存在しない」または「不明」を意味する場合があります。Dの引数は、これらはすべて明確に定義されるべきであり、キャッチオールの「null」は決して使用されるべきではないということです。詳細に検討していNot Present = Not Presentなかったので、Dの支持者はSQLのどこにあるnull = nullか、どちらnull != nullが真実でないかを主張するのではないかと思います。
Philip Couling

コッドはもっと多くのタイプのヌルがあるべきだと言った、私は彼が最初に4を提案し、後で17に拡張したと思います確かに、既知の未知数と未知の未知数がありますが、実際には、データは既知の既知のものであり、それ以外はあまりありません。

1

デフォルトがどうあるべきかについてあなたの前提に同意するわけではありませんが、開発者として何も仮定しないことをお勧めします。データベーステーブルの仕様をチェックすることはそれほど難しくありません。

特に他のシステムからマージする場合にデータをバルクロードするように求められるDBAの観点からは、データを入力するかどうかに関係なく、各フィールドの設定をよく理解できます。

ビジネスやアプリケーションは人が運営しています。彼らがプログラマーでない場合、「決して」と「常に」の定義は完全に同じではなく、時間とともに変化します。特定のフィールドの現在のnull設定はあいまいであってはなりません。


データは実際に価値のあるものであり、プログラムはそれを形作る一時的なツールにすぎないため、正しい、一括読み込み、移行などが最終的に他のすべての懸念に勝ります。パンチされたカードや1900年の国勢調査のレコーディングマシンを見た人はいますか?いいえ、ただしデータは引き続き利用できます。過去1年間で、あるシステムから別のシステムに何回移動されましたか?誰かがそれを使うたびに、私はそう思う。

0

データベースは、通常のプログラミング言語とは異なる動物です。

テーブルのスキーマが設定されているため、情報を行に保存するときにすべてのデータが存在する必要があります。ただし、このデータの多くは、コードに読み込まれると、モデルオブジェクトの有効な表現を作成するために必要とされない場合があります。すべてのデータが非nullであり、データが入力されている必要があるということは、これらの必須ではないフィールドに値が含まれている必要があり、まだ値がないため「不明」であることを意味します。

Webフォームのすべてのフィールドを常にデータベースに入力する必要があることを想像してください。これらのフィールドはデータベースではnullにできないため、値を受け取る必要があります...狂気のレシピです。

データの種類に応じて、データの欠如、空の文字列、特定の数値、特定の日付などを表す予約済みの値を設定できますが、どの値を選択しますか?次に、たとえば、これらの任意の値が実際には「不明」を意味し、「1970年1月1日」ではないことを全員が同意することを確認する必要があります。null嫌悪は多くのを取り、誰かがnullが悪いと言っただけで長い複雑な回り道に連れて行くことができます。nullの処理を回避するためだけに取得する準備はどのくらい複雑ですか?

未知のすべてに対して単一の普遍的な値を持つことは、任意の定数値のセットを使用するよりもはるかに好ましいと思います。私は定数値が悪く、nullがより良いと言っているわけではありません。モデルがこの情報を表す定数によって十分に提供されている場合は、必ずそれを使用してください。すべてのnull嫌い者にとって、これはnullが拒否された場合は発明する必要がある状況です!

「不明」という概念がデータベースにどれだけ広まっているかを見てみると、そうです、値をnullに設定できるようにすることは、デフォルトで非常に理にかなっていると思います。

さらに深く、ここで他の回答を見てみると、nullは単なる「言語機能」ではなく、SQLの基礎となっている理論の不可欠な部分であることを知って驚くことはありません。相対性理論からC(光速)を取り除くことはできますが、絶対最大速度の概念は残っており、何らかの形または形に戻るように表現する必要があります。


0

短い答え:下位互換性。

長い答え:

完全に正規化されたデータベースでは、NULLはどの列でも許可されていません。たとえば、整数であるPostOfficeBox列を持つMailingAddressというテーブルがあるとします。誰もが私書箱を持っているわけではないので、これを実装するには2つの方法があります。

まず、列でNULLを使用できます。

次に、PostOfficeBoxがMailingAddressと新しいテーブルから削除されます。PostOfficeBoxは列Numberで作成され、そのPKはMailingAddressへのFKです。しかし、今では郵送先住所を取得するために2つのクエリが必要です。

SQLでは、実用的な目的で列にNULLを使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.