50

false や空の文字列 '' とは異なる、データベース テーブル内の NULL 値のセマンティックな意味を理解しています。ただし、フィールドが null 可能である場合のパフォーマンスの問題についてよく読んでおり、NULL が実際に意味的に正しい場合は空の文字列を使用するようにアドバイスされています。

null 許容フィールドと NULL 値を使用するのに適切な状況は? トレードオフは何ですか?単純に NULL を完全に使用することを避け、空の文字列、false または 0 を使用して値がないことを示すのは賢明でしょうか?

アップデート

OK - '' と NULL のセマンティックの違い、および NULL が適切なフィールド値である (パフォーマンスに依存しない) 状況を理解しています。ただし、示唆されたパフォーマンスの問題について詳しく説明します。これは、Schwartz、Zeitsev らによる優れた「High Performance MySQL」からのものです http://www.borders.co.uk/book/high-performance-mysql-optimization-backups-replication-and-more/857673/ :

インデックス、インデックス統計、および値の比較がより複雑になるため、MySQL が null 許容カウントを参照するクエリを最適化するのは困難です。null 許容カラムは、より多くのストレージ スペースを使用し、MySQL 内部で特別な処理を必要とします。null 許容列がインデックス化されると、エントリごとに余分なバイトが必要になり、MyISAM で固定サイズのインデックス (単一の整数列のインデックスなど) が可変サイズのインデックスに変換される可能性さえあります。

詳細はこちら: Google ブックスのプレビュー

これが決定的な答えである可能性が非常に高く、私は第一線からのセカンドオピニオンと経験を探していました.

4

11 に答える 11

37

ただし、フィールドがnull可能である場合のパフォーマンスの問題についてよく読んでおり、NULLが実際に意味的に正しい場合は、空の文字列を使用するようにアドバイスされています。

私は少しの間、単語の選択について気まぐれになります:

  • それが重要なパフォーマンス要因であったとしても、それはNULLの代わりに値を使用することを意味的に正しくしません。SQLでは、NULLには意味的な役割があり、欠落している値または適用できない値を示します。特定のRDBMS実装におけるNULLのパフォーマンス特性は、これとは無関係です。パフォーマンスはブランドごと、またはバージョンごとに異なる場合がありますが、言語でのNULLの目的は一貫しています。

いずれにせよ、NULLのパフォーマンスが低いという証拠は聞いたことがありません。null許容列が非null許容列よりもパフォーマンスが悪いことを示すパフォーマンス測定値への参照に興味があります。

私が間違っていない、または場合によっては真実ではないということではありません。ただ、怠惰な仮定をすることは意味がないということです。科学は推測で構成されていません。繰り返し可能な測定で証拠を示さなければなりません。

メトリックは、パフォーマンスの違いも示すため、心配する価値があるかどうかを判断できますつまり、影響は測定可能でゼロではない可能性がありますが、テーブルの適切なインデックス作成やデータベースキャッシュのサイズ設定など、より優れたパフォーマンス要因と比較すると、それでも重要ではありません。

MySQLでは、NULLの検索はインデックスの恩恵を受けることができます。

mysql> CREATE TABLE foo (
  i INT NOT NULL,
  j INT DEFAULT NULL,
  PRIMARY KEY (i),
  UNIQUE KEY j_index (j)
);

mysql> INSERT INTO foo (i, j) VALUES 
  (1, 1), (2, 2), (3, NULL), (4, NULL), (5, 5);

mysql> EXPLAIN SELECT * FROM foo WHERE i = 3;
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
| id | select_type | table | type  | possible_keys | key     | key_len | ref   | rows | Extra |
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+
|  1 | SIMPLE      | foo   | const | PRIMARY       | PRIMARY | 4       | const |    1 |       | 
+----+-------------+-------+-------+---------------+---------+---------+-------+------+-------+

mysql> EXPLAIN SELECT * FROM foo WHERE j IS NULL;
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key     | key_len | ref   | rows | Extra       |
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
|  1 | SIMPLE      | foo   | ref  | j_index       | j_index | 5       | const |    2 | Using where | 
+----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+

それはまだパフォーマンスの測定ではないことに注意してください。NULLの検索中にインデックスを使用できることを示しただけです。私は(確かに測定していませんが、これは単なるStackOverflowです)、NULLと空白の文字列を検索するときに、インデックスの利点がペナルティの可能性を覆い隠していると断言します。

NULLの代わりにゼロ、空白、またはその他の値を選択することは、正しい設計上の決定ではありません。これらの値を列で重要なものとして使用する必要がある場合があります。そのため、NULLは、定義上、任意のデータ型の値のドメイン外の値として存在します。したがって、整数や文字列などの値の全範囲を使用しても、「上記の値のいずれでもない」ことを意味するものがあります。 「」

于 2009-01-23T02:25:40.853 に答える
12

実際、MySQL のマニュアルには、 NULL の問題に関する素晴らしい記事があります。

それが役に立てば幸い。

また、NULLとパフォーマンスに関するこの他のSO投稿も見つけました

于 2009-01-23T00:09:41.093 に答える
5

数値または日付の場合を除き、データベースで NULL 値を使用することはできません。これを行う理由は、数値をデフォルトでゼロにするべきではない場合があるためです。これは非常に悪いことです。私は株式ブローカーの開発者であり、 NULL0の間には大きな違いがあります。COALESCE の使用は、デフォルト値をゼロに戻したい場合に便利です。

MyVal = COALESCE(TheData, 0)

フラットファイルからのデータの一括挿入を行うとき、フォーマットファイルを使用してデータのエントリを決定し、空の値を空の文字列に自動的に変換します。

日付のデフォルトは、私が信じている照合に応じて表示される値ですが、私たちのデフォルトは 1900 のようなものです。繰り返しますが、日付は非常に重要です。他のプレーン テキスト値はそれほど重要ではありません。通常、空白のままにすると問題ありません。

于 2009-01-27T13:32:17.733 に答える
3

の代わりに空の文字列を使用しないでくださいNULLNULL空の文字列が何かであり、内部に何もない場合、何も表さない。別の値 ( であっても) とNULL比較すると常に false になり、関数で合計されません。NULLNULLCOUNT

不明な情報を表す必要がある場合は、 に代わるものはありませんNULL

于 2009-01-23T00:20:47.657 に答える
3

@ForYourOwnGood が言ったように、「不明な」情報には Null を使用する必要があります。例: 顧客が登録時に入力する必要のあるフィールドが多数あり、そのうちのいくつかはオプションである場合。なんらかの理由で、その特定の顧客の ID を予約したい場合があります。オプションのフィールドを顧客が実際に選択して空にしておくかどうかわからないため、最初に保存するときにそれらを NULL、つまり「不明」に設定する必要があります。行。顧客がフォームを送信し、すべての検証に合格し、情報を保存した場合、オプション フィールドが意図的に空のままになっていることがわかります。

これは NULL を使用する良いケースです。

于 2013-06-30T20:57:55.263 に答える
3

一般に、属性が必須の場合は Not NULL として定義され、省略可能な場合は nullable として定義されます。

于 2009-01-23T00:08:42.250 に答える
2

NULL 列の意味は、多かれ少なかれ「このコンテキストには当てはまらない」ということです。通常、次の 2 つの場合に NULL 列を使用します。

  • フィールドが適用されない場合 (ブール列 is_thirsty があり、2 つのデータセットを追加するとします。1 つは人間で、1 つは石です。人間の場合は is_thirsty を true または false に設定しますが、石の場合は、おそらく NULL に設定します。
  • 何かにフラグを立てて、値を含むデータを保存する必要がある場合。在庫の締め日と同様に、a) 在庫がこれ以上変更できないことを指定し、b) 在庫がいつ閉じられたかを指定するために使用します。2 つの列 (closed_atおよびis_closed) を使用する代わりに、closed_at 列を作成し、在庫セットを変更できる場合はそれを NULL に設定しますが、クローズされたら日付を設定します。

基本的には、フィールドの空が単なる空のフィールドとは異なる一意のセマンティックを持つ場合に NULL を使用するという事実に要約されます。ミドルネームのイニシャルがないのは、まさにそれです。締め切り日がないということは、在庫セットがまだ変更可能であることを意味します。

NULL 値には厄介な副作用がある可能性があり、データをテーブルに追加するのが難しくなり、多くの場合、NULL 値と空の文字列がごちゃまぜになってしまう可能性があります。

また、NULL は何にも等しくないため、十分に注意しないと、あちこちでクエリが台無しになります。

個人的には、上記の 2 つのケースのいずれかに該当する場合にのみ NULL 列を使用します。空であることが値の不在以外に意味がない場合、空のフィールドを示すためにそれを使用することはありません。

于 2009-01-23T00:17:06.977 に答える
1

もちろん、主な利点は、あなたが言及した NULL のセマンティックな意味です。

それに加えて、いつものようにストレージエンジンに依存するかもしれませんが、ドキュメントを確認してください.しかし、少なくともいくつかのデータベースでは、NULLは通常の値よりもはるかに少ないスペースを占有します. たとえば、20 文字と宣言された「varchar」列があり、めったに入力されない場合は、空の文字列ではなく NULL にすることで、多くのディスク領域を節約できます。

NULL を使用した場合のパフォーマンスの問題については聞いたことがありません。NULL を間違ってカウントしたためにカウントをいじくりまわしている人たちの話を聞いたことがありますが、決してパフォーマンスは向上しませんでした。もしそれが本当なら、私はそれについて聞いてみたいです!

于 2009-01-23T00:15:48.087 に答える
0

Oracle などの一部のデータベースでは、MySQL に関する考えが正しいかもしれません。

  • null はインデックス化されないため、null 値を探すことがボトルネックになる可能性があります。
  • 行の末尾の NULL はスペースを節約します。
于 2009-01-23T00:22:06.467 に答える