私はランダムな6文字の注文番号を生成するこのPHPコードを持っています:
<?php
$random = mt_rand(100000,999999);
echo $random;
?>
この番号をデータベースに挿入することはできますが、重複がなく、注文番号が一意であることを確認するにはどうすればよいですか?
番号を一意のインデックスとして設定し、重複が見つかった場合にエラーをキャッチします。または、代わりに MySQL 関数 RAND() を使用して数値を生成し、値を取得します。
単一の INSERT ステートメントで実行できる可能性があります。このようなもの(ただし、この特定の例は、行数が増えると劇的に遅くなります)
INSERT INTO numbers (SomeNumber)
SELECT aNum
FROM (SELECT a.i+b.i*10+c.i*100+d.i*1000+e.i*10000 AS aNum
FROM integers a, integers b, integers c, integers d, integers e) Sub1
LEFT JOIN Numbers ON Sub1.aNum = Numbers.SomeNumber
WHERE Numbers.SomeNumber IS NULL
ORDER BY RAND()
LIMIT 1
または、はるかに効率的ですが、行が挿入されない可能性があります (10 個の乱数を生成し、挿入に使用されていないものを選択します)。したがって、影響を受ける行を確認し、0 の場合は再試行する必要があります:-
INSERT INTO numbers (SomeNumber)
SELECT aNum
FROM (SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum
UNION SELECT ROUND(RAND() * 899999) + 100000 AS aNum) Sub1
LEFT JOIN Numbers ON Sub1.aNum = Numbers.SomeNumber
WHERE Numbers.SomeNumber IS NULL
LIMIT 1
これらの両方の例で、挿入された行の ID を取得し、そこから挿入された番号を選択できます。
<?php
$random = mt_rand(100000,999999);
echo $random;
$sql ="SELECT FROM table where ordernumber=$random";
$result = mysqli_query($conn,$sql);
if(mysqli_num_rows($result)>0){
// regenerate random number
}
else{
//insert here
}
?>
しかし、これは良いアプローチではなく、自動インクリメントを使用します
データベースのこのフィールドに UNIQUE INDEX を作成するだけです。番号を生成し、データベースに存在するかどうかを確認します。存在する場合は、存在しないまで再試行します。
ランダム キーのアドレス空間が過密でないことを確認する必要がある唯一のキャッチは、そうしないと、衝突なしで新しいキーを生成するのが遅くなりすぎることです。
行数が可能なアドレス空間の 10% 未満である限り、この方法はうまく機能します。しかし、50%以上になるとかなり悪くなります。
これまでに未使用のキーのリストを保持しようとするいくつかの独創的なスキームを作成することもできますが、これはおそらく複雑すぎます。
挿入する前に、番号がデータベースに存在するかどうかを確認してください。はいの場合は、別の乱数を生成し、再度チェックを行います。ただし、このauto increment
機能を使用して同じことを行うことをお勧めします。