プロが教える店舗&オフィスのセキュリティ対策術

下記の通り同じデータが無かった場合に限りインサートしています。


//同じデータが既にあるか確認
$sql = "select * from `reg_data` where ";
$sql .= "`Date` = '".$date."' and ";
$sql .= "`ID` = '".$id."' and ";
$sql .= "`No` = '".$no."'";
$result = mysql_query($sql);
$rows = mysql_num_rows($result);

//データが0なら今日のレコード作成
if($rows == 0){

$sql = "insert into `reg_data` values('0', '".$date."', '".$id."', '".$no.")";
mysql_query($sql);
}


しかし、3%ぐらいの確立で重複インサートになってしまいます。


重複といっても
1個目のフィールドはAUTO_INCREMENTになっておりまして

AUTO_INCREMENTの値が重複する事は無いです。


$date、$id、$noがまったく同じテーブルがいくつか重複した場合でも
AUTO_INCREMENTの値は全て連番になっています。


重複インサートが発生しないよう改善するには
どうしたら良いでしょうか。


日付を2フィールド目に書いているので
0時0分1秒辺りでインサートが集中してしまいます。

分散させられたら改善するような気がしますが
いい案が思いつきません。


宜しくお願い致します。

A 回答 (2件)

Date, ID, No でユニークインデックスを作成して、DBに重複しないよう管理させてはどうでしょう。



CREATE UNIQUE INDEX idx_reg_data ON reg_data (Date, ID, No);
    • good
    • 0
この回答へのお礼

UNIQUE INDEXの詳しい利用方法を始めて知りました。


複数の組み合わせで
ユニークになるようにMySQLに管理させる事が出来るんですね

こんな便利な機能があったなんて・・・


教えて頂きありがとう御座います!

無事に実装でき、重複が無くなりました!

お礼日時:2012/06/15 16:18

データベースの一意性保証の問題ですね。



質問者さんの問題は、「同じデータがあるか確認」してから、実際に「レコード作成」までの間に、他のプロセスあるいはスレッドの処理が入りこむケースでしょう。
あるデータが、データ確認からレコード作成するまでに、他のプロセスが「データ確認・レコード作成」の処理ができないように、例えばテーブルロックすれば、解決しますね。

もちろん、テーブルロックをすることで全体の処理速度は低下します。それが、許容できるかどうか?許容できるなら、それで解決ですが、許容できないレベルの速度低下となるなら、キー項目の持ち方を変えるなり、何かさらに対策を考えることになると思います。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!