- ベストアンサー
データベースで重複しない乱数を生成する再帰関数
- データベースに存在するデータと重複しない乱数を生成する関数を再帰を使用して作成しました。
- 乱数を生成し、データベース内での重複チェックを行い、重複していれば再帰呼び出しを行います。
- 最終的に重複しない乱数が生成されるまで繰り返し、生成された乱数を返します。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
少し前に質問者さんがやっている事とほぼ全く同じような事をしたので、大体どんな風に書いたか書きます。 $flg = false; for($i=0;$i<3;$i++){ $uniqueId = func_rand_int();// 1~2147483647(Mysqlのintの最大値)をランダムで発生 $sql->query(sql_user_search($uniqueId));// $uniqueIdが登録されるかを調べる為のSQLを発行 if(!$sql->fetch_assoc()){ // クエリー無しの場合 // ここで登録処理 $flg = true; break; } } //ループを抜けた所で$flgがtrueだったらOK、falseなら例外でNG DBに1000万件のデータが入っていたとしても、 例外で登録が失敗する可能性は確率的に約1000万分の1 単純にuniqueidやmicrotimeを使って被らないIDを作るのもありですが、 IDから時間が推測出来るので 問題が無いくらいの確率を考えてこういうロジックでやりました。
その他の回答 (2)
- yambejp
- ベストアンサー率51% (3827/7415)
INSERT IGNORE INTOでデータを強制インサートして、 mysql_affected_rows()で、戻り値が1ならOK、0なら再処理 ただし同じIDが振られる可能性が高いのであれば、あまりやるべきではない 念のためカウンタをつかって最多エラーヒット回数を別テーブルに 履歴としてのこしておくとよいかも。
お礼
IGNOREオプションをはじめて知りました。 改めて調べて利用してみようと思います。 ありがとうございました^^
- oraora777
- ベストアンサー率20% (56/268)
そもそもそういうユニークキー作る時ってmt_rand()を使うのではなくて uniqid()を使ってユニークキーを作る。
お礼
ありがとうございます。 アドバイスを参考に書いてみました。 <?php function Func_CreateUniqueID(){ try{ $pdo=new PDO("mysql:host=localhost;dbname=DBNANME","USRNAME","PASS"); for($i=1;$i<=10;$i++){ $rand_num=mt_rand(); echo "発生させた乱数:$rand_num<br>"; $sql="select * from TBNAME where COLNAME like '$rand_num'"; $res=$pdo->query($sql); //クエリ実行 if($res->fetch(PDO::FETCH_ASSOC)){ echo "重複する値が存在しますよ、もう一度ループします<br>"; }else{ echo "重複する値が無いですよ、ループを抜けます. break<br>"; echo "ループ回数:$i<br>"; return $rand_num; break; } } //for文終わり }catch(PDOException $e){ var_dump($e->getMessage()); } } ?> まだ何を使えば良いのか、戻り値は何か?など細かい書き方について調べる必要がありますが、とりあえずは動きそうです。 どうもありがとうございました^^