27

データベース スキーマを設計していますが、各列が必要かどうかを決定するためにどの基準を使用すればよいnullableか考えています。

アプリケーションにとってまったく意味を成すために、行に絶対に入力する必要がある列のみを NOT NULL としてマークする必要がありますか?

または、null にならないようにする予定のすべての列をマークする必要がありますか?

少数の NOT NULL 列と多数の NOT NULL 列のパフォーマンスへの影響は何ですか?

NOT NULL 列が多いと挿入が少し遅くなると思いますが、クエリ実行プランジェネレーターには列に関するより多くの情報があるため、実際には選択を高速化する可能性があります..

私よりも知識のある人が私にローダウンを与えることができますか?

4

15 に答える 15

30

正直なところ、私は常に NOT NULL がデフォルトであるべきだと思っていました。NULL は奇妙な特殊なケースであり、使用するときは常にケースを作成する必要があります。さらに、列を NOT NULL から NULL 可能に変更する方が、逆に変更するよりもはるかに簡単です。

于 2009-03-18T00:06:56.880 に答える
15

重大なパフォーマンスへの影響はありません。これを問題として考えることさえ考えないでください。そうすることは、初期の巨大な最適化のアンチパターンです。

「アプリケーションにとってまったく意味を成すために、行に絶対に入力する必要がある列のみを NOT NULL としてマークする必要がありますか?」

はい。それはそれと同じくらい簡単です。NULLが必要でそれを偽造するよりも、NULL値を含まないNULL可能な列を使用する方がはるかに優れています。とにかく、あいまいなケースは、ビジネス ルールで除外する方が適切です。


編集:

Null 許容フィールドについて、最終的に最も説得力があると私が考えるもう 1 つの議論があります。それは、ユース ケースの議論です。私たちは皆、いくつかのフィールドに値を要求するデータ入力フォームの影響を受けてきました。そして、必須フィールドに適切な値がなかったフォームはすべて放棄しました。最終的に、アプリケーション、フォーム、およびデータベースの設計は、それらがユーザーの要件を反映している場合にのみ防御可能です。また、ユーザーが価値を提示できないデータベース列が非常に多く存在することは明らかです。ビジネス プロセスの特定の時点で、場合によっては常に存在することもあります。

于 2009-03-17T23:37:59.493 に答える
12

NOT NULL 側でエラー。ある時点で、アプリケーションで NULL が「意味する」ものを決定する必要があります。おそらく、列ごとに異なるものになるでしょう。一般的なケースのいくつかは、「指定されていない」、「不明」、「適用できない」、「まだ発生していない」などです。これらの値のいずれかが必要になる時期がわかれば、NULL 許容列を適切に許可して、その周りのロジックをコーディングします。

ランダムなものを NULL にすることは、遅かれ早かれ、常に悪夢のような IME です。NULL は慎重かつ控えめに使用し、ロジックでの意味を理解してください。

編集: null列がないと主張しているという考えがあるようです。それはばかげている。NULL便利ですが、それが期待される場合に限られます。

Le Dorfier の DateOfDeath の例は良い例です。NULL DateOfDeath は、「まだ起きていない」ことを示します。これで、ビュー LivingPersons を作成できますWHERE DateOfDeath IS NULL

しかし、NULL OrderDate とはどういう意味ですか? まだ注文してないってこと?Order テーブルにレコードがあるのに? NULL アドレスはどうですか?NULL を値にする前に、これらのことを頭に入れておく必要があります。

DateOfDeath に戻ると、人のクエリはNULL レコードを返しません。論理的には 1999 年以降に死亡する必要があるWHERE DateOfDeath > '1/1/1999'ことがわかっているにもかかわらずです。それはあなたが望むものですか?そうでない場合は、そのクエリに含めることをお勧めします。すべての列を NULL にすることを許可する場合、クエリを作成するたびにそれについて考える必要があります。IME、これは、NULL の場合に実際に正当な意味を持つ 10% ほどの列にとって、精神的な負担が大きすぎます。OR DateOfDeath IS NULL

于 2009-03-18T00:21:34.553 に答える
10

データベースで NULL をできるだけ使用しないようにしています。これは、文字フィールドが常に null ではないことを意味します。数値フィールド、特にお金などを表すもの (株、単位など) についても同様です。

2 つの例外があります。

  1. 日付がわからない可能性がある日付 (例: DivorcedOn)
  2. オプションの外部キー関係 (MarriedToPersonId)。場合によっては、外部キーテーブルで「空白」行を使用し、関係を必須にしました(例:JobDescriptionCode)

また、「不明」/「未設定」のビット フィールドを明示的に使用することもありました (JobDescriptionCode や IsEmployeed など)。

いくつかの主な理由があります。

  1. NULL は常に数値フィールドで問題を引き起こします。いつも。いつも。いつも。合計が発生し、NULLが返されるため、ある時点でX + Yを選択することにどれほど注意を払ってもかまいません。
  2. NULL は、文字列フィールド (通常はアドレス フィールド) で簡単に問題を引き起こす可能性があります (たとえば、Addresses から AddrLine1 + AddrLine2 を選択します)。
  3. ビジネス ロジック層で NULL を保護するのは、面倒な労力の無駄です。DB に入れないようにすれば、数百行のコードを節約できます。

私の好みのデフォルト:

  • 文字列 -> ""、別名空の文字列
  • 数字 -> 0
  • 日付 -> 今日または NULL (例外 #1 を参照)
  • ビット -> false
于 2009-03-18T00:41:12.977 に答える
10

I have found marking a column as NOT NULL is usually a good idea unless you have a useful meaning for NULL in the column. Otherwise you may unexpectedly find NULL in there later when you realise you don't want it, and changing is harder.

于 2009-03-17T23:44:09.197 に答える
7

Chris Date のDatabase In Depthは、こ​​の種の質問に役立つリソースです。このインタビューで彼のアイデアを味わうことができます。彼は次のように述べています。

はい、そうです、SQLはかなり悪いと思います。しかし、あなたはその主要な欠陥が何であるかを明確に尋ねます。さて、ここにいくつかあります:

  • 行を複製する
  • ヌル
  • 左から右への列の順序
  • 名前のない列と重複する列名
  • 「=」が適切にサポートされていない
  • ポインター
  • 高冗長性

私自身の経験では、ほぼすべての「計画された NULL」は、ベース テーブルへの外部キーを持つ子テーブルでより適切に表現できます。子テーブルへの参加はオプションであり、null/not null の区別が実際に行われる場所です。

これは、一次論理命題としての関係の解釈によく対応します。それもまた、ごく当たり前のことです。ボブの住所がわからない場合、自分のロロデックスに次のように書きます。

Bob. ____

それとも、ボブの実際の住所がわかるまで、ボブの住所カードに記入することを控えるだけですか?

編集: Date の引数は、Database In Depth の 53 ~ 55 ページのセクション見出し「Why Nulls are Prohibited 」の下に表示されます。

于 2009-03-18T00:56:22.737 に答える
4

すべての素晴らしい答えをありがとう、みんな。あなたは私に多くのことを考えさせてくれ、私が自分の意見/戦略を立てるのを手伝ってくれました。

その列のnullがアプリケーションにとって特定の意味を持つ場合に限り、nullを許可します。

nullの一般的な意味のいくつか:

  • ユーザーから直接来るものすべて
    • ここでnullは、「ユーザーが入力しなかった」ことを意味します
    • これらの列については、nullを許可することをお勧めします。そうしないと、とにかくasdasd@asd.comタイプの入力を取得するだけです。
  • 「0または1」関係の外部キー
    • nullは、「関連する行がない」ことを意味します
    • したがって、これらの列にはnullを許可します
    • これは物議を醸していますが、これは私の意見です。

一般に、列内のnullの有用な意味を考えることができない場合は、である必要がありますNOT NULL。後でいつでもnull許容に変更できます。

私が最終的に得たようなものの例:

create table SalesOrderLine (
    Id int identity primary key,
    -- a line must have exactly one header:
    IdHeader int not null foreign key references SalesOrderHeader, 
    LineNumber int not null, -- a line must have a line number
    IdItem int not null, -- cannot have null item
    Quantity decimal not null, -- maybe could sell 0, but not null
    UnitPrice decimal not null, -- price can be 0, but not null
    -- a null delivery address means not for delivery:
    IdDeliveryAddress int foreign key references Address, 
    Comment varchar(100), -- null means user skipped it
    Cancelled bit not null default (0) -- true boolean, not three-state!
    Delivered datetime, -- null means not yet delivered
    Logged datetime not null default (GetDate()) -- must be filled out
)
于 2009-03-18T23:18:50.217 に答える
4

他の理由がない限り、私はNOT NULLに傾倒します。他の誰かが言ったように、好きかどうかにかかわらず、NULLは奇妙な特殊なケースです。

NULLに関する私のお気に入りの1つは次のとおりです。

SELECT F1 FROM T WHERE F2 <> 'OK'

...これは(少なくともDB2では)f2がnullである行を含みません-リレーショナル用語では、(NULL <>'OK')はNULLであるためです。しかし、あなたの意図は、すべてのOKではない行を返すことでした。追加のOR述語が必要であるか、代わりにF2 DISTINCT FROM'OK'と記述します(これは、そもそも特殊なケースのコーディングです)。

IMO、NULLは、ポインター演算や演算子のオーバーロードなど、科学と同じくらい多くの芸術を必要とするプログラマーのツールの1つにすぎません。

Joe Celkoは、これについてSQL For Smartiesで書いています。アプリケーションでNULLを使用することの落とし穴は、その意味が未定義であるということです。それは、不明、初期化されていない、不完全、適用できないことを意味する可能性があります-または上記のばかげた例のように、それはOKまたはそうでないことを意味します-OK?

于 2009-03-18T01:31:23.667 に答える
2

I would tend to agree with dorfier.

Be serious in your application about being flexible when receiving database NULL values and treating them as empty values, and you give yourself a lot of flexibility to let NULL's get inserted for values you don't specify.

There's probably a lot of cases where you need some very serious data integrity (and/or the intense speed optimization of disallowing NULL fields) but I think that these concerns are tempered against the extra effort it takes to make sure every field has a default value and/or gets set to a sensible value.

于 2009-03-17T23:43:33.880 に答える
2

誰かがそれについて痛みを訴えるまで、すべてに NOT NULL を使用してください。次に、できるだけしぶしぶながら、一度に 1 つの列でそれを削除します。できる限り、DB 内の null をできるだけ避けてください。

于 2009-03-18T00:37:10.553 に答える
1

少数のNOTNULL列と多数のNOTNULL列のパフォーマンスへの影響は何ですか?

これは明らかなことを示しているかもしれませんが、列がnull許容の場合、各レコードには1ビットの追加ストレージが必要になります。したがって、BIT列はNULL可能の場合に100%多いストレージを消費しますが、UNIQUEIDENTIFIERはNULL可能の場合に0.8%多くのストレージを消費します。

病理学的なケースでは、データベースに単一のBIT列で構成される単一のテーブルがある場合、その列をnull許容にするという決定は、データベースのパフォーマンスを半分に低下させます。ただし、実際のシナリオの大部分では、ヌル可能性がパフォーマンスに測定可能な影響を与えることはありません。

于 2009-03-18T01:32:35.117 に答える
1

長期的に考えると、列に NULL があると、クエリの設計方法に影響します。CASE ステートメント、COALESCE を使用するか、NULL 値を明示的にテストする必要があるかによって、決定を下すことができます。

パフォーマンスの観点からは、NULL を気にする必要がない方が高速です。設計の観点から、NULL を使用すると、項目が入力されていないことを簡単に知ることができます。有用な例には、「UpdatedDateTime」列が含まれます。NULL は、アイテムが更新されていないことを意味します。

個人的には、ほとんどの状況で NULL を許可します。

于 2009-03-17T23:49:05.973 に答える
0

'Not Null' または 'Null' の使用は、主に特定の永続化要件によって決定される必要があります。

値が Nullable であることは、2 つまたは 3 つの状態 (ビット フィールドを持つ 3 つの状態) があることを意味します。

例えば; 「IsApproved」と呼ばれるビット フィールドがあり、値が挿入より後の段階で設定されている場合。次に、3 つの状態があります。

  1. 「IsApproved」未回答
  2. 「IsApproved」は承認済みです
  3. 「IsApproved」は承認されていません

そのため、フィールドが正当に未回答と見なされ、適切なデフォルト値がない場合。これらのフィールドは、null 可能であると見なす必要があります

于 2009-03-22T22:12:51.927 に答える
-1

null許容列は、第3正規形に違反します。

しかし、それは答えではありません。

データベースには、データの構造を保持する列とデータのコンテンツを保持する列の2種類の列があります。キーは構造であり、ユーザーが入力可能なフィールドはデータです。他のこと-まあ-それは判断の呼びかけです。

結合句で使用される構造体は、通常、nullではありません。データであるものは通常null許容です。

選択肢のリストまたはnull(選択なし)のいずれかを保持する列がある場合、通常、null許容列ではなく、「選択肢なし」の特定の値を指定することをお勧めします。これらのタイプの列は、多くの場合、結合に参加します。

于 2009-03-22T02:32:07.163 に答える