web-dev-qa-db-ja.com

INTと一意-データベースのIDフィールドの識別子

SQL Server 2005(近い将来SQL Server 2008の可能性があります)を使用して、Webサイト用の新しいデータベースを作成しています。アプリケーション開発者として、関係に使用されるテーブルのIDフィールドにinteger(またはbigintなど)を使用する多くのデータベースを見てきました。しかし最近、IDフィールドにunique identifierGUID)を使用するデータベースも見ました。

私の質問は、一方が他方よりも有利であるかどうかです。 integerフィールドは、クエリや結合などで高速になりますか?

PDATE:明確にするために、これはテーブルの主キー用です。

32
mkchandler

GUIDはランダム性が高いため、クラスター化されたキーとして問題があります。この問題は、前回のTechnet MagazineのQ&AコラムでPaul Randalによって対処されました: クラスター化インデックスキーとしてGUIDを使用したいのですが、他の人はそれができると主張していますインデックスのパフォーマンスの問題につながります。これは本当ですか。もしそうなら、その理由を説明できますか?

ここで、議論は特にclusteredインデックスについてであることに注意してください。列を「ID」として使用したいとしますが、それがクラスター化されたキーなのか、単に主キーなのかは不明です。通常、この2つは重複しているため、クラスター化インデックスとして使用することを想定しています。それが悪い選択である理由は、私が上で述べた記事へのリンクで説明されています。

非クラスター化インデックスの場合、GUIDにはまだいくつかの問題がありますが、テーブルの左端のクラスター化キーである場合ほど大きくはありません。繰り返しになりますが、GUIDのランダム性により、非クラスター化インデックスレベルのみであるかどうかにかかわらず、ページの分割と断片化が発生します(はるかに小さな問題)。

GUIDの使用法を取り巻く多くの都市伝説があり、int(4バイト)と比較してサイズ(16バイト)に基づいて非難し、使用すると恐ろしいパフォーマンスを約束します。これはわずかです。誇張されています。サイズ16のキーは、適切に設計されたデータモデルでは、非常にパフォーマンスの高いキーになる可能性があります。intの4倍の大きさであると、密度の低い非リーフが増えることは事実です。インデックスのページ、これは大多数のテーブルにとって実際の懸念事項ではありません。b-tree構造は、自然にバランスの取れたツリーであり、ツリーのdepthです。トラバーサルが問題になることはめったにないため、INTキーではなくGUIDキーに基づいて値を探す)のパフォーマンスは似ています。リーフページのトラバーサル(つまり、テーブルスキャン)では、非リーフページ、およびGUIDサイズがページサイズに与える影響は、レコード自体がGUIDによって導入された余分な12バイトよりも大幅に大きいため、通常は非常に小さいです。 dヒアリングアドバイスに基づいてon 'は16バイト対4'で、かなり大きな塩の粒があります。個々のケースバイケースで分析し、サイズの影響が実際の違いをもたらすかどうかを判断します。テーブル内のother列の数(つまり、GUIDリーフページのサイズ)およびそれを使用している参照の数(つまり、より大きな外部キーを格納する必要があるため、otherテーブルの数が増加しますキー)。

GUIDは最近多くの悪い報道を受けており、一部はそれに値しないため、私はGUIDのある種の間に合わせの防御でこれらすべての詳細を呼び出しています。それらにはメリットがあり、あらゆる分散システムに不可欠です(データの移動について話している瞬間、レプリケーションや同期フレームワークなどを介して)。 GUID適切な考慮なしに回避されたときの悪い評判に基づいて悪い決定が下されるのを見てきました。しかし、本当です、使用する必要がある場合a GUIDクラスター化されたキーとして、ランダム性の問題に対処していることを確認してください。可能な場合は順次GUIDを使用してください。

そして最後に、あなたの質問に答えるために:GUIDを使用する特定の理由がない場合は、INTを使用してください。

52
Remus Rusanu

GUIDは、newsequentialid()関数を使用している場合でも、より多くのスペースを占有し、intよりも遅くなります。レプリケーションを実行する場合、または同期フレームワークを使用する場合は、ほとんどGUIDを使用する必要があります。

8
JBrooks

INTは4バイト、BIGINTは8バイト、GUIDSは16バイトです。データを表すために必要なスペースが多いほど、データを処理するために必要なリソース(ディスクスペース、メモリなど)も多くなります。したがって、(a)速度は遅くなりますが、(b)これはおそらくボリュームが問題である場合にのみ問題になります(行、または非常に短い時間で数千のトランザクション。)

GUIDの利点は、(ほぼ)グローバルに一意であるということです。適切なアルゴリズムを使用してGUIDを生成します(SQL Server xxxxは適切なアルゴリズムを使用します)。2つのGUIDが同じになることはありません。生成するコンピューターの数に関係なく、頻度に関係なく。 (これは72年の使用後は適用されません-詳細を忘れています。)

複数のサーバー間で生成された一意の識別子が必要な場合は、GUIDが役立つ場合があります。モンドのパフォーマンスと20億未満の値が必要な場合は、intで十分です。最後に、そしておそらく最も重要なことは、データに自然キーがある場合は、それらに固執し、代理値を忘れることです。

6
Philip Kelley

積極的に、絶対に一意のIDを持っている必要がある場合は、GUIDを使用してください。つまり、マージ、同期、複製を行う場合は、おそらくGUIDを使用する必要があります。

堅牢性の低いものについては、テーブルがどれだけ大きくなるかに応じて、intで十分です。

ほとんどの場合のように、正しい答えは、それは異なります。

4
Jack Marchetti

レプリケーションなどに使用しますnotを主キーとして使用します。

キンバリーLトリップの記事

  • に対して:スペース、厳密には単調ではない、ページ分割、ブックマーク/ RIDなど
  • のために:えー...
3
gbn

JBrooksに完全に同意しました。テーブルが大きく、JOINSでselectを使用する場合、特に派生テーブルで使用する場合、GUIDを使用するとパフォーマンスが大幅に低下する可能性があることを言いたいと思います。

2
Alex_L