固有のシリアル番号の生成
このドキュメントでは、独自の一意の 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 が含まれます。デフォルトの割り当てポリシーは「discard-as-you-go」であり、プロセスは再起動時に新しいワーカー ノード 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 を取得できます。