7

通常、100人のユーザーのテーブルがある場合は、主キーとしてuserID列を自動インクリメントするだけです。しかし、突然100万人または500万人のユーザーがいる場合、より分散され始めたいので、それは非常に困難になります。その場合、各ノードが同じ主キーを作成するため、自動インクリメントの主キーは役に立ちません。

これに対する解決策は、自然な主キーを使用することですか?私は、この多数のユーザーにとって自然な主キーを考えるのに本当に苦労しています。問題は、彼らはすべて若者であるため、国民保険番号や私が考えることができる他の一意の識別子を持っていないことです。複数列の主キーを作成することはできますが、それでも可能性はありますが、ごくわずかな重複が発生します。

誰かが解決策を知っていますか?

ありがとう

4

9 に答える 9

11

とりあえず、ユーザーIDの自動インクリメントを維持すると思います。

突然何百万人ものユーザーが殺到した場合は、それを変更することを考えることができます。

言い換えれば、あなたがそれを持っているときに問題を解決します。「時期尚早の最適化はすべての悪の根源です。」

質問に答えるために-いくつかの自動増分では自動増分をシードできるため、異なるノードで異なる自動増分を取得できます。これにより、自動インクリメントの使用を許可しながら、問題を回避できます。

于 2010-04-08T18:17:59.827 に答える
8

ここでの標準的な解決策は、GUIDを使用することです。ただし、インデックス作成に関してはパフォーマンスが低下します。

于 2010-04-08T18:16:55.067 に答える
2

GUIDは優れていますが、衝突する可能性があります(まれですが)。

これは非標準の解決策かもしれませんが、私はそれをそこに捨てるつもりです:

自動インクリメントの数値を使用できますが、将来的には分散に従って数値スペースを分離します。

たとえば、サーバーが3台あるとします。次のようにIDを記録します。

サーバー1: 0〜9,999,999
サーバー2:10,000,000〜19,999,999
サーバー3:20,000,000〜29,999,999

32ビットintの制約内でも、十分な拡張スペースを残す必要があり(心配な場合は、1億のギャップを使用することもできます)、基本的にシステム全体の一意性が保証されます。

于 2010-04-08T18:29:47.360 に答える
2

数百万の ID が必要で、多数のノードがある場合は、主キーを次の複合体にします。

NodeID  int   --unique for each node 2 or 4 byte  
UserID  int   --auto increment 8 byte, repeats for each node

これは GUID よりもはるかに優れています (小さく、メモリ使用量が少なく、高速になります)。

于 2010-04-08T18:37:49.900 に答える
1

パフォーマンスが低下し、データが低下する可能性がない限り、自然な主キーを使用しないでください。時間の経過とともに変更される可能性のない自然キー、特に名前はほとんどありません。自然キーが変更された場合、関連するすべての子レコードも変更する必要があります。これは明らかに悪いことです。

GUIDSを使用できます。しかし、500万はデータの観点からは何もありません。おそらく、変更は必要ありません。システムには10,000,000人を超えるさまざまな人がいて、パーティション化やGUIDの必要がない中規模のデータベースしかありません。

于 2010-04-08T18:23:33.900 に答える
0

GUIDは簡単な方法ですが...

どのくらい分散させる必要がありますか?データベースの数が限られている場合は、各データベースに使用する数の範囲を指定できます。したがって、たとえば、最初のデータベースは0〜999,999の範囲の数値を自動生成し、次のデータベースは1,000,000〜1,999,999を使用します。そうすれば、お互いにぶつかることなく、それぞれがユーザーIDを生成できます。データベースにそれを識別する一意の番号が含まれている場合、範囲はこの番号から自動的に生成されます。

自動インクリメント列を使用してこれを行うことはできないと思いますが、ストアドプロシージャはこの方法で数値を生成できます。

于 2010-04-08T18:27:12.040 に答える
0

GUIDは、クラスター化されるとキーとしてゴミになります。非クラスター化の場合でも、別の列にクラスター化インデックスが必要です。

整数キーを使用し、newノード/サイトごとに

  • 10刻みでインクリメントします。ノードを追加するときは、2、3などから始めます。
  • 使用範囲(例:1-> 1000000、1000000-> 1999999など)
  • そして、-veも忘れないでください。たとえば、2番目のノードにIDENTITY(-1、-1)を設定できます

ノード/サイトがある場合は、SiteIDの2番目の列も機能します。

于 2010-04-08T18:33:11.073 に答える
0

MSSQL を使用している場合は、テーブルの PK を UNIQUEIDENTIFIER として作成し、デフォルト値またはバインディングを NEWID() に設定できます。

于 2010-04-08T18:55:52.173 に答える
0

GUID を考慮しないことをお勧めします。理由の 1 つは、現在私が GUID で問題を抱えているためです。何百万ものユーザーがいる場合、より大きな同時実行性が必要になる可能性があり、インデックスがあるため、挿入および削除中に GUID があなたの人生を台無しにするでしょう。デフォルトではクラスター化インデックスになります。つまり、クラスター化インデックスがある場合、挿入と削除のたびにレコードが物理的に移動します。またはページのトップ。そのため、挿入操作と削除操作全体が非常にコストがかかり、インデックスを削除すると選択にコストがかかります。

特に、複数のテーブルがあり、それらの間に関係がある場合は、Guid を主キーと見なさないでください。

私が推奨する次の2つのソリューションがあります。

  1. 銀行ソフトウェアの場合のように完璧な複合キーを作成できる場合、transactionId は主キーになります。ここで、branchId はレコードを挿入するノードの ID であり、transactionId はブランチでの自動番号であるため、一意性が得られます。はるばる。

  2. 上記がやりたくない、または検討していない場合は、Guid を一意のフィールドとして使用できますが、自動インクリメント番号を主キーとして追加すると、クライアント (ノード) が (web を使用してデータを送信する場合のように) 全体的なコストを削減できますサービス) RPC の場合、レコードをサーバー データベースに挿入する必要があります。その後、自動番号が生成され、この自動番号は将来の選択、削除、または更新に使用できますが、クライアントはこの自動番号について知る必要はありません。

2 番目の解決策は少しわかりにくく複雑ですが、GUID を PK として使用するよりも優れています。ただし、解決策 1 が該当する場合は、それを選択してください。

コストは処理時間だけでなくロック (待機) 時間も同様に完全に無駄であり、クアッドコアサーバーはその半分を実行している可能性があり、ロックが増えるとデッドロックの可能性が高くなることを意味するので、私の友人は決してガイドを使用します。

よろしくムバシャール

于 2010-04-08T19:47:55.337 に答える