私は主にMySQLとPostgreSQLに興味がありますが、一般的には次のように答えることができます。
空の文字列を保存するための物理的なストレージの意味は...
レコードが、名前と住所の情報を収集するフォームからのものであるとしましょう。ユーザーがアパートに住んでいない場合、住所の2行目は通常空白になります。この場合の空の文字列は完全に有効です。私は、値が不明または指定されていないことを意味するためにNULLを使用する傾向があります。
物理ストレージの違いが実際に心配する価値があるとは思いません。データベース管理者として、私たちはより大きな魚を揚げる必要があります!
MySQLとPostgreSQLについては知りませんが、少し一般的に扱います。
DBMSには、NULLと ''の間でユーザーを選択できないOracleがあります。これは、両方を区別する必要がないことを明確に示しています。いくつかの迷惑な結果があります:
次のように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を区別できる場合は、設定が空であることを表し、デフォルトが適用されることを回避できます。
作業しているドメインによって異なります。 NULL
は値がないことを意味します(つまり値がない)が、空の文字列は長さがゼロの文字列値。
たとえば、個人のデータを格納するテーブルがあり、Gender
列が含まれているとします。値は「男性」または「女性」として保存できます。ユーザーが性別データを提供しないことを選択できる場合は、それをNULL
(つまり、ユーザーが値を提供しなかった)およびnot空の文字列(ないため、値を持つ性別 '')。
覚えておかなければならないことの1つは、必須ではないフィールドがある場合に、存在する値は一意でなければならないため、空の値をNULLとして格納する必要があることです。それ以外の場合は、そのフィールドに空の値を持つタプルを1つだけ持つことができます。
また、リレーショナル代数とNULL値にはいくつかの違いがあります。たとえば、NULL!= NULLです。
また、日付のNULLの批評と3VLの問題を SQLおよびリレーショナル理論 (および日付の批評のルビンソンの批評 Nulls、3値論理、およびSQLのあいまいさ)に組み込むこともできます。批評日の批評 )。
両方とも関連するSOスレッド、 DBモデルからNULL可能な列を削除するためのオプション で詳細に参照および説明されています)。
新しい考え、NULL
/NOT NULL
の選択に大きな影響を与えるのは、フレームワークを使用している場合です。私はsymfony alotを使用し、許可NULL
フィールドを使用することで、データを操作するときのコードとデータチェックの一部を簡素化します。
フレームワークを使用していない場合、または単純なSQLステートメントと処理を使用している場合は、追跡するのが簡単であると思われる方を選択します。空のフィールドをINSERT
に設定するのを忘れることでNULL
ステートメントを実行しても面倒にならないように、私は一般的にNULLを好みます。
Oracleで作業しなければならなかった( これは区別できない )私は次の結論に達しました。
論理的な視点からそれは重要ではありません。 NULLと長さゼロの文字列を区別することで、DBMSに値が追加される説得力のある例は、実際には考えられません。
以下から:ゼロレンズを許可しないNULL
able列_''
_(Oracle風のソリューション)またはゼロレンズを許可する_NOT NULL
_列のいずれかがあります。
そして、私の経験から、_''
_は、データの処理時にalotをより意味のあるものにします。通常、文字列の欠如を処理したいからです空の文字列として:連結、比較など.
注:私のOracleエクスペリエンスに戻るには、検索リクエストのクエリを生成するとします。 _''
_を使用する場合、_WHERE columnX = <searchvalue>
_を生成するだけで、等価検索で機能します。 NULL
を使用する場合は、WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL)
を実行する必要があります。ば! :-)
また、デザインの観点からも異なります。
例えば.
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は簡単な文字列でもその逆でもありません。
乾杯
理論について話す場合、Coddのルールでは、RDBMSはNULL
値を特別な方法で処理する必要があるとしています。
正確にどのように使用されるかは、実際のドメイン-タスク-プロジェクト-アプリケーション-エリアに応じて、データベースアーキテクト次第です。