GUID / UUIDデータベースキーの利点と欠点


222

私は過去にいくつかのデータベースシステムで作業しましたが、すべてのデータベースキーがGUID / UUID値であった場合、データベース間でのエントリの移動がはるかに簡単になりました。この方法を何度か検討したことがありますが、特にパフォーマンスと電話で読み込めないURLに関しては、常に多少の不確実性があります。

誰かがデータベースのGUIDを広範囲に使用しましたか?そのようにするとどのような利点が得られますか。また、起こりうる落とし穴は何ですか。


1
Jeffがそれについて投稿した「主キー:IDとGUID」です。
jfs 2008

1
また、リモートクライアントのためのハイローを使用することができます。stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm
ニール・マクギガン


主キー:IDとGUID」に関するJeff Atwoodの投稿の場所を更新しました。参考のために@jfsに感謝します。
アダムKatz

@jfsリンクがblog.codinghorror.com/primary-keys-ids-versus-guidsに変更されました
cr0ss

回答:


229

利点:

  • オフラインで生成できます。
  • レプリケーションをささいなことにします(intとは対照的に、これは本当に困難にします)
  • ORMは通常それらのようです
  • アプリケーション全体で一意です。したがって、アプリ(GUID)でCMS(GUID)のPKを使用でき、衝突が発生することはありません。

短所:

  • スペースをより広く使用しますが、スペースは安くなります。
  • 挿入順序を取得するためにIDで注文することはできません。
  • URLは見苦しく見えますが、実際には、WTFはREAL DBキーをURLに挿入していますか?(この点は、以下のコメントで論争されています)
  • 手動でのデバッグは難しくなりますが、それほど難しくはありません。

個人的には、適切なサイズのシステムでほとんどのPKに使用していますが、あちこちに複製されたシステムで「トレーニング」を受けたので、必要でした。YMMV。

重複データのことはゴミだと思います-あなたがそれをやっても重複データを得ることができます。サロゲートキーは、通常、私がこれまで作業してきた場所にはありません。ただし、WordPressのようなシステムを使用します。

  • 行の一意のID(GUID /その他)。ユーザーには表示されません。
  • 公開IDは一部のフィールドから一度だけ生成されます(例:タイトル-記事のタイトルにする)

更新: したがって、これは+1されているため、GUID PKの大きな欠点、つまりクラスター化インデックスを指摘する必要があると思いました。

多数のレコードがあり、GUIDにクラスター化インデックスがある場合、アイテムのリスト(つまり、ポイント)のランダムな場所に挿入が行われるため、挿入のパフォーマンスが低下します(これはポイントです)。

したがって、挿入パフォーマンスが必要な場合は、おそらくauto-inc INTを使用し、他の人と共有したい場合はGUIDを生成します(つまり、URLでユーザーに表示します)。


184
[WTFはREAL DBキーをURLに入れていますか?]なぜそれがあなたを困らせるのか分かりません。他に何を使いますか?スタックオーバーフローを見てください... URL内のIDENTITY値がいたるところにあり、問題なく動作します。URLでDBキーを使用しても、セキュリティを強化できます。
ユーロミセリ2008

20
いいえ、そうではありませんが、SEOのようなものは、キーがなければ、通常は特に優れています。もちろん、これは簡単に回避できるので、それは少々過剰な発言だったと思います
Nic Wise

7
良い答えです。GUIDを使用した場合のパフォーマンス上の不利な点に関する情報も追加するとよいでしょう。たとえば、それらによる結合、並べ替え、およびインデックス付けは、すべて整数を使用するよりも遅くなります。GUIDは素晴らしいですが、パフォーマンスが非常に重要な場合には手間がかかります。
ジョーンズ博士、

26
一つのことを覚えておいてください、人々はしばしばページ、質問、フォーラムのタイトルを変更します。SEOの場合、URLに小さなIDのようなものを含めるのは良いことです。これにより、タイトルが変更された場合でも、古いURLから来た人々をどこに転送するかがわかります。example.com/35/old-and-bustedちょうどになったexample.com/35/new-hotnessあなたがしているアプリは、単にタイトルをチェックして、301で上のユーザーを転送することができます
Xeoncross

9
GUIDのインデックス作成はコストがかかり、時間がかかるため、主キーの候補としては非常に貧弱です。
マシュージェームスデイビス

14

@マット・シェパード:

顧客のテーブルがあるとします。顧客がテーブルに2回以上存在することは望ましくありません。そうしないと、販売部門と物流部門全体で多くの混乱が発生します(特に、顧客に関する複数の行に異なる情報が含まれている場合)。

そのため、顧客を一意に識別する顧客IDがあり、そのIDが(請求書で)顧客に知られていることを確認して、顧客と顧客サービス担当者が通信する必要がある場合に共通の参照を利用できるようにします。重複する顧客レコードがないことを保証するには、顧客識別子の主キーまたは顧客識別子列のNOT NULL + UNIQUE制約を使用して、一意性制約をテーブルに追加します。

次に、なんらかの理由で(私には考えられません)、GUIDテーブルを顧客テーブルに追加して、それを主キーにするように求められます。一意性保証なしで顧客ID列が残っている場合、GUIDは常に一意であるため、組織全体で今後のトラブルを求めています。

一部の「アーキテクト」は、「ああ、しかし私たちはアプリ層で実際の顧客の一意性の制約を処理します!」と言うかもしれません。正しい。その汎用プログラミング言語と(特に)中間層フレームワークに関するファッションは常に変化しており、一般的にデータベースが長持ちすることはありません。そして、ある時点で、現在のアプリケーションを経由せずにデータベースにアクセスする必要がある可能性が非常に高くなります。==トラブル。(しかし、幸いにも、あなたと「アーキテクト」はもうなくなっているので、混乱を解消するためにそこにいることはありません。)言い換えれば、データベース(および他の層)にも明らかな制約を維持します。時間)。

言い換えると、GUID列をテーブルに追加することには十分な理由があるかもしれませんが、実際の(==非GUID)情報内で一貫性を保つための野心を低くする誘惑に負けないでください。


1
聞いて聞いて!SQL比較ページが大好きです。非常に便利です。私が見落としているのは、変更ログだけです。
Henrik Gustafsson

3
私はこの回答にはいくつかの説明が必要だと思います。これはUUIDが主キーとして使用されないことを前提としています。この仮定がどこから来たのかはわかりませんが、それをそのままでは使用できないシステムはまだ見ていません。私はそれが古い答えであることを知っています。分散システムでUUIDを使用することの利点は、当時はそれほど広く理解されていなかったと思います(?)
2014年

12

なぜ誰もパフォーマンスについて言及しないのですか?複数の結合がある場合、すべてこれらの厄介なGUIDに基づいて、パフォーマンスはフロアを通過します:(


1
UUID(または同様の)を導入する必要がある状況で、これについて詳しく説明できますか?しかし、それらを主キーとして使用することについて心配しています。
JoeTidee

1
UUIDは整数のサイズの4倍です...(データベースにUUIDタイプがある場合)
Jasen

11

GUIDを "uniqifiers"として使用すると、GUIDが将来的に多くの問題を引き起こす可能性があり、重複したデータがテーブルに入る可能性があります。GUIDを使用する場合は、他の列のUNIQUE制約を維持することを検討してください。


11
これが問題の核心です。GUIDを導入すると、どの行も一意になります。しかし、行の非人工部分に突然重複(真実のいくつかのバージョン)が含まれる場合があります。
Troels Arvin

8
+1して補正します。私はあなたが何を意味するかを理解していますが、それはひどく表現されています。
Stefano Borini、

11

主な利点は、データベースに接続せずに一意のIDを作成できることです。また、IDはグローバルに一意であるため、さまざまなデータベースのデータを簡単に組み合わせることができます。これらは小さな利点のように見えますが、以前は多くの作業を節約できました。

主な短所は、もう少し多くのストレージが必要なこと(最新のシステムでは問題ではない)であり、IDは実際には人間が読めるものではありません。これはデバッグ時に問題になる可能性があります。

インデックスの断片化など、いくつかのパフォーマンスの問題があります。しかし、それらは簡単に解決できます(jimmy nillsonによる櫛のガイド:http : //www.informit.com/articles/article.aspx? p=25862 )

編集は、この質問に対する私の2つの答えをマージしました

@マットシェパード彼は、異なるGUIDを持つ行を主キーとして複製できることを意味すると思います。これは、GUIDだけでなく、あらゆる種類の代理キーの問題です。そして、彼が言ったように、それは非キー列に意味のある一意の制約を追加することによって簡単に解決されます。代わりの方法は自然キーを使用することであり、実際の問題があります。


Comb GUIDについて知っています。それらはインデックス作成(INSERTパフォーマンス)の問題を解決するのに役立ちます。「主な欠点は、もう少しストレージが必要になることです」これは、データベースファイルのサイズが大きいため、パフォーマンスに影響しますか?
Amit Joshi

8

その列をクラスター化インデックスとしても使用している場合(比較的一般的な方法)、GUIDSを主キーとして使用する場合に考慮すべきもう1つの小さな問題。いずれにしてもGUIDがシーケンシャルに開始されないため、挿入時にヒットします。挿入すると、ページ分割などになります。システムのIOが高くなる場合に考慮すべきこと...


6

主キーID対GUID

主キーとしてのGUIDのコスト(SQL Server 2000)

神話、GUIDと自動インクリメント(MySQL 5)

これは本当にあなたが望むものです。

UIDプロ

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

GUIDの短所

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

1

本当に対処されていないことが1つあります主キーとしてランダム(UUIDv4)IDを使用すると、主キーインデックスのパフォーマンスが低下します。テーブルがキーの周りにクラスター化されているかどうかに関係なく発生します。

RDBMは通常、主キーの一意性を確保し、BTreeと呼ばれる構造でキーによる検索を保証します。BTreeは、大きな分岐係数を持つ検索ツリーです(バイナリ検索ツリーの分岐係数は2です)。さて、シーケンシャルな整数のIDだけで発生するのインサートを引き起こす1手付かずのリーフノードのほとんどを残して、木の側面を。ランダムなUUIDを追加すると、挿入によってリーフノードがインデックス全体で分割されます。

同様に、保存されたデータがほとんど一時的なものである場合、最新のデータにアクセスして結合する必要がある場合がよくあります。ランダムなUUIDを使用すると、パターンはこれによる恩恵を受けず、より多くのインデックス行にヒットするため、メモリ内により多くのインデックスページが必要になります。順次IDを使用すると、最新のデータが最も必要とされる場合、ホットインデックスページに必要なRAMが少なくなります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.