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

萩原 namioh @ sea.plala.or.jp
2008年 2月 15日 (金) 19:22:32 JST


ミカヤ様

お世話になります。

テーブル構造を以下に変更しました。
実際にエクスポートしたものです。

-- 
-- テーブルの構造 `counter2`
-- 

CREATE TABLE `counter2` (
  `bid` int(10) NOT NULL,
  `ac` int(11) NOT NULL DEFAULT '0',
  `pc` int(11) NOT NULL DEFAULT '0',
  `mb` int(11) NOT NULL DEFAULT '0',
  `date` int(11) NOT NULL,
  UNIQUE KEY `datebid` (`date`,`bid`)
) ENGINE=MyISAM DEFAULT CHARSET=ujis;

しかくうまく動作しませんでした。

phpで実行された実際のSQLは以下になります。
----------------------------------
INSERT INTO counter2
    (datebid,date,bid,mb)
  VALUES
    (200802154,20080215,4,1)
  ON DUPLICATE KEY UPDATE
    mb=mb+1;
----------------------------------

DBで直接SQLを実行すると
#1054 - Unknown column 'datebid' in 'field list'

になってしまいます。

datebidというフィードが必要なのでしょうか?

お手数お掛けいたします。


萩原



----- Original Message ----- 
From: "池谷 美歌也" <mikaya_ikeya @ pakureserve.jp>
To: "'PHP-users ML'" <php-users @ php.gr.jp>
Sent: Friday, February 15, 2008 5:31 PM
Subject: [PHP-users 33286] Re:MySql で二重書き込みを防ぐには?


> ミカヤです。
>
>> --
>> -- テーブルの構造 `counter2`
>> --
>>
>> CREATE TABLE `counter2` (
>>   `bid` int(10) NOT NULL,
>>   `ac` int(11) NOT NULL DEFAULT '0',
>>   `pc` int(11) NOT NULL DEFAULT '0',
>>   `mb` int(11) NOT NULL DEFAULT '0',
>>   `date` int(11) NOT NULL,
>>   UNIQUE KEY `bid` (`bid`),
>>   UNIQUE KEY `date` (`date`)
>> ) ENGINE=MyISAM DEFAULT CHARSET=ujis;
>
> このユニークキーの設定では「複数」にユニークキーになってしまいます。
> この設定だとbidとdateのどちらもユニークでなければならないので望みのデータ保存は出来ません。
>
> 「複合」のユニークキーは下のように設定します。
> -- -------------------------------------
> CREATE TABLE IF NOT EXISTS `counter2` (
>  `bid` int(10) NOT NULL,
>  `ac` int(11) NOT NULL default '0',
>  `pc` int(11) NOT NULL default '0',
>  `mb` int(11) NOT NULL default '0',
>  `date` int(11) NOT NULL,
>  UNIQUE KEY `datebid` (`date`,`bid`)
> ) ENGINE=MyISAM DEFAULT CHARSET=ujis;
> -- -------------------------------------
> こうするとdateとbidのセットでユニーク、という設定になります。
>
>
>
>> $type = $_GET[type];
>> $bid = $_GET[bid];
>>
>> $sql = <<< EOSQL
>>   INSERT INTO counter2
>>     (datebid,date,bid,$type)
>>   VALUES
>>     ($m$bid,$m,$bid,1)
>>   ON DUPLICATE KEY UPDATE
>>     {$type}={$type}+1;
>> EOSQL;
>> mysql_query($sql);
> 説明が足りなかったのかも知れませんが、このコードはテーブルに「datebid」というユニークキーの列を追加したという前提で書いたものです。
> これをそのまま使用しても、テーブルにdatebidという列がないので普通にUnknown 
> columnのエラーが出ませんか?
>
> 環境に合わせるなら次のようなコードになるんじゃないでしょうか。
> // -------------------------------------
> $type = $_GET[type];
> $bid = $_GET[bid];
>
> $sql = <<< EOSQL
>  INSERT INTO counter2
>    (date,bid,ac,$type)
>  VALUES
>    ($m,$bid,1,1)
>  ON DUPLICATE KEY UPDATE
>    ac=ac+1, {$type}={$type}+1;
> EOSQL;
> mysql_query($sql);
> // -------------------------------------
>
>
> あとおせっかいかもしれませんが、自動で吐き出すタグのURLとはいえGETのクエリ文字列をそのままSQLに埋め込むのは危険だと思いますよ。
> // -------------------------------------
>  $type = mysql_real_escape_string($_GET[type]);
>  $bid = mysql_real_escape_string($_GET[bid]);
> // -------------------------------------
> せめてこれくらいの対策はしたほうがいいです。
>
>
>> -----Original Message-----
>> From: php-users-bounces @ php.gr.jp
>> [mailto:php-users-bounces @ php.gr.jp] On Behalf Of 萩原
>> Sent: Friday, February 15, 2008 4:50 PM
>> To: PHP-users ML
>> Subject: [PHP-users 33284] Re:MySql で二重書き込みを防ぐには?
>>
>> ミヤカ様
>>
>> ありがとうございます。
>>
>> ご指示いただいたスクリプトを試してみました。
>> しかし、INSERTとUPDATEともにうまく処理されませんでした。
>>
>> 自分でもON DUPLICATE KEY について調べてみましたが、
>> 原因が特定できません。
>>
>> 何か基本的な事が間違っているのでしょうか?
>>
>> 今までのスクリプトをストップできないので、
>> counter2というテスト用テーブルを作成して試しています。
>>
>>
>>
>> //カウント
>> if(!$res[0]){ //なかったらインサート
>>
>> $sql = "insert into counter set bid = '$_GET[bid]',date =
>> '$m',$_GET[type] = '1',ac = '1'"; mysql_query($sql); echo $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);
>> echo $sql;
>>
>> }
>>
>> ここまでは正常に処理されています
>>
>> //カウント(ここからご指示いただいたスクリプトテストです)
>> $type = $_GET[type];
>> $bid = $_GET[bid];
>>
>> $sql = <<< EOSQL
>>   INSERT INTO counter2
>>     (datebid,date,bid,$type)
>>   VALUES
>>     ($m$bid,$m,$bid,1)
>>   ON DUPLICATE KEY UPDATE
>>     {$type}={$type}+1;
>> EOSQL;
>> mysql_query($sql);
>>
>>
>> --
>> -- テーブルの構造 `counter2`
>> --
>>
>> CREATE TABLE `counter2` (
>>   `bid` int(10) NOT NULL,
>>   `ac` int(11) NOT NULL DEFAULT '0',
>>   `pc` int(11) NOT NULL DEFAULT '0',
>>   `mb` int(11) NOT NULL DEFAULT '0',
>>   `date` int(11) NOT NULL,
>>   UNIQUE KEY `bid` (`bid`),
>>   UNIQUE KEY `date` (`date`)
>> ) ENGINE=MyISAM DEFAULT CHARSET=ujis;
>>
>>
>> ※以下のタグでカウンターを読み込んでいます
>>
>> <img src='http://******.***/count.php?bid=1&type=pc'
>> width="1" height="1">
>>
>> お忙しいところお手数お掛けいたします。
>>
>>
>> 萩原
>>
>
> _______________________________________________
> 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 メーリングリストの案内