SQLでレコードの有無を確認 ~3つの方法とそのデメリット~

わざわざ記事にすることか?

といわれてしまいそうですが、それでもかまいません。

 

書かせていただきます。

 

というのも、Google先生に聞くといつも複数方法が帰ってきてどれがいいのか迷うからです。

 

例とあわせて僕の悩みを説明させていただきます。

 

レコードが存在するかどうかのSQL文

いつもパッと思いつくのは以下の3つですね。

具体例とあわせて、デメリットを挙げていきます。

 

レコードの合計値が0かどうかで判定

SELECT COUNT(*) FROM テーブル名 WHERE カラム名 = '条件'

 

これが一番検索ででてきますね。

 

同時に、

 

レコードが多いと処理に時間がかかるのでやめたほうがいい

 

という説明も出てきます。

 

レコードがあるかないかを知りたいだけなのに、わざわざマッチするレコード件数をカウントするって必要もないですからね。

 

該当のレコードが見つかるかどうかで判定

SELECT * FROM テーブル名 WHERE カラム名 = '条件'

 

僕はこれを使ってます。

ただ、「レコードが存在しない場合になにがしかの処理する」といった場合に、すべてのレコードをチェックすることになります。

 

なので、読み書きが多発するサービスではデータベースへの負荷が高くなってしまいます。

 

条件にマッチするレコードが存在するかどうか

SELECT EXISTS(SELECT * FROM テーブル名 WHERE カラム名 = '条件')

 

一番イメージ近いですが、これなら上記のSQL文でも同じです。

ただ、「条件にマッチするレコードが存在しなかったら、挿入する」という処理であれば、

 

INSERT INTO hoge (X, Y) SELECT 'a', 'b' FROM テーブル名 WHERE NOT SELECT EXISTS(SELECT * FROM テーブル名 WHERE カラム名 = '条件')

 

てな具合で、1行で書くことができます。

もっとシンプルにかけたらベストなのですが、、、、

 

僕がやっていること

とまぁメジャーそうなものを挙げましたが、他の方法ももあると思います。

 

僕の勝手な要望ですが、データベースで該当の条件でレコードがあるかどうかのチェックってかなり頻度高いので、それを一発でチェックできるSQL文くらいあってもいいんではないかと思います。

 

ちなみに僕は、SELECT文を実行する際には、

  • エラーがないか
  • レコードがあるかどうか

 

をチェックする関数を作ってそれをかますようにしています。

ちなみに僕のチェックロジックは以下のとおりです。

(なお、プログラム言語はPHPです)

 

たとえば、とあるテーブルからある条件でデータを抽出し参照したい場合は、

  • SQL実行結果を変数に格納する
  • mysql_errno関数をつかって、エラーの有無を確認し、mysql_error関数でエラー内容を表示
  • mysql_num_rows関数を使って、取得した内容を変数に格納し、それがNULLだったらレコードなしと判定

 

という処理を入れています。

 

具体的なソースとしては以下になります。

 

$result = mysql_query("SELECT * FROM テーブル名 WHERE カラム名 = '条件'");

// 【エラーが無いか確認】
if (mysql_errno()) {
    exit('エラー : '. mysql_error());
}

// 【レコードがあるか確認】
$count = mysql_num_rows($result);
if (!$count) {
    exit('条件に一致するレコードがありません。');
}

 

この処理に満足しているわけではないので、もっといい方法があったら教えてください!

 

終わりに

初期構築時は「動けば何でもいいや」として気にしてない方も多いのではないでしょうか。

(勝手なイメージですが、スタートアップなんかはアジャイルでとにかく早くサービスを形にするといった手法が取られているのでよくありそうですね)

 

そういうサービスは、2,3年運用すると「ページの表示に時間がかかる」とか、「データベースにかかる負荷が高すぎる」なんてことになり、アプリ・インフラを見直してチューニングしたりします。

 

昨今、特にITのスピードは早いので、「じっくり考えて安全・確実にサービスを立ち上げるのだ」なんてやってたら競合他社にあっという間に差をつけられ、取り返すために多くの工数を割いたりすることを考えると、スピード重視であることは仕方がないと思います。

 

でも、初期構築でちょっと配慮すれば防げる問題であれば少々時間を取られてもやっておいたほうがサービスに関わる人すべてがメリットを享受できます。

 

今回テーマにしたような、些細なことの積み重ねだと思います。

 

開発者の皆さん。ちょっとでも疑問に感じたら面倒くさいと思わずに一度調べてみましょう。

 

その判断が、プロジェクトマネージャーやディレクター、クライアントを助けることになり、最終的にエンドユーザの満足度につながることになりますので、ご協力宜しくお願いします。

(誰かにお願いしているみたいになってしまった。。。。他意はないですよ。。。)

 

Author:yukio iizuka
プロフィール画像
フリーランスとしてUX視点で業務支援しています。 HCD-Net認定 人間中心設計専門家 LEGO®︎ SERIOUS PLAY®︎ メソッドと教材活用トレーニング修了認定ファシリテーター Hi-Standard好きです。
http://yukioiizuka.com
mislead
MISLEADの記事に共感いただけましたら
いいねをお願いします。

コメント一覧

コメントはありません

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください



       

© yukio iizuka All Rights Reserved...