MySQL Null は 5 つの問題を引き起こす可能性があります (すべて致命的)

MySQL Null は 5 つの問題を引き起こす可能性があります (すべて致命的)

正式に開始する前に、次の図に示すように、MySQL サーバーの構成とバージョン番号情報を確認しましょう。

「軍隊が移動する前に、食料と飼料を準備する必要があります。」関連する構成を読んだ後、テスト テーブルとテスト データを作成しましょう。

-- person テーブルが存在する場合は、まずそれを削除します。DROP TABLE IF EXISTS person; 
 
-- ユーザー名フィールドが空になる person テーブルを作成し、通常のインデックスを設定します CREATE TABLE person (
 id INT 主キー auto_increment,
 名前 VARCHAR(20)、
 モバイルVARCHAR(13)、
 インデックス(名前)
)ENGINE='innodb';
 
-- person テーブルにテストデータを追加します insert into person(name,mobile) values('Java','13333333330'),
 ('MySQL','13333333331'),
 ('Redis','13333333332'),
 ('カフカ','13333333333'),
 (「春」、「13333333334」)、
 ('MyBatis','13333333335'),
 ('RabbitMQ','13333333336'),
 ('Golang','13333333337'),
 (NULL、'13333333338')、
 (NULL、'13333333339');
 
人から*を選択します。

構築されたテスト データを次の図に示します。

データが揃ったので、列にNULL値がある場合にどのような問題が発生するかを見てみましょう。

1. カウントデータが失われる

列にNULL値がある場合、 countを使用して列をクエリすると、次の SQL に示すように、データが「失われる」ことになります。

personからcount(*),count(name)を選択します。

クエリの実行結果は次のとおりです。

上記の結果から、 count(name)クエリを使用すると、 NULL値を持つ2つのデータが失われることがわかります。

解決

列にNULL値がある場合、データ統計にはcount(*)が使用されます。

追加知識: count(constant) を使わない

Alibaba の「Java 開発マニュアル」では、count( ) の代わりに count(列名) または count(定数) を使用しないように規定されています。count( ) は、SQL92 で定義された行をカウントするための標準構文です。これはデータベースとは関係がなく、NULL または非 NULL とも関係ありません。

注意: count(*) は NULL 値を持つ行をカウントしますが、count(列名) はこの列内の NULL 値を持つ行をカウントしません。

2. 明確なデータ損失

count(distinct col1, col2)クエリを使用する場合、列の 1 つNULL場合、他の列の値が異なっていても、次の SQL に示すように、クエリ結果のデータは失われます。

person から count(distinct name,mobile) を選択します。

クエリの実行結果は次のとおりです。

データベースの元データは次のとおりです。

上記の結果から、携帯電話番号列の 10 個のデータはすべて異なるが、クエリ結果は 8 であることがわかります。

3.データ損失を選択

列にNULL値がある場合、不等クエリ (<>/!=) を実行すると、 NULL値の結果が失われます。たとえば、次のデータ:

名前が「Java」に等しいデータを除くすべてのデータをクエリする必要があります。 期待される結果は、ID が 2 から 10 までのデータです。 ただし、次のクエリを実行すると:

select * from person where name<>'Java' order by id;
-- または select * from person where name!='Java' order by id;

クエリ結果は次のとおりです。

2 つのNULLデータが突然消えたことがわかります。この結果は、通常の期待を満たしていません。

解決

上記の問題を解決するには、クエリ結果にNULL値を含む結果を追加するだけです。次のように SQL を実行します。

select * from person where name<>'Java' or isnull(name) order by id;

最終的な実行結果は次のとおりです。

4. Nullポインタ例外が発生する

列にNULL値がある場合、 sum(column)の戻り結果は 0 ではなくNULLになることがありますsumクエリの結果がNULLの場合、プログラム実行中に Null ポインタ例外 (NPE) が発生する可能性があります。 この問題を説明しましょう。

まず、テーブルとテストデータを作成しましょう。

-- goods テーブルが存在する場合は、まずそれを削除します。DROP TABLE IF EXISTS goods; 
 
-- 商品テーブルを作成する CREATE TABLE goods (
 id INT 主キー auto_increment,
 数値整数
)ENGINE='innodb';
 
-- テストデータを商品テーブルに追加します。 insert into goods(num) values(3),(6),(6),(NULL);
 
商品から*を選択します。

表の元のデータは次のとおりです。

次に、 sumクエリを使用して次の SQL を実行します。

id>4の商品からsum(num)を選択します。

クエリの実行結果は次のとおりです。

クエリ結果が 0 ではなくNULLの場合、Null ポインタ例外が発生する可能性があります。

Null ポインタ例外の解決

NullPointerException を回避するには、次の方法を使用します。

id>4の商品からifnull(sum(num), 0)を選択します。

クエリの実行結果は次のとおりです。

5. クエリの難易度が上昇

列にNULL値が含まれている場合、 NULL値または非NULL値のクエリが難しくなります。

いわゆるクエリの難易度が上がるというのは、 NULL値クエリを実行するときに、クエリにIS NULLIS NOT NULLIFNULL(cloumn)式などのNULL値一致クエリ方式を使用する必要があり、従来の=、!=、<>...などの式が使用できないことを意味します。これにより、特に初心者プログラマーにとって、クエリの難易度が上がります。次に、これらの問題について説明します。

personテーブルを例に挙げてみましょう。元のデータは次のとおりです。

誤った使い方1:

name<>null の場合、 person から * を選択します。

次の図に示すように、実行結果は空で、データが見つかりません。

誤った使い方2:

name!=null の場合、 person から * を選択します。

次の図に示すように、実行結果も空であり、データは照会されません。

正しい使い方1:

名前が null でない person から * を選択します。

実行結果は次のとおりです。

正しい使い方2:

!isnull(name) となる person から * を選択します。

実行結果は次のとおりです。

推奨される使用方法

Alibabaの「Java開発マニュアル」では、 NULL値の判定にISNULL(cloumn)を使用することを推奨しています。その理由は、SQL文ではnullの前に改行があると読みにくくなるのに対し、 ISNULL(column)は全体が簡潔でわかりやすいからです。パフォーマンスデータから分析すると、 ISNULL(column)もより効率的です。

拡張知識: NULLはインデックスに影響しません

注意深い友人は、次の図に示すように、私がpersonテーブルのnameフィールドを作成したときに、そのフィールドに対して通常のインデックスを作成したことに気付いたかもしれません。

次に、 explainを使用してクエリ プランを分析し、 nameNULL値がインデックスの選択に影響するかどうかを確認します。

explainの実行結果を次の図に示します。

上記の結果から、 nameNULL値があっても、MySQL のクエリに対するインデックスの使用には影響しないことがわかります。

要約する

この記事では、列がNULLの場合に発生する可能性のある 5 つの問題 (クエリ結果の損失、NULL ポインター例外、クエリの難易度の上昇) について説明しました。したがって、テーブルを作成するときに、 is not null制約を設定することをお勧めします。列に値がない場合、デフォルト値として null 値 ('') または 0 を設定できます。

これで、MySQL が Null になることで発生する 5 つの問題 (すべて致命的) に関するこの記事は終了です。MySQL が Null になることで発生する問題の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL で not in を使用して null 値を含める問題を解決する
  • 設定操作からMySQLへのNULLが見つからない問題を解決する
  • MySQL IFNULL判定問題の解決方法
  • MySQL の NOT IN 充填ピットの NULL 列の問題の解決方法
  • mysql は、含まれていない、左結合、IS NULL、NOT EXISTS の効率の問題のレコードです

<<:  ブリージングカルーセルを実装するネイティブJS

>>:  HTML テーブルタグチュートリアル (23): 行の境界線の色属性 BORDERCOLORDARK

推薦する

MySQL アップグレードのベストプラクティス

MySQL 5.7 には、オンライン DDL、マルチソース レプリケーション、拡張された半同期、テー...

MySQL の重要なパフォーマンス インデックスの計算と最適化方法の概要

1 QPS 計算 (1 秒あたりのクエリ数) MyISAMエンジンベースのDBの場合 MySQL&g...

MySQLはデータ復旧を実装するためにbinlogログを使用する

MySQL binlog は MySQL ログの中で非常に重要なログであり、データベースのすべての ...

Alibaba Cloud OSS によってアップロードされた Nginx プロキシ転送実装コード

序文ミニプログラムのアップロードには https が必要なので、サーバーの https は lets...

Windows 2008 Server サブドメインを親ドメインに追加すると、ドメインが既に存在するというエラー メッセージが表示されます。

Windows 2008 Serverのサブドメインを親ドメインに参加させると、「ドメインは既に存...

Linux で同じ内容のファイルを識別する方法の詳細な説明

序文ファイルのコピーによってハードドライブのスペースが大量に浪費され、ファイルを更新するときに混乱が...

MySQL スロークエリ関連パラメータの原理の分析

MySQL スロー クエリ (正式名称はスロー クエリ ログ) は、MySQL によって提供されるロ...

MySQL マスタースレーブスイッチチャネルの問題の解決策

VIP を設定した後、アクティブ/スタンバイの切り替え中に表示されるエラー メッセージは次のとおりで...

GolangでMySQLデータベースを操作するための実装コード

序文Golang は、SQL データベースにアクセスするための database/sql パッケージ...

Vue+webrtc (Tencent Cloud) ライブブロードキャスト機能の実装実践

目次1. 生放送効果2. ライブストリーミングを開始する手順2.1 Tencent Web(高速ライ...

React ページ ターナーの実装 (フロント エンドとバックエンドを含む)

目次フロントエンド上記のアイデアに従って、ページめくり機能を設計して記述します。バックエンド(Jav...

UbuntuへのDocker CEのインストール

この記事は、Ubuntu 17.10 での Docker CE のインストールを記録するために使用さ...

プロジェクトの再構築からプロジェクトにおける CSS3 カスタム変数の使用について話す

CSS3変数について変数を宣言するときは、変数名の前に 2 つのハイフン ( -- ) を追加します...

Vue で ToDo アプリケーションを実装する例

背景まず最初に、私はフロントエンド開発の専門家ではないことを述べておきたいと思います。私の以前のコン...

MySQL が innobackupex を使用して接続サーバーをバックアップできない場合の解決策

innobackupex を使用してバックアップする際に MySQL がサーバーに接続できない場合は...