web-dev-qa-db-ja.com

GUID vs INT-主キーとしてどちらが良いですか?

Guidintを使用する理由と使用しない理由について読んでいます。

intは小さく、高速で、覚えやすく、時系列を維持します。そして、Guidに関しては、私が見つけた唯一の利点は、それがユニークであることです。どちらの場合にGuidintより優れているのか、そしてその理由は?

私が見てきたことから、intには、多くの場合は無関係である数の制限を除いて、欠陥はありません。

なぜ正確にGuidが作成されたのですか?実際には、単純なテーブルの主キーとして機能する以外の目的があると思います。 (何かのためにGuidを使用する実際のアプリケーションの例はありますか?)

(Guid = UniqueIdentifier)SQL Serverのタイプ

107
BrunoLM

これはスタックオーバーフロー here および here で要求されています。

ジェフの投稿 は、GUIDの使用の長所と短所について多く説明しています。

GUIDプロ

  • すべてのテーブル、すべてのデータベース、すべてのサーバーで一意
  • 異なるデータベースのレコードを簡単にマージできます
  • 複数のサーバーにデータベースを簡単に分散できます
  • データベースへのラウンドトリップを行わずに、どこでもIDを生成できます
  • ほとんどのレプリケーションシナリオでは、とにかくGUID列が必要です

GUIDの短所

  • これは、従来の4バイトのインデックス値の4倍です。注意しないと、パフォーマンスとストレージに深刻な影響を与える可能性があります
  • デバッグが面倒(_where userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}'_)
  • 生成されたGUIDは、最高のパフォーマンス(SQL Server 2005以降ではnewsequentialid()など)を実現し、クラスター化インデックスの使用を可能にするため、部分的にシーケンシャルである必要があります

パフォーマンスについて確信があり、レコードを複製またはマージする予定がない場合は、intを使用して、SQL Serverで自動シード(identity seedを設定します)。

94
CoderHawk

データを外部ソースと同期している場合は、永続的なGUIDの方がはるかに良い場合があります。GUIDを使用している簡単な例は、顧客に送信されるツールです。ネットワークをクロールし、特定のクラスの自動検出を実行し、見つかったレコードを保存します。その後、すべての顧客レコードが中央のデータベースに統合されます。整数を使用した場合、7,398 "1"、どの "1"がどれであるかを追跡するのはかなり困難です。

19
TML

私はハイブリッドアプローチを使用して成功しています。テーブルには、自動インクリメントの主キー整数id列とguid列の両方が含まれています。 guidは、必要に応じて行をグローバルに一意に識別するために使用でき、idは、クエリ、並べ替え、および行の人間による識別に使用できます。

18
rmirabelle

いくつかのベストプラクティスでは、使用する値のセット全体を可能な限り少ないメモリで収容できるデータ型を使用する必要があるとまだ言及されています。たとえば、中小企業の雇用者の数を格納するためにそれを使用していて、100に到達する可能性が低い場合、int(smallintでも)がそうである一方でbigint値の使用を提案する人は誰もいません。

もちろん、これの欠点は「スケーラビリティについてはノーと言ってください!」のようなものです。


また、これは完全に関連しているわけではありませんが、これには別の要因があります。過度でない場合、私は通常、自動生成されていない主キーを使用することを推奨します(意味がある場合)。たとえば、ドライバーの情報を保存する場合は、「ID」の自動生成列を新たに作成する必要はありません。ライセンス番号を使用してください。

当たり前のことのように聞こえますが、忘れられがちです。

コンテキストについて:回答のこの部分は、データの理論的なアプローチから対処されました。このアプローチでは、PKをレコードの一意のデータ識別子にする必要があります。ほとんどの場合、それらが既に存在するときに作成するため、前の回答です。

ただし、これらのデータポイントを厳密に制御できることは非常にまれであるため、修正や調整が必要になる場合があります。主キーではこれを行うことはできません(まあ、できますが、苦痛になることもあります)。

明確化のために@VahiDに感謝します。

1
Alpha

自動インクリメントIDを使用すると、ビジネスアクティビティに関する情報が漏洩する可能性があります。ショップを運営していて、order_id購入を公に特定すると、誰でも簡単な計算で毎月の販売数を知ることができます。

1
golopot

上記の@rmirrabelleの回答- https://dba.stackexchange.com/a/96990/118371 は私がすることです。ただし、より大規模なプロジェクトには、究極の設計があります。

使用:キーマッピングテーブル

TableA

- ID int (PK)
- Data varchar(100)

TableAMap

- ID int (PK)
- UniversalID GUID (Indexed - nonclustered)

他のスレッドがこのスレッドで説明したように、GUIDがデータベースの複製/インポート/エキスポートに必要になることはほとんどありません。したがって、GUIDがメインテーブルにある代わりに、1行あたり8バイト余分にかかり、GUIDインデックスは(デフォルトでは)同じボリュームに保存され、別のテーブル(別名正規化)が役に立ちます。

別個のテーブルを使用すると、DBAは別の遅いディスクに自由にテーブルを格納できます。また、GUIDが特定のバッチジョブでのみ必要な場合は、必要な直前にGUIDインデックスを作成し、後で削除することができます。

0
Todd

GUIDの生成方法に関するもう1つのこと。 mrdennyは、newsequentialid()が使用されている場合でも、インスタンスを再起動すると新しい値が前の処理で残された「ホール」から始まることを正しく指摘しました。 「順次」GUIDに影響を与えるもう1つのものは、ネットワークカードです。私が正しく覚えている場合、NICのUIDはGUIDアルゴリズムの一部として使用されます。NICが置き換えられたものであり、UIDが物事のシーケンシャルな側面を維持するためにより高い値になるという保証はありません。また、アルゴリズムを使用した値の割り当てに複数のNICがどのように影響するかもわかりません。

ただ考えて、私は正しく覚えていることを願っています。すてきな一日を!

0
bobo8734