[PHP-users 33276] Re: MySqlで二重書き込みを防ぐには?

池谷 美歌也 mikaya_ikeya @ pakureserve.jp
2008年 2月 14日 (木) 16:09:19 JST


確認してないので動くかどうか分かりませんが、dateとbidをユニークキーにして
ON DUPLICATE KEYを使うと一回のクエリで全部済むと思います。

マニュアルに「通常、複数の UNIQUE キーを持つテーブルに対しては ON DUPLICATE KEY 節を使用しないようにする。」という記述があるため、下
のコードではdateとbidを組み合わせた一つのユニークキーを用意したという前提でSQL文を作っています。

$type = $_GET[type];
$bid = $_GET[bid];

$sql = <<< EOSQL
  INSERT INTO counter
    (datebid,date,bid,$type)
  VALUES
    ($m$bid,$m,$bid,1)
  ON DUPLICATE KEY UPDATE
    {$type}={$type}+1;
EOSQL;
mysql_query($sql);

> if(!$res[0]){ //なかったら新規レコード追加
>
> $sql = "insert into counter set bid = '$_GET[bid]',date =
> '$m',$_GET[type] = '1',ac = '1'"; mysql_query($sql);
>
> }else if($res[0]){ //あったらカウント追加
>
> $sql = "update counter set $_GET[type] = $_GET[type]+1,ac =
> ac+1 where date = '$m' && bid = '$_GET[bid]'";
>
> mysql_query($sql);



> -----Original Message-----
> From: php-users-bounces @ php.gr.jp
> [mailto:php-users-bounces @ php.gr.jp] On Behalf Of 萩原
> Sent: Thursday, February 14, 2008 3:25 PM
> To: PHP-users ML
> Subject: [PHP-users 33271]MySqlで二重書き込みを防ぐには?
>
> MySqlを利用したアクセスカウンターを作成しています。
> アクセス数の多いサイト用なので1アクセス1レコードではなく、
> 日付け毎に1日の合計数がレコードにカウントされていく仕組みです。
>
> 流れとしては、
>
> アクセスがあった時点で本日のレコードがあるかチェック
>> レコードが無かったら本日(20080214)を新規でインサート or  すでに本日のレコードがあったら本日に1カウントupdate
>
> という簡単な流れです。
>
> 今回問題なのは、レコードが無かった場合(本日最初のアクセス)が、数件同時アクセスだった場合に
> 同じレコードが複数追加されています。
>
> このような仕組みを作る場合、MySqlでのlockはどのように行うのでしょうか?
>
> 詳しい方ご教授お願いします。
>
>
> ■実際のカウント用スクリプトです
>
> <?
>
> //DB接続
>
> $host = "******";
> //ユーザー
> $us = "******";
> //パスワード
> $pas = "******";
> //データベース
> $db = "*******";
>
> $con = mysql_connect($host,$us,$pas);
> if(!$con){echo "接続失敗";}
> mysql_select_db($db);
>
> //今日を取得
> $m = date("Ymd");
>
> //DBから今日のレコード有無をチェック
> $sql = "SELECT count(*) FROM counter ";
> $sql .= "where date = '$m' && bid = '$_GET[bid]'"; //
> ※複数のサイト連動のカウンターなのでサイトの識別を bid で分けています。
>
> $reslut = mysql_query($sql);
> $res = mysql_fetch_array($reslut);
>
> //カウント
> if(!$res[0]){ //なかったら新規レコード追加
>
> $sql = "insert into counter set bid = '$_GET[bid]',date =
> '$m',$_GET[type] = '1',ac = '1'"; mysql_query($sql);
>
> }else if($res[0]){ //あったらカウント追加
>
> $sql = "update counter set $_GET[type] = $_GET[type]+1,ac =
> ac+1 where date = '$m' && bid = '$_GET[bid]'";
>
> mysql_query($sql);
>
> }
>
> ?>
>
> _______________________________________________
> PHP-users mailing list  PHP-users @ php.gr.jp
> http://ml.php.gr.jp/mailman/listinfo/php-users
> PHP初心者のためのページ - 質問する前にはこちらをお読みください
> http://oldwww.php.gr.jp/php/novice.php3
>



PHP-users メーリングリストの案内