4

今まで私は C# を使ってきました "Guid = Guid.NewGuid();" Linq to SQL を使用して、一部の SQL Server データベース テーブルに ID フィールドとして格納できる一意の ID を生成する方法。インデックス作成の理由から、GUID を使用するのは良くない考えであり、代わりに自動インクリメントの Long を使用する必要があるとのことでした。長時間使用すると、データベース トランザクションが高速化されますか? その場合、Long タイプの一意の ID を生成するにはどうすればよいですか?

よろしく、

4

7 に答える 7

10

どちらにも長所と短所があり、重要なのはそれらをどのように使用するかに完全に依存します.

すぐに、複数のデータベースで機能する識別子が必要な場合は、GUID が必要です。Long にはいくつかのトリック (各データベースに異なるシード/インクリメントを手動で割り当てる) がありますが、これらはうまくスケーリングしません。

インデックス作成に関する限り、インデックスがクラスター化されている場合 (デフォルトでは主キーがクラスター化されていますが、これはテーブルに合わせて変更できます)、挿入のたびにテーブルを再編成する必要がないため、Long を使用すると挿入パフォーマンスが大幅に向上します。

ただし、同時挿入に関する限り、長い (ID) 列は GUID よりも遅くなります。ID 列の生成では、1 つの行だけが次の連番を取得するように一連の排他ロックが必要です。多くのユーザーが常に多くの行を挿入する環境では、これによりパフォーマンスが低下する可能性があります。この状況での GUID 生成は高速です。

ストレージに関しては、GUID は Long の 2 倍のスペースを占有します (8 バイトと 16 バイト)。ただし、8 バイトが 1 つのリーフに収まるレコードの数に顕著な違いをもたらすかどうかは、行の全体的なサイズに依存し、したがって、平均的なリクエスト中にディスクから取り出されるリーフの数に依存します。

于 2009-07-23T12:07:14.800 に答える
4

「インデックス作成の女王」であるKim Trippは、基本的に彼女のインデックス作成ブログ投稿ですべてを述べています。

基本的に、彼女のベスト プラクティスは次のとおりです。最適なクラスタリング キーは次のようになります。

  • 個性的
  • 小さな
  • 安定している (決して変化しない)
  • 増え続ける

GUID は「小さい」および「増え続ける」に違反しているため、最適ではありません。

さらに、すべてのクラスタ化キーは、すべての非クラスター化インデックスのすべてのエントリに追加されるため (データベース内のレコードを実際に検索するためのルックアップとして)、可能な限り小さくする必要があります (INT = 4 バイト対 GUID = 16 バイト)。数億の行といくつかの非クラスター化インデックスがある場合、GUID ではなく INT または BIGINT を選択すると、スペースに関してだけでも大きな違いが生じる可能性があります。

マルク

于 2009-07-23T13:52:08.737 に答える
3

long (SQL サーバーの big int) は 8 バイトで、Guid は 16 バイトであるため、ルックアップ時に SQL サーバーが比較しなければならないバイト数を半分にしています。

long を生成するには、データベースにフィールドを作成するときに IDENTITY(1,1) を使用します。

そのため、create table または alter table を使用します。

Field_NAME BIGINT NOT NULL PRIMARY KEY IDENTITY(1,1)

Linq を sql に投稿するためのコメントを参照してください

于 2009-07-23T11:42:53.490 に答える
3

これを見てください

ID列にuniqueidentifier(GUID)またはbigintを使用する方が良いですか?

于 2009-07-23T11:50:19.000 に答える
1

GUIDまたはIDについて1日中議論できます。私はデータベースがアイデンティティを持つ一意の値を生成することを好みます。複数のデータベースのデータをマージする場合は、別の列を追加して(ソースデータベースを識別するために、場合によってはtinyintまたはsmallint)、複合主キーを形成します。

IDを使用する場合は、生成する予想されるキーの数に基づいて、適切なデータ型を選択してください。

bigint - 8 Bytes - max positive value: 9,223,372,036,854,775,807  
int    - 4 Bytes - max positive value:             2,147,483,647

「予想されるキーの数」は行の数とは異なることに注意してください。主に行を追加して保持する場合、20億を超える一意のキーでINTで十分であることがわかる場合があります。あなたのテーブルはそれほど大きくならないでしょう。ただし、行の追加と削除を続ける大量のテーブルがある場合は、行数が少なくなる可能性がありますが、キーをすばやく処理できます。INT 20億のキーを通過するのにどのようにログが必要かを確認するには、いくつかの計算を行う必要があります。すぐに使い果たされない場合はINTを使用し、そうでない場合はキーサイズを2倍にしてBIGINTを使用します。

于 2009-07-23T13:32:16.560 に答える
1

複数のデータベースへのインポート/エクスポートを検討する必要がある場合は、GUID を使用してください。複数の子リレーションシップのデータセットを操作する場合、IDENTITY 属性を指定する列よりも多くの場合、GUID を使用する方が簡単です。これは、データベースから切断された状態でコード内に GUID をランダムに生成し、すべての変更を一度に送信できるためです。GUID が適切に生成されると、偶然複製することは非常に困難になります。ID 列では、多くの場合、子データを追加する前に、親行の最初の挿入とその新しい ID のクエリを実行する必要があります。次に、データベースにコミットする前に、すべての子レコードを新しい親 ID で更新する必要があります。同じことが孫などにも当てはまり、階層を下っていきます。不必要で平凡に思える多くの作業が積み重なっていきます。IDENTITY を指定せずにランダムな整数を考え出すことで、Guid と同様のことを行うことができますが、時間の経過とともにより多くのレコードを挿入すると、衝突の可能性が大幅に増加します。(Guid.NewGuid() は、まだ存在しないランダムな Int128 に似ています)。

Byte (TinyInt)、Int16 (SmallInt)、Int32/UInt16 (Int)、Int64/UInt32 (BigInt) は、変更されない小さなルックアップ リストや、複数のデータベース間で複製されないデータに使用します。(権限、アプリケーション構成、色名など)

GUIDを使用しているかロングを使用しているかに関係なく、インデックス作成にはクエリに同じくらい時間がかかると思います。通常、索引付けされたテーブルには、とにかく 128 ビットより大きい他のフィールドがあります (たとえば、ユーザー テーブル内のユーザー名)。Guid と Integers の違いは、メモリ内のインデックスのサイズと、インデックスの作成と再構築にかかる時間です。多くの場合、データベース トランザクションの大部分は読み取りです。書き込みは最小限です。データベースは通常、適切に最適化されていない結合テーブル、不適切なページング、またはインデックスの欠落で構成されているため、最初にデータベースからの読み取りを最適化することに集中してください。

何事もそうですが、一番いいのは自分の主張を証明することです。2 つのテーブルを持つテスト データベースを作成します。1 つは整数/倍長の主キーを持ち、もう 1 つは GUID を持ちます。それぞれに N-Million 行を入力します。CRUD 操作 (作成、読み取り、更新、削除) 中のそれぞれのパフォーマンスを監視します。パフォーマンスに影響はありますが、重要ではないことに気付くかもしれません。

サーバーは、多くの場合、デバッグ環境や他のアプリケーションが CPU、メモリ、およびハード ドライブの I/O (特に RAID を使用) を占有することなく、ボックス上で実行されます。開発環境では、パフォーマンスのアイデアしか得られません。

于 2009-07-24T21:23:55.867 に答える
1

.NET アプリケーションから順次 GUID を作成することを検討してください。

http://dotnet-snippets.de/dns/sequential-guid-SID998.aspx

標準 Guid と比較して Sequential Guid のパフォーマンスの向上は何ですか?

于 2009-07-26T15:44:26.540 に答える