サブライブラリーのサブテーブルの後、主キーIDに対処する方法

データベースの実装に基づいて、

データベースの増分ID

これは、IDを取得するたびに、あなたのシステムは、データの小さなビジネス上の意味のライブラリにテーブルを挿入し、データベースのID増分を取得することであることを意味します。そして、サブサブライブラリーテーブル書き込み、外出先に対応するIDを取得するために下ります。

この方式の利点は、便利で簡単で、誰が使用されます。欠点は、単一のライブラリ生成インクリメントIDということで、高い同時実行は、その後、ボトルネックがあるだろう場合、あなたは、単に外観を向上させたい場合は、その後、すべての本サービスからサービスをオープンしました時間は、最大電流IDを取得し、その後、ID、IDのグループにIDを自身のいくつかのワンタイム・リターンをインクリメントした後インクリメントいくつかのID後の値に現在の最大値を変更する;しかし、いずれの場合にも、単一のデータベースに基づいています。

適切なシーン:二つの理由で、あなたのサブライブラリーのサブテーブル、いずれかの単一のデータベースの同時実行性が高すぎるか、あるいは単一のライブラリのデータが大きすぎる;あなたの同時実行性は高くありませんが、データの量は、サブライブラリーのサブテーブルに大きすぎない限り、それは、ライブラリとテーブルの自動インクリメントの主キーを生成するために、放置、その後、数百に第2のアップあたりの最高によって複雑にすることができるので拡大は、あなたは、このプログラムを使用することができます。

増分ステップ・フィールドを設定するテーブルまたはデータベース配列

水平方向のスケーリングは、データベース配列表または自己増力フィールド工程によって提供することができます。

例えば、そこに8つのサービスノード、シーケンスIDを生成する機能を使用して、各サービスノード、それぞれ異なる開始配列のIDであり、連続増分ステップ・サイズは8です。

データベース・IDシーケンスステップ

適したシナリオ:ユーザーIDが繰り返さ防止されたときに、このソリューションは、性能目標を達成することができ、実装が比較的簡単です。しかし、サービスノード固定ステップサイズも固定されているが、サービスノード、悪いがなかった場合も、将来的に増加します。

UUID

給付は、ローカルに来ていないデータベースに基づいて、生成される;悪い場所がある、UUIDが長すぎる、大空間、悪い主キーパフォーマンスなど、より重要なのは、UUIDは、秩序がないB +ツリーインデックスにつながることができます過剰なランダム書き込みの書き込みに(連続ID生成部は、シーケンシャルライトであることができる)、及び、挿入操作が必要な場合には、シーケンシャル書き込み追記動作を生成していないので、全体のB +を読み取りノード全体がディスクに書き戻されます後にメモリへのツリーノードは、このレコードが挿入され、記録空間におけるこの動作は比較的大きな、著しい性能劣化です。

適切なシーン:あなたは、ランダムに生成されたファイル名、番号等に欲しいものであれば、あなたはUUIDを使用することができますが、主キーがUUIDであるとして使用することはできません。

UUID .randomUUID().toString().replace(「- 」、「」)- > sfsdf23423rr234sfdaf

現在のシステム時刻を取得します。

これは、現在の時刻を取得することですが、問題は、このような1秒同時何千もの高い同時実行は、事態の繰り返しがあるだろうと、これは確かに適切ではないということです。基本的には考えられなかったでしょう。

適切なシーン:あなたは、一般的にこのプログラムを使用する場合は、現在の時間は、あなたが考えるビジネスが受け入れ可能である場合、また可能である、IDとして、一緒にスプライス他の多くの事業分野です。あなたは、グローバルに一意の番号を形成するために一緒にスプライシングされた現在の時刻とのビジネスフィールドの値を平準化することができます。

スノーフレークアルゴリズム

スノーフレークアルゴリズムは、長いタイプID 41は、作業機械10ビットで、数ミリ秒として、その中に使用されるビット、64ビット、1ビットを使用しないScalaの言語を使用して、収入分配ささえずりID生成アルゴリズムでありますID、シーケンス番号として12ビット。

  • 1ビット:ないので、なぜそれから?最初のビットにバイナリが1であるので、それがある場合、それは負であるが、我々は、IDを生成する正であるので、最初のビットが0に均一です。
  • 41ビット:それは、タイムスタンプ(ミリ秒)ことを示しています。41ビットの数は、最大に表現することができます  2^41 - 1つまり、あなたが識別することができ、  2^41 - 1 ミリ秒の値を、69歳で大人の用語で表現。
  • 10ビット:作業機IDを記録、サービス、すなわち1024機械最大2 ^ 10のマシンに展開することができ表します。しかし、5ビットの10ビット代わっ室IDで、マシンIDの代わりに5のGeビット。ほとんどの代表者という意味  2^5の部屋(32室)は、各部屋に表すことができ  2^5 、機械(32機)。
  • 12ビット:生成された、12ビットが表すことができる同じミリ秒に異なるIDを記録するために使用される最大の正の整数  2^12 - 1 = 4096、すなわち、この数は同じに異なるID 4096ミリ秒の間で区別するために12ビットで表すことができます。 。
0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000
パブリッククラスIdWorker {

    プライベートロングworkerId; プライベートロングdatacenterId、プライベート、長いシーケンス公共IdWorker(ロングworkerId、ロングdatacenterId、ロングシーケンス){ //正気workerIdためのチェック//ここにビットをチェックしていない、あなたはエンジンルームとマシンIDで渡されることが必要IDが0以上で32以上とすることができない(workerId IF > maxWorkerId || workerId < {0)スロー新しい新しいはIllegalArgumentException(文字列.format("最後のD 0内の最後の大%以下の範囲内で作業者IDすることができない"、maxWorkerId));} IF(datacenterId > maxDatacenterId || datacenterId <0){ スロー新しいはIllegalArgumentException(文字列.formatを("データセンターIDが%dまたは0より小さい値を超えることはできません)、maxDatacenterId")。} システムの.out .printf("ワーカー開始タイムスタンプシフト%のD、データセンターのIDビット%のD、作業者IDビット%のD、シーケンスは%dをビット、workerid%dの左"、timestampLeftShift、datacenterIdBits、workerIdBits、sequenceBits、workerId)。この.workerId = workerId。この.datacenterId = datacenterId。この.sequence =配列; } プライベート長いtwepoch = 1288834974657L。プライベートworkerIdBitsロング= 5L; プライベートロングdatacenterIdBits = 5L; //これはバイナリ操作であり、わずか5ビットは31桁までである、すなわち、機械は、ID 32内とすることができるプライベートロングmaxWorkerId = - 1L ^(- 1L workerIdBits <<); //これは、5ビットのみ32内のルームIDまで、唯一の31桁までの平均であるプライベートロングmaxDatacenterId = - 1L ^(- 1L << datacenterIdBits); プライベートロングsequenceBits = 12L; プライベートロングworkerIdShift = sequenceBits; プライベートロングdatacenterIdShift= sequenceBits + workerIdBits。プライベート長いtimestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits。プライベート長いsequenceMask = - 1L ^(- 1L << sequenceBits)。プライベート長いlastTimestamp = - 1L; 公衆ロングgetWorkerId(){ リターンworkerId。} パブリックロングgetDatacenterId(){ datacenterIdを返します。} パブリックロングgetTimestamp(){ 戻りシステム)(.currentTimeMillisします。} パブリック同期ロングNEXTID(){ //取得現在のタイムスタンプは、ここにあるミリ秒のロングタイムスタンプ= TIMEGEN(); IF(タイムスタンプ<LastTimestamp){ システム.ERR .printf(「時計が後退要求の%のDまで拒否しています。.. 」LastTimestamp); スロー新しい新規のRuntimeException(文字列.format("クロックは、%Dミリ秒を生成することを拒否するための下位IDを動かし。"、LastTimestamp -タイムスタンプ));} (LastTimestamp IF ==タイムスタンプ){ //これがあることを意味します唯一のミリ秒単位で最大4096個の番号を持つことはできません//どんなにあなたが渡されたどのくらい、この場所は、常に4096この範囲での動作は、あなたが4096シーケンスの範囲超えないようにシーケンスを渡す保証さ=(シーケンスを+1)&sequenceMask; IF(配列== 0){タイムスタンプ= tilNextMillis(LastTimestamp);}} 他{シーケンス= 0;} //ここで最後に生成されたIDミリ秒LastTimestampで記録したタイムスタンプ=タイムスタンプ; /ここで/タイムスタンプが41ビットに、左にある; // idが5ビットの部屋に残され; //マシン5ビットの左ID入れ、最後のシーケンス番号が「入れては、12ビットをされ; //最終的に64ビットの2進数に一緒にスプライシング、10進長い型に変換される((タイムスタンプリターン- twepoch)<< timestampLeftShift)(datacenterId | << datacenterIdShift)|(workerId << workerIdShift)};配列| プライベート長いtilNextMillis(長いLastTimestamp){長いタイムスタンプ= timeGen()。一方、(タイムスタンプ<= lastTimestamp){タイムスタンプ= timeGen()。} タイムスタンプを返します。} プライベートロングtimeGen(){ 戻りシステム)(.currentTimeMillisします。} // ---------------测试--------------- パブリック静的ボイドメイン(文字列[] 引数){ IdWorkerワーカー= 新しいIdWorker (1、1、1)。(のためのI値int = 0; iが< 30; iが++){ システムの.out .println(ワーカー.nextId())。}}}

あなたは41ビットはミリ秒単位での現在のタイムスタンプであることを、それの意味について、どのように言うか、それはこの意味である。そして、5ビットは、他の5ビット、あなたが部屋のIDで(だけ32の最大以内)に合格したことですあなたは前世代に従うならば、あなたのマシンが(だけで最大32以内)のidで渡され、12ビットのシリアル番号の残りの部分は、つまり、時間のミリ秒のIDの中に残っている場合、注文は、あなたが蓄積与えます未満4096個の番号まで。

ですから、彼はサービスに従事するツールを活用し、各部屋内の各マシンの機械室のシリアル番号の先頭が0である、そのようなことを初期化されます。そして、それは機械室は、IDを生成することを言って、リクエストを受信するたびに、対応する労働者の世代があります。

このアルゴリズムスノーフレークを使用して、あなたも機械室とIDのIDの、とにかく、あなたはさておき5ビット+ 5ビットを設定し、あなたが可能であり、他のものに意味をビジネスを持って、あなた自身の会社のサービスを開発することができます。

、通常は数十秒あたりの同時シーンの何千もの、それは高い同時実行であれば、これは比較的良好なパフォーマンスがどうあるべきか、あなたと十分なスノーフレークアルゴリズムはまだ比較的トリッキーなので、あなたが本当にID分散型発電を行う必要がありますA。

おすすめ

転載: www.cnblogs.com/windpoplar/p/10926571.html
おすすめ