データベース名:はてな
テーブル名:人力
カラム:id, 部屋名(Not uniqe)
今回得たい結果:
id | 部屋名
------------------
1 | h2
2 | h1
※h1とh2の順序は逆でも良い
■A,B,C,Dの4人がいると仮定します。
今、AからDが同時にデータの挿入を開始します。
A,Bは部屋名「h1」のデータを挿入。
C,Dは部屋名「h2」のデータを挿入。
しかし、このまま全員が『同時』にデータの挿入を行うと、
if文を書いていたとしても、例えば、
id| 部屋名
----------------
1 | h1
2 | h2
3 | h2
上記のように重複した部屋名が出来てしまうことがあります。
現在、テーブルをロックすることで回避しているのですが、
人数が増えたとき待ち時間がどれくらい増えるか不安です。
解決策があればよろしくお願いします。
※テーブルロックでの待ち時間は、
100人だろうが、1万人だろうが大したことない。
という答えが一番嬉しかったり…
ロック処理自体のコストはたいしたことは無いが、テーブルロックだとすべての INSERT が順番にしか実行できないから
件数が多いと件数分の時間がそのままかかってしまうね。
部屋名が UNIQUE になるテーブル、たとえば
CREATE TABLE 部屋 ( 部屋ID integer primary key, 部屋名 text UNIQUE NOT NULL );
なんてのを作っておいて、INSERT 実行前に必ず
SELECT * FROM 部屋 WHERE 部屋名 = 'h1' FOR UPDATE
を実行するようにすれば、行レベルのロックですむから部屋が別の人の処理は同時実行できる。
前提として MyISAM では無理なのと部屋名を決める処理はアプリケーション側で工夫しなければいけないぐらいか。
もうちょっと詳細が分かればスマートなやり方もあるのだろうけど。
まず、異なるユーザーが同時に同じレコードを更新する頻度を推測して下さい。ユーザー数は最大を見込んで計算してください。
それが、数分に1回程度の頻度であれば、現状のようにロックをかけることで十分だと思います。ロック処理で待たされることは無いはずですから。
同時更新が毎秒発生するようだと、別の対応策が必要です。
たとえばメッセージキューを使う方法があります。MySQL 5.1 限定ですが、「Q4M - MySQL 上で動作するメッセージキュー」で紹介されています。PHPからも利用できます。
ただ、キューが満杯になるケースもあり得るわけで、できれば、同時更新レコードが発生しないようなDB設計(または業務設計)をした方が良いと思います。
有り難う御座います!
詳細を省いてしまったせいで、回答し辛くしてしまい申し訳ありませんでした。
早速頻度の推測から始めたいと思います。
ロック処理自体のコストはたいしたことは無いが、テーブルロックだとすべての INSERT が順番にしか実行できないから
件数が多いと件数分の時間がそのままかかってしまうね。
部屋名が UNIQUE になるテーブル、たとえば
CREATE TABLE 部屋 ( 部屋ID integer primary key, 部屋名 text UNIQUE NOT NULL );
なんてのを作っておいて、INSERT 実行前に必ず
SELECT * FROM 部屋 WHERE 部屋名 = 'h1' FOR UPDATE
を実行するようにすれば、行レベルのロックですむから部屋が別の人の処理は同時実行できる。
前提として MyISAM では無理なのと部屋名を決める処理はアプリケーション側で工夫しなければいけないぐらいか。
もうちょっと詳細が分かればスマートなやり方もあるのだろうけど。
ありがとうございます。
求めている回答にかなり近いものです!
これで締め切りますが、より「スマート」な方法があればコメント欄に是非お願いします。
ポイントを送信したいと思います。
ありがとうございます。
求めている回答にかなり近いものです!
これで締め切りますが、より「スマート」な方法があればコメント欄に是非お願いします。
ポイントを送信したいと思います。