affected rows
MySQL で UPDATE 文を実行したときに、マッチした行の数と実際に更新処理がされる行の数は一致しない。
ということを知らずにいて一時間ほどさまよってた。
UPDATE 文が作用した行数が 1 以上であれば、すでにテーブルにはレコードがあり、そのレコードが更新されたとしてそこで終了。行数が 1 未満であれば、テーブルにはレコードなかったので、INSERT 文を実行する。
なんてロジックにしていたら、アクセス数が多くなったときに、UPDATE 文が複数のクライアントで同じになってしまい、余分にレコードが INSERT されてしまっていた。面倒くさくても事前に SELECT して、対象のレコードがあるかないか確かめなきゃダメだね(REPLACE は使えない状況だった)。
<?php // updated がすでに '2010-05-12 00:00:00' になっていると、更新は実行されないので // affected rows は 0. $query = "UPDATE hoge SET updated = '2010-05-12 00:00:00' WHERE id = 123"; $affected_rows = $db->exec($query); if ($affected_rows < 1) { // INSERT } else { // NOP }