2012-02-18 11 views
4

ランダムに生成された一意の値を含むMySQLにデータを挿入するPHPアプリケーションがあります。この文字列には約10億の可能性があり、おそらく一度に1〜200万件ものエントリーはありません。基本的に、ほとんどの組み合わせはデータベースに存在しません。MySQLはユニークなテクニックを挿入します

私は、挿入時に一意の値を保証するための最もコストのかからないアプローチを見つけようとしています。具体的には、私の2つのオプションは次のとおりです。

  1. この一意のIDを生成する関数があります。各世代で、値がデータベースに存在するかどうかをテストし、存在する場合は、それを再生成します。
  2. ランダムな文字列を生成して挿入を試みます。挿入に失敗した場合、テストエラーは1062です(鍵X Yの場合、MySQLの重複エントリ)、キーを再生成して新しい値を挿入します。

挿入を再試行する際にMySQLエラーに頼るのは悪い考えですか?私が見ているように、値はおそらくユニークで、初期(テクニック1を使用する)は不要であるようです。

EDIT#1

私も言及している必要があり、値は大文字および/または数字のいずれかで構成される6文字の長さの文字列でなければなりません。インクリメンタルにすることはできません。ランダムにする必要があります。サイドノートとして

EDIT#2

、私は推測することは困難である商品券の償還コードを作成しようとしています。数字と文字を使用すると、それぞれの文字に対して36個の可能性が生まれます。単なる数字の場合は10個、単なる文字の場合は26個です。

ここでは、私が作成した解決策を取り除きました。表に入力された最初の値は主キーで、自動増分されます。 affected_rows()の挿入が成功した場合は1に等しくなります。

$code = $build_code(); 
while ((INSERT INTO certificates VALUES ('', $code) ON DUPLICATE KEY UPDATE pk = pk) && affected_rows() == 0) 
     $code = $build_code(); 
+0

サイドの議論を:私もこの種の問題を満たしています。良い解決策は、ランダムな文字列をタイムスタンプと組み合わせて使用​​することでした。その結果、文字列を推測することはできず、データベースに文字列/挿入を生成する際に衝突がないことを保証します。 –

+0

[uniqid](http://php.net/manual/en/function.uniqid.php)機能を見ましたか? – Beatles1692

+0

ランダムな一意のIDをどれだけ大きくするかを決める際の経験則です。どちらかといえば重複しないようにしてください(ハードウェアに欠陥がある可能性が高く、重複があるよりも誤った答えが返される可能性が高くなります)。または、重複が常に発生するように十分小さくして(有限の時間にコードをテストできるように)、それに対処するチェックをしてください。 –

答えて

2

挿入を再試行するためにMySQLエラーに頼るのは悪い考えですか?

いいえ。あなたが望むなら、それを先に使ってください。事実、多くの人があなたがチェックして、それが存在しなければ、それは挿入するのが安全だと思っています。しかし、テーブルをロックしない限り、別のプロセスが侵入してIDを取得する可能性が常にあります。

あなたの目的に合っていれば、ランダムなIDを生成してください。 dupsを適切に処理するように、コードをテストするようにしてください。 unkey dupがどのように発生するかについてのあなたの前提を確実にするために、単にdupを記録するのにも役立つでしょう。

-1

理由だけではなく、使用しない: "YourColName BIGINT AUTO_INCREMENT PRIMARY KEY" 一意性を確保するために?

+1

AUTO_INCREMENTはランダムなものではなく、以下の数字を生成するので、 –

+0

私はちょうどあなたがこれをやりたい理由を理解していないと思いますか? –

関連する問題