• 締切済み

「SELECTして取得できない場合、INSERT」の不完全さの改善

はじめまして。 ユニークキー設定しているカラムに、 SELECTして取得できない場合、INSERTの処理をすると 違うセッションでタイミングによってINSERTがエラーになってしまうと思います。(以下参照) -------------------------------------- 時間  SESSION1     SESSION2 ↓    SELECT→× ↓                SELECT→× ↓    INSERT→○ ↓                INSERT→× -------------------------------------- この様な場合、SESSION2を生かすには、その後SELECTを再度実行すればよいと思うのですが、他によい方法はないのでしょうか? 何かございましたら、ご教授お願いいたします。 各バージョン MySQL5.0 (PHP5.1)

みんなの回答

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

ん~だから最初に書いたとおりINSERT IGNORE INTOで問題ないのでは? SESSION1 insert ignore into t1 (value) values ('b'); select id from t1 where value = 'b'; SESSION2 insert ignore into t1 (value) values ('c'); select id from t1 where value = 'c'; たとえばこれが insert ignore into t1 (value) values ('b'); insert ignore into t1 (value) values ('c'); select id from t1 where value = 'b'; select id from t1 where value = 'c'; でも結果はおなじですよね? こういうことがやりたいのではないのですか? (仮にすでにvalueにbやcがあれば、insert処理が無視されるので なんの問題もないです)

hekotare
質問者

お礼

ご回答ありがとうございます。 なるほど。初めのSELECTを省くということですか。 その場合、毎回INSERTを流すことになると思いますが、実際にINSERTされない場合は、 それほどサーバに負荷はかからないと考えてよろしいでしょうか? そうであれば、問題ないと思います。

すると、全ての回答が全文表示されます。
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

SELECTして取得できないとか・・・なにか難しいことを 考えているような感じなので、 簡単な具体例をあげてみたほうが良いと思います。

hekotare
質問者

お礼

具体的な例として、以下を準備します。 -------------------------------------------- create table t1( id int auto_increment primary key, value varchar(10), unique (value) ); insert into t1 (value) values ('a'); -------------------------------------------- まず select id from t1 where value = 'a'; としたときに、idは取得できます。 次に、 select id from t1 where value = 'b'; とした場合、結果がありませんので、 insert into t1 (value) values ('b'); select last_insert_id(); とします。 そこで、違う2つのセッションでほぼ同時に select id from t1 where value = 'c'; がされた場合、 片方は insert into t1 (value) values ('c'); select last_insert_id(); が成功しますが、もう一方はinsertできません。 最終的に取得したいものは、id(auto_increment)ですので、 取得するには、insertが失敗した方で、再度 select t1 where value = 'c'; をしないといけません。 結構このようにしたい場合はあると思うのですが、 いい方法を知りません。 何かありましたら、ご教示していただけますとうれしいです。

すると、全ての回答が全文表示されます。
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

なにをしたいかよくわかりませんが、 INSERT IGNORE INTO すればいいだけでは?

hekotare
質問者

お礼

ご回答ありがとうございます。 すみません。補足します。 SELECTされた行の番号(AUTO_INCREMENT)を取得することを前提とさせていただきます。(INSERTの場合は、LAST_INSERT_ID()) ですので、やはりINSERTした後にSELECTが必要になってしまうのでしょうか? 何か遠回りのような気がしまして、投稿させていただいた次第です。 よろしくお願いいたします。

すると、全ての回答が全文表示されます。

関連するQ&A