MySQLフィールド定義でnullを使用しない理由の分析

MySQLフィールド定義でnullを使用しない理由の分析

NULL が頻繁に使用されるのはなぜですか?

(1)Javaのnull

Java の NullPointerException など、Null は頭痛の種です。予期しない null ポインターを回避するには、さまざまな if 判断を慎重に行う必要があり、面倒で肥大化します。

このため、多くの処理を備えたオープンソースパッケージが数多く存在する。

共通 lang3 の StringUtils.isBlank(); CollectionUtils.isEmpty();

グアバのオプション

Java 8でもこの問題を回避するためにOptionalが導入されました(Guavaに似ていますが、使用方法が少し異なります)

(2)なぜMySQLのnullは広く悪用されているのでしょうか?

(a) データ テーブルを作成するときは、非標準の null を作成するのがデフォルトです。一部の MySQL クライアントでは、自動的に生成されるテーブル ステートメントで not null を指定しない場合があります。

(b) null ではない場合、より多くのスペースが必要であると考える人もいるかもしれません。

(c)開発中にデータを挿入する際にnull値を判断する必要がないため、手間が省け、SQLの記述が容易になる。

2. 公式文書

NULL 列には、その値が NULL であるかどうかを記録するために行に追加のスペースが必要です。MyISAM テーブルの場合、各 NULL 列は 1 ビット余分に占有し、最も近いバイトに切り上げられます。

MySQL では、null 許容列を参照するクエリを最適化するのが難しく、インデックス、インデックス統計、および値がより複雑になります。 NULL 可能列にはより多くのストレージ スペースが必要であり、MySQL 内で特別な処理が必要になります。 NULL 可能列にインデックスを付けると、各レコードに追加のバイトが必要になり、MYISAM の固定サイズ インデックスが可変サイズ インデックスになることもあります。 —— 「ハイパフォーマンス MySQL 第 2 版」より

not null を指定しないことによるパフォーマンス上の利点はないようです。

MySQLがnullを使用しない3つの理由

(1)NULL値が使用されるすべての状況を意味のある値で表現することができ、コードの可読性と保守性の向上に役立ち、制約の観点からビジネスデータの標準化を強化できます。

(2)NULL値から非NULL値への更新はインプレースでは行えないため、インデックス分割が発生しやすくなり、パフォーマンスに影響します。 (null -> not null のパフォーマンス向上は非常に小さいため、問題が発生することが確実でない限り、優先的な最適化対策として考慮しないでください)

(3)タイムスタンプ型では、特にexplicit_defaults_for_timestampパラメータが有効になっていない場合にNULL値が問題になりやすい。

(4) NOT INや!=などの否定条件クエリは、NULL値がある場合には常に空の結果を返すため、クエリでエラーが発生しやすくなります。

null によって引き起こされる 4 つの悪いケース

データの初期化:

テーブルtable1を作成する(
    `id` INT (11) NOT NULL,
    `name` varchar(20) NOT NULL
)


テーブルtable2を作成する(
    `id` INT (11) NOT NULL,
    `名前` varchar(20)
)

テーブル1に値(4、「zhaoyun」)、(2、「zhangfei」)、(3、「liubei」)を挿入します。
テーブル2に値(1、「zhaoyun」)、(2、null)を挿入します

(1) NOT INサブクエリはNULL値がある場合には常に空の結果を返すため、クエリでエラーが発生しやすくなります。

名前が含まれていないテーブル1から名前を選択 (IDが1であるテーブル2から名前を選択)

+-------------+
| 名前 |
|--------------|
+-------------+

(2)列の値は空であってもよく、インデックスにはNULL値は格納されず、これらのレコードは結果セットに含まれません。

テーブル2から*を選択します。name != 'zhaoyun'

+------+--------------+
| ID | 名前 |
|------+--------------|
| | |
+------+--------------+

テーブル2から*を選択します。name != 'zhaoyun1'

+------+--------------+
| ID | 名前 |
|------+--------------|
| 1 | 趙雲 |
+------+--------------+

(3) concatを使用する場合は、まず各フィールドがnullでないかどうかを確認する必要があります。そうでない場合、いずれかのフィールドが空であれば、連結結果はnullになります。

デュアルからconcat("1", null)を選択します。

+--------------------+
| 連結("1", null)|
|--------------------|
| NULL |
+--------------------+

(4)カウントを計算する際、NULL列は統計に含まれません。

table2からcount(name)を選択します。

+--------------------+
| count(ユーザー名) |
|--------------------|
| 1 |
+--------------------+

5つのインデックスの長さの比較

テーブルtable1を変更し、インデックスidx_name(name)を追加します。
テーブルtable2を変更し、インデックスidx_name(name)を追加します。
select * from table1 where name='zhaoyun'; を説明します。
select * from table2 where name='zhaoyun'; を説明します。

テーブル1のkey_len = 82

テーブル2のkey_len = 83

key_lenの計算ルールは、データ型、文字エンコーディング、NULLかどうかの3つの要素に関連しています。

key_len 82 = 20 * 4 (utf8mb4 - 4 バイト、utf8 - 3 バイト) + 2 (varchar 可変長文字を格納する長さは 2 バイトで、固定長フィールドには追加のバイトは必要ありません)

key_len 83 = 20 * 4 (utf8mb4 - 4 バイト、utf8 - 3 バイト) + 2 (varchar 可変長文字は 2 バイトで格納され、固定長フィールドには追加のバイトは不要) + 1 (null フラグ)

したがって、インデックス フィールドを NULL に設定しないことをお勧めします。NULL にすると、インデックス、インデックス統計、および値が複雑になり、余分な 1 バイトのストレージ領域が必要になるためです。

これで、MySQL フィールド定義で null を使用しない方法についての記事は終了です。MySQL フィールド定義での null の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL フィールドで NOT NULL を使用する必要があるのはなぜですか?
  • MySQL の null 可能フィールドは NULL に設定する必要がありますか、それとも NOT NULL に設定する必要がありますか?
  • mysqlは2つ以上のフィールドがNULLであるレコードを見つける問題を解決します
  • MySQL クエリの空のフィールドまたは空でないフィールド (null または null ではない)

<<:  iframeノードの初期化の問題に関する議論

>>:  Linux で FastDFS ファイル サーバーを構築するための実装手順

推薦する

Firefox で英語の文字が折り返されない問題の解決方法

テキストのレイアウトには、言語に応じていくつかの書式設定要件があります。たとえば、簡体字中国語では、...

Windows10 HomeバージョンにDockerをインストールするときに発生する問題の概要

Docker ダウンロード アドレス: http://get.daocloud.io/#instal...

JavaScript の BigIn 関数の共通プロパティをまとめます

目次1. 概要2. 属性1. 数学演算子2. 比較演算子3. ブール演算結論1. 概要BigInt ...

ウェブページの読み込み速度を上げる25の方法とヒント

はじめに<br />誰もが高速インターネット接続にアクセスできるわけではありません。たと...

Ubuntu16.04にCUDA9.0をインストールするための詳細なチュートリアル

序文:この記事は、CUDA 9.0 をインストールした経験に基づいています。CUDA 9.0 は現在...

星のきらめき効果を実現するネイティブ js

この記事の例では、星のきらめき効果を実現するためのjsの具体的なコードを共有しています。具体的な内容...

複数の Tomcat を展開して起動し、プロジェクトを移行する方法を 1 つの記事で学習します。

目次tomcatをデプロイする1.ダウンロードして解凍する2. 設定ファイルを変更する移植プロジェク...

グローバルトーストコンポーネントをカプセル化するVueの完全な例

目次序文1. vue-cliを使う1. Toastコンポーネントを定義する2. main.jsで設定...

JavaScript を使用したコマンドライン アプリケーションの構築

目次1. ノードをインストールする2. Commander.jsをインストールする3. JavaSc...

フロントエンドセキュリティの詳細な説明: JavaScript の http ハイジャック対策と XSS

目次HTTP ハイジャック、DNS ハイジャック、XSS HTTPハイジャックDNSハイジャックXS...

入力ボックスのオートコンプリート機能をオフにする

これで、autocomplete と呼ばれる input の属性を使用できるようになりました。オート...

Dockerコンテナのエクスポートとインポートの例

目次DockerコンテナのエクスポートDockerコンテナのインポ​​ートこの記事では主に、コンテナ...

Nginx try_files ディレクティブの使用例

Nginx の設定構文は柔軟で、高度に制御可能です。バージョン 0.7 以降では、try_files...

ウェブページ制作でウェブフォントファイルにベクターアイコンを追加する方法

ご存知のとおり、コンピューターには 2 種類の画像があり、1 つはビットマップ、もう 1 つはベクタ...

MySQL データ定義言語 DDL の基本ステートメント

MySQL DDL ステートメントDDL、DMLとは何ですか。 DDL はデータ定義言語であり、CR...