0

私のデータベース アプリケーションでは、顧客ごとに一意の 4 桁の数字フィールドが必要です。9999 までは自動インクリメントを使用できますが、その後は削除された顧客数を再利用する必要があります (特定の時点で 5000 を超える顧客は存在しませんが、生涯にわたって 9999 を超える顧客が存在する可能性があります)。システム)。

質問 1: 次の再利用可能な空き番号を見つける (My)SQL ステートメントはありますか?

質問 2: 番号を取得し、それを新しい顧客に割り当て、その顧客をすべて 1 つのトランザクションで保存した場合、同時に行われた同様のトランザクションはデータベースによって順次処理されるため、番号が衝突しませんよね?

4

5 に答える 5

7

10,000 の可能な値すべてが定義されたテーブルを保存し、それぞれに「使用中」フラグを付けた方がよいでしょう。そうすれば、再利用のために番号を解放するのは、「inuse=false」を設定するための簡単な更新です。

また、利用可能な最小値を簡単に見つけることができます

SELECT idstring
FROM idstringtable
ORDER BY idstring ASC
WHERE (available = 1)
LIMIT 1

適切なロック/トランザクションでこれを行うと、2 つ以上のリクエストが同じ ID を取得するのを防ぐことができます。また、テーブルが小さいため、グローバル テーブル ロックを行ってもパフォーマンスに大きな影響はありません。

そうしないと、番号付けシーケンスの最初の「ギャップ」を見つけようとして、users テーブルを探し回る羽目になります。

于 2011-10-19T20:28:02.247 に答える
2

このモデルを使用する必要がある場合(そして私はそれに対してお勧めします)、「利用可能な」番号のプールを作成し、アカウントを作成するときに、そこからTOP1を取得します。次に、ユーザーが削除されたら、その番号をプールに返します。

于 2011-10-19T20:28:30.573 に答える
1

別のテーブルを使用して使用中の ID を追跡するという推奨事項は機能しますが、別のテーブルを使用して使用中の ID を追跡したくない場合は、自己結合を実行して ID 番号のギャップを見つけることができます。自己結合は非常に単純です。

select top 1 t1.id + 1
  from table t1
  left join table t2 on t1.id = t2.id - 1
 where t1.id < 10000
   and t2.id is null

MS SQL Server では TOP 1 を使用して最上位の結果を取得しますが、MySQL では構文が異なる場合があります。

于 2011-10-19T21:53:57.660 に答える
1

これは、最初に利用可能なスロットを見つけるためのものです:

select i1.id + 1 as FirstAvailable
from issues i1 left join issues i2 on (i1.id = i2.id - 1)
where i2.id is null
limit 1

これは本番環境の Redmine インスタンスに対して実行され、欠落している最初の ID を見つけました。必要に応じて調整してください。

于 2011-10-19T20:34:08.933 に答える