Null または空の文字列 -- テーブルの列にデータがないことを表すには、どちらが優れているでしょうか? (私は特にMySQLを使用していますが、これはシステムに依存しないと考えています。)一方を他方よりも使用することの主な利点/欠点はありますか、それとも単にプログラマーの好みですか?
16 に答える
無条件に NULL を使用すると言うすべての人に強く反対します。列を NULL にすることを許可すると、列を NOT NULL として設定した場合には存在しない追加の状態が導入されます。追加の状態が必要ない場合は、これを行わないでください。つまり、空の文字列の意味と null の意味の違いがわからない場合は、列を NOT NULL として設定し、空の文字列を使用して空を表します。同じものを 2 つの異なる方法で表現することは、悪い考えです。
NULL を使用するように言った人のほとんどは、NULL が空の文字列とは異なることを意味する例も示しました。そして、それらの例では、それらは正しいです。
ただし、ほとんどの場合、NULL は不必要な余分な状態であり、プログラマーはより多くのケースを処理する必要があります。他の人が述べたように、Oracle は NULL と空の文字列を同じものとして扱うため、この余分な状態が存在することを許可していません (Oracle で null を許可しない列に空の文字列を格納することは不可能です)。
ヌル。空の文字列は「データなし」ではなく、たまたま空のデータです。
ない。リレーション内のタプルの不在として、データの不在を表します。
パフォーマンス上の理由から、一部の RDBMS では結合を避けたい場合がありますが、欠落している可能性のある情報が別の関係になるようにモデルを設計してみてください。
Nullの方が良い "" 実際にはデータを表し、コードに同じものを登録しません
リレーショナル データベース モデルのコンテキストでは、null は「値がない」または「不明な値」を示します。それはまさにあなたが説明した目的のために存在します。
更新: 申し訳ありませんが、追加するのを忘れていましたが、ほとんどの (すべて?) RDMBS は null に対して同じ定義を使用していますが、null の処理方法には微妙な違いがあります。たとえば、MySQL と Oracle では、UNIQUE 列 (または列のセット) で複数の null を使用できます。これは、null は値ではなく、一意と見なすことができない (null != null) ためです。しかし、前回 MS SQL Server を使用したときは、1 つの null しか許可されませんでした。そのため、RDBMS の動作と、問題の列が制約されるかインデックスが作成されるかを考慮する必要がある場合があります。
以下に、MySQL サイトからのリンクをいくつか示します。
http://dev.mysql.com/doc/refman/5.0/en/problems-with-null.html
http://dev.mysql.com/doc/refman/5.0/en/working-with-null.html
NULL
値は 2 ビットで、空の文字列は 1 ビットしかないことを一度読みました。99% の場合、これは何の違いもありませんが、非常に大きなテーブルでは、 または であるかどうNULL
かが問題ではない場合、これが true である場合''
に使用する方がよい場合があります。''
常に NULL を使用してください。「この人の電話番号がわからない」(NULL) と「この人は空白のまま」(空白) の違いを考えてみましょう。
仕事に適したツールを使用してください。NULL は、(まだ) 値が提供されていないことを示すか、適用できる値がないことを示します。
しかし、空の文字列も情報です。値が適用可能であり、与えられたが、たまたま空の文字列であることを示すことができます。
列に NULL と '' の両方を含めることを許可すると、これらのケースを区別する機会が得られます。いずれにせよ、一方を他方を意味するために使用するのはよくありません。
文字列の連結では、NULL と組み合わせると NULL になることに注意してください。例: CONCAT(NULL, 'foo') は NULL を返します。SQL 式で NULL をデフォルト値に変換する場合は、COALESCE() 関数の使用方法を学びます。
ほとんどの場合、null の方が優れています。ほとんど違いがない状況もあるかもしれませんが、ごくわずかです。(少なくともMySQLでは)field = ''
と同じではないクエリをいつ実行するかを覚えておいてください。field is null
NULL は、それが生まれた場所から暗黒時代に追いやられるべき価値のないものです。デフォルト値で簡単に処理できる特別な NULL ケースを処理するには、かなりの量のプログラミングが必要であることがわかりました。
列のデフォルトを空の文字列に設定します。列が null を許可しないように強制します。これは、デフォルト値を割り当てると、ほとんど発生しません。列の値が null の場合を無視して、コードを適切に記述してください。
私が常に NULL で抱えていた大きな問題の 1 つは、"SELECT * from tbl WHERE column = NULL" が常に空の結果セットを返すことです。NULL は、NULL を含め、何にも等しいことはできません。特別なキーワード「列がnullです」は、何かがnullであることを確認する唯一の方法です。null から離れると、比較は成功します: "column = ''" 7 行が返されます。
私は 2 つの主要な DB 実装をゼロから行いましたが、最終的に NULL を使用したことを後悔しました。次回は、NULL はありません。
NULL 可能列とメイン テーブルへの外部キーだけのために別のテーブルを作成します。レコードにその列のデータがない場合、2 番目のテーブルにはレコードがありません。これは最もクリーンなソリューションであり、null の処理や空の文字列に特別な意味を与えることについて心配する必要はありません。
私が知る限り、Oracle は違いを区別していません。
select 1 from (select '' as col from dual) where col is null;
列にデータがない理由を考えてみましょう。テーブルのデザインが雑ということですか?null は好きではありませんが、null が適切な (または十分に適切な) 場合があり、通常はシステムが停止することはありません。候補キー (主キーまたは代替キー) に null を許可しないでください。
列の「データなし」値は、デフォルト値で表す必要があります。NULL は不明な値を意味することに注意してください。つまり、列に値があるかどうかはわかりませんが、現時点ではわかりません。
たとえば、ローン申請システムでは、運転免許証番号フィールドの NULL 値は、申請者またはローン処理業者が運転免許証番号を入力しなかったことを意味します。NULL 値は、申請者がライセンスを持っていないことを自動的に意味するわけではありません。彼はライセンスを持っているかもしれないし、持っていないかもしれません。あなたはそれを知らないだけです。それが NULL である理由です。
あいまいさは、文字列列にあります。値がない場合、数値列には明らかにゼロが含まれます。値のない文字列をどのように表現できますか? 上記の例では、運転免許証を持っていない申請者に対して、「none」などの任意のデフォルト値を割り当てることができます。できれば空の文字列を使用することをお勧めします。一貫性を保つために、他のテーブルではデフォルトの空の値を使用してください。
原則としてNULLを使用しないという問題については、実際にはNULLが必須である場合があります。統計を幅広く扱う人として、データ プロバイダーが不完全なデータを含むデータ セットを提供することはよくあることです。たとえば、国ごとの GDP のデータ セットでは、前の年と後の年の GDP の数値が欠落している場合があります。その理由の 1 つは、その国の政府からの公式データがないことです。GDP がゼロであると結論付けて (DUH!)、抽出されたデータまたはグラフにゼロの値を表示するのは正しくありません。正しい値は NULL です。これは、まだデータがないことを意味します。エンド ユーザーは、抽出されたデータとグラフに含まれていないデータポイントをゼロではないと正しく解釈します。さらに、特に平均を行うときに、計算でエラーが発生することはありません。
理論的には理にかなっているいくつかの「ルール」は、実際にはあなたのケースでは不十分または不正確な解決策になります。
重要な例外が 1 つあります。Bill Karwin は、「CONCAT(NULL, 'foo') は NULL を生成する」と述べていますが、これはほとんどの RDBMS に当てはまりますが、Oracle には当てはまりません。
上記の James Curran が示唆したように、Oracle は、NULL と空の文字列をまったく同じように扱うことによって標準 SQL から逸脱するために、このかなり重要な分岐点を選択しました。ただし、それらを同じように扱うだけでなく、連結時に NULL 以外の値を返すことで、実際には NULL 値の意味を損なう可能性があります。
具体的には、Oracle では CONCAT(NULL, 'foo') は 'foo' を生成します。オラクルに感謝します。null を失ってしまいました。あなたには関係ないかもしれませんが、データが他の RDBMS に渡されてさらに処理されるときに違いが生じることは確かです。
NULL 値は参照整合性に役立つことがわかりました。MySQL の場合、フィールドが NOT NULL に設定されている場合、挿入にはデータを設定する必要があります。それ以外の場合、NULL が可能な値であり、外部キー制約は適用されません。
- id: 主キー
- product_id: 外部キーが NULL ではありません
- ref_id: (NULL可能)
id および product_id 領域は常に必要です。ref_id は NULL に設定できます。ただし、他の値を使用する場合は、FOREIGN KEY 制約を満たす必要があります。