NULLを使用する場合と空の文字列を使用する場合


82

主にMySQLとPostgreSQLに興味がありますが、一般的には次のように答えることができます。

  • 空の文字列とNULLを区別するのに役立つ論理的なシナリオはありますか?
  • 空の文字列を次のように保存するための物理ストレージの意味はどうなりますか?

    • ヌル?
    • 空の文字列?
    • 別の分野?
    • その他の方法で?

回答:


67

レコードは、名前と住所の情報を収集するフォームから取得したとしましょう。ユーザーがアパートに住んでいない場合、住所の2行目は通常空白です。この場合の空の文字列は完全に有効です。NULLを使用して、値が不明または指定されていないことを意味する傾向があります。

物理的なストレージの違いは実際には心配する価値がないと思います。データベース管理者として、もっと大きな魚を揚げる必要があります!


2
+1使用するNULLかどうかの速度/サイズの違いを心配する必要があるdbaはごくわずかです
パトリック

28
同意しました...「不明」のためにNULLを予約しようとしています...空の文字列は「空であるべきだとわかっています」です。それはあなたのデータは複数のソースから来ているときに特に便利です
ジョー

6
未処理-NULLは不明で、空の文字列が指定されました。
-ScottCher

@Larryパフォーマンスへの影響は何ですか?多くの列のテーブルと多くの行のテーブルでパフォーマンスはどのように異なりますか?
シミー

データセットに値が指定されていない場合と空の文字列に区別がある場合は適切に使用する必要がありますが、個人的にデータでその区別が必要ない場合は、純粋に空の文字列を常に使用することに同意しますコマンドラインでのMySQLクライアントからのクエリ結果が、大量のNULLの代わりに空の文字列で見やすくなることを見つける
RTF

25

私はMySQLとPostgreSQLについては知りませんが、これを少し一般的に扱いましょう。

NULLと ''の間でユーザーを選択できないOracleという1つのDBMSがあります。これは、両方を区別する必要がないことを明確に示しています。いくつかの迷惑な結果があります:

次のように、varchar2を空の文字列に設定します。

Update mytable set varchar_col = '';

以下は同じ結果につながります

Update mytable set varchar_col = NULL;

ただし、値が空またはNULLの列を選択するには、使用する必要があります

select * from mytable where varchar_col is NULL;

を使用して

select * from mytable where varchar_col = '';

構文的には正しいですが、行を返すことはありません。

一方、Oracleで文字列を連結する場合。NULL varcharは空の文字列として扱われます。

select NULL || 'abc' from DUAL;

abcを生成します。これらの場合、他のDBMSはNULLを返します。

値が割り当てられていることを明示的に表現したい場合は、「」などを使用する必要があります。

そして、空ではないトリムがNULLになるかどうか心配する必要があります

select case when ltrim(' ') is null then 'null' else 'not null' end from dual

します。

''がNULLと同一ではないDBMS(SQL-Serverなど)を見る

''での作業は一般に簡単で、ほとんどの場合、両方を区別する必要はありません。私が知っている例外の1つは、列が設定を表し、それらの空のデフォルトがない場合です。''とNULLを区別できる場合、設定が空であることを表現し、デフォルトが適用されることを回避できます。



17

作業しているドメインによって異なります。NULL値が存在しない(つまり、値がない)ことを意味し、空の文字列は長さがゼロの文字列値があることを意味します。

たとえば、人のデータを保存するテーブルがあり、Gender列が含まれているとします。値を「男性」または「女性」として保存できます。ユーザーが性別のデータを提供しないことを選択することができる場合、あなたにすることを保存する必要がありますNULL(つまり、ユーザーが値を提供しなかった)といない空の文字列(値とは性別がないので「」)。


7
ユーザーが性別を提供しないことを選択した場合は、必ず「提供することを拒否」を保存する必要があります。NULLはあいまいです。「顧客に尋ねられていない」、「顧客がリストにない性別で識別している」なども意味する場合があります。
Jon of All Trades

8

覚えておく価値のあることの1つは、必須ではないフィールドがあり、存在する値が一意でなければならない場合、空の値をNULLとして格納する必要があることです。それ以外の場合、そのフィールドに空の値を持つタプルを1つだけ持つことができます。

また、リレーショナル代数とNULL値にはいくつかの違いがあります。たとえば、NULL!= NULLです。


4
NULL!= NULLであるというのは、実際にはそうではありません。;-)
ピーターアイゼントラウト

1
MS SQLはこの規則に従っていないことに注意してください。複数のNULL値はUNIQUE制約に違反します。幸いなことに、2008年からは、フィルター処理されたインデックスを使用して適切な動作を取得できます。
すべての取引のジョン


4

フレームワークを使用している場合、新しい思考、NULL/の選択に対する大きな影響がありますNOT NULL。symfony alotを使用し、許可NULLフィールドを使用すると、データを操作する際のコードとデータのチェックの一部が簡素化されます。

フレームワークを使用していない場合、または単純なsqlステートメントと処理を使用している場合は、追跡する方が簡単だと思う方を選択します。INSERT空のフィールドをに設定するのを忘れて文を実行するのが面倒にならないように、私は通常NULLを好みますNULL


質問は、NULL対空文字列(ヌル可能列、IMO)についてであり、NULL対NOT NULLではありませんか?
ガン

ストレージに関する質問の一部は、彼がNull / Not Nullについても考えているのではないかと思うようになりました。
パトリック

またはNULLとNOT NULLの関係に関する他の@everyoneは、これを参照できます:dba.stackexchange.com/q/63/107
Gan

2

オラクルと仕事をしなければならなかったので差別化することはできません)、私は次の結論に達しました。

  • 論理的なPOVからは問題ではありません。NULLと長さゼロの文字列を区別することでDBMSに値が追加されるような説得力のある例を考えることはできません。

  • 以下から:NULLzero-lenを許可しない列''(Oracleのようなソリューション)またはNOT NULLzero-lenを許可する列があります。

  • そして、私の経験から、データを処理するとき、空の文字列として文字列の不在を処理したい''ので、はるかに理にかなっています:連結、比較など。

注:私のOracleエクスペリエンスに戻るには、検索リクエストのクエリを生成するとします。使用する''場合は、生成するだけでWHERE columnX = <searchvalue>、等価検索で機能します。あなたが使うならあなたはしNULLなければなりませんWHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL)。ああ!:-)


2

また、設計の観点からも異なります。

例えば

CREATE TABLE t (
    id INTEGER  NOT NULL,
    name CHARACTER(40),
    CONSTRAINT t_PK PRIMARY KEY (id)
);

CREATE UNIQUE INDEX t_AK1 ON t (name);

次のようになります:

 \d t
          Table "public.t"
 Column |     Type      | Modifiers
--------+---------------+-----------
 id     | integer       | not null
 name   | character(40) |
Indexes:
    "t_pk" PRIMARY KEY, btree (id)
    "t_ak1" UNIQUE, btree (name)

いくつかのデータを挿入しましょう:

op=# insert into t(id, name ) values ( 1, 'Hello');
INSERT 0 1

op=# insert into t( id, name) values ( 2, '');
INSERT 0 1

op=# insert into t( id, name) values ( 3, '');

ERROR:  duplicate key value violates unique constraint "t_ak1"

次に、nullを試してみましょう。

op=# insert into t( id, name) values (4, null );

INSERT 0 1

op=# insert into t( id, name) values (5, null);

INSERT 0 1

これは許可されています。

Soooooo:nullは単純な文字列でもその逆でもありません。

乾杯


1

理論について話すと、Coddのルールでは、RDBMSはNULL値を特別な方法で処理する必要があるとされています。

実際のドメイン-タスク-プロジェクト-アプリケーション-エリアによって異なりますが、どの程度正確に使用されるかはデータベース設計者次第です。

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