一意のシリアル番号の生成
このドキュメントでは、独自の一意の ID を生成する開発者を支援する一意のシリアル番号生成スキームを紹介します。
自動インクリメント列
AUTO_INCREMENT
は、MySQL プロトコルと互換性のある多くの RDBMS の列属性です。 AUTO_INCREMENT
属性を使用すると、データベースはユーザーの介入なしにこの列に値を自動的に割り当てることができます。テーブル内のレコード数が増えると、この列の値は自動的に増加し、一意であることが保証されます。ほとんどのシナリオでは、 AUTO_INCREMENT
列がプロキシ主キーとして使用されますが、実際には意味がありません。
AUTO_INCREMENT
列の制限は、列が整数型である必要があり、それらに割り当てられる値が整数でなければならないことです。アプリケーションで必要なシリアル番号が文字、数字、およびその他の文字でスライスされている場合、ユーザーがシリアル番号で必要な自動インクリメント番号をAUTO_INCREMENT
列から取得することは困難です。
シーケンス
シーケンス は、増分シーケンス値を生成するためにアプリケーションが呼び出すことができるデータベース オブジェクトです。アプリケーションは、シーケンス値を柔軟に使用して、1 つ以上のテーブルに値を割り当てることができます。アプリケーションは、より複雑な処理にシーケンス値を使用して、テキストと数値の組み合わせを生成することもできます。このアプローチにより、プロキシ キーに追跡と分類の意味が与えられます。
シーケンスは TiDB v4.0 から利用できます。詳細については、 配列文書を参照してください。
スノーフレークのようなソリューション
Snowflake は、Twitter が提案する分散 ID 生成ソリューションです。いくつかの実装があり、より一般的なものは、Baidu のuid-generatorと Meituan のleafです。このセクションでは、例としてuid-generator
を使用します。
uid-generator
によって生成される 64 ビットの ID 構造は次のとおりです。
| sign | delta seconds | worker node id | sequencs |
|------|---------------|----------------|----------|
| 1bit | 28bits | 22bits | 13bits |
- 符号: 1 ビットの固定長。生成された ID が常に正の数であることを示すために、
0
に固定されています。 - デルタ秒: デフォルトで 28 ビット。現在の時間。事前設定された時間基準 (デフォルトは
2016-05-20
) に対する秒単位の増分値として表されます。 28 ビットで約 8.7 年までサポートできます。 - ワーカー ノード ID: デフォルトで 22 ビット。マシン ID を表します。通常、アプリケーション プロセスの開始時に集中型 ID ジェネレーターから取得されます。一般的な集中型 ID ジェネレーターには、自動インクリメント列と ZooKeeper が含まれます。デフォルトの割り当てポリシーは、都度破棄で、プロセスは再起動時に新しいワーカー ノード ID を再取得します。 22 ビットは、最大約 420 万回の開始をサポートできます。
- シーケンス: デフォルトで 13 ビット。 1 秒あたりの同時実行数のシーケンス。 13 ビットは、1 秒あたり 8192 の同時シーケンスをサポートできます。
番号割り当てソリューション
番号割り当てソリューションは、データベースからの自動インクリメント ID の一括取得として理解できます。このスキームには、各行がシーケンス オブジェクトを表すシーケンス番号生成テーブルが必要です。テーブル定義の例は次のとおりです。
フィールド名 | フィールドタイプ | フィールドの説明 |
---|---|---|
SEQ_NAME | varchar(128) | さまざまなアプリケーションを区別するために使用されるシーケンスの名前。 |
MAX_ID | bigint(20) | 割り当てられている現在のシーケンスの最大値。 |
STEP | int(11) | 割り当てられた各セグメントの長さを示すステップ。 |
毎回、アプリケーションは構成されたステップでシーケンス番号のセグメントを取得します。同時にデータベースを更新して、割り当てられている現在のシーケンスの最大値を保持します。シーケンス番号の処理と割り当ては、アプリケーションのメモリで完了します。シーケンス番号のセグメントが使い果たされると、アプリケーションはシーケンス番号の新しいセグメントを取得します。これにより、データベースへの書き込みに対する負荷が効果的に軽減されます。実際には、ステップを調整してデータベース更新の頻度を制御することもできます。
最後に、上記の 2 つのソリューションで生成された ID は、TiDB テーブルの主キーとして直接使用できるほどランダムではないことに注意してください。実際には、生成された ID に対してビット リバースを実行して、よりランダムな新しい ID を取得できます。