質問

私はこれまでに数多くのデータベース システムに取り組んできましたが、すべてのデータベース キーが GUID / UUID 価値観。私も何度かこの道をたどることを検討しましたが、特にパフォーマンスや電話で読み上げられない URL に関しては、常に多少の不確実性が伴います。

データベース内の GUID を広範囲に扱った人はいますか?そのようにすることでどのようなメリットが得られるでしょうか?また、考えられる落とし穴は何ですか?

役に立ちましたか?

解決

利点:

  • オフラインで生成できます。
  • レプリケーションを簡単にします (int の場合は非常に困難になります)。
  • ORM は通常好きです
  • アプリケーション全体で一意です。したがって、CMS (guid) からの PK をアプリ (guid も) で使用することができ、衝突が決して起こらないことがわかります。

短所:

  • より広いスペースを使用しますが、スペースは安価です(er)
  • ID で注文して挿入注文を取得することはできません。
  • URL では見苦しく見えるかもしれませんが、実際、URL に REAL DB キーを入れるなんて、いったい何をしているのでしょうか?
  • 手動でデバッグするのは難しくなりますが、それほど難しくはありません。

個人的に、私はまともなサイズのシステムのほとんどの PK にこれらを使用しますが、私はあちこちに複製されたシステムで「訓練」されたので、それらを持たなければなりませんでした。YMMV。

重複データというのはくだらないことだと思います。どうやっても重複データが得られる可能性があります。私がこれまで働いてきたところでは、代理キーはたいてい嫌われます。ただし、WordPress のようなシステムを使用しています。

  • 行の一意の ID (GUID など)。ユーザーには決して表示されません。
  • パブリック ID は、何らかのフィールド (例:タイトル - 記事のタイトルにします)

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

大量のレコードがあり、GUID にクラスター化インデックスがある場合、アイテムのリストの最後 (高速です) ではなく、アイテムのリスト内のランダムな場所 (これが重要です) に挿入が行われるため、挿入のパフォーマンスが低下します。

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

他のヒント

@マット・シェパード:

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

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

次に、何らかの理由 (私には思いつきませんが) で、顧客テーブルに GUID 列を追加し、それを主キーにするように求められます。顧客 ID 列が一意性が保証されないまま放置されている場合、GUID は常に一意であるため、将来的に組織全体に問題が発生することになります。

「建築家」の中には、「ああ、でも私たちは、 本物 私たちのアプリ層には顧客の一意性の制約があります!」右。汎用プログラミング言語と (特に) 中間層フレームワークの流行は常に変化しており、通常、データベースが存続しなくなることはありません。また、ある時点で、現在のアプリケーションを経由せずにデータベースにアクセスする必要が生じる可能性が非常に高くなります。== トラブル。(しかし幸いなことに、あなたと「建築家」はとうの昔に亡くなっているので、混乱を片付けるためにそこにいるわけではありません。) 言い換えると、次のようになります。データベース内 (および時間があれば他の層でも) 明らかな制約を維持してください。

言い換えると:テーブルに GUID 列を追加する正当な理由があるかもしれませんが、それによってテーブル内での一貫性の目標が低下するという誘惑に陥らないようにしてください。 本物 (==非 GUID) 情報。

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

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

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

編集 この質問に対する私の 2 つの回答を統合しました

@Matt Sheppard彼は、主キーとして異なるGUIDを持つ行を複製できることを意味していると思います。これは、GUID だけでなく、あらゆる種類の代理キーの問題です。そして、彼が言ったように、これはキー以外の列に意味のある一意の制約を追加することで簡単に解決できます。別の方法は自然キーを使用することですが、これには大きな問題があります。

GUID が「一意化子」として使用されると、将来、重複したデータがテーブルに入り込む可能性があり、多くの問題が発生する可能性があります。GUID を使用する場合は、他の列でも UNIQUE 制約を維持することを検討してください。

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

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

主キー ID と GUID の比較

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

神話、GUID vs.自動増加 (MySQL 5)

これが本当にあなたが望んでいることです。

UID のプロ

  • すべてのテーブル、すべてのデータベース、すべてのサーバーにわたって一意です
  • 異なるデータベースのレコードを簡単に結合できます。
  • 複数のサーバー間でデータベースを簡単に分散できます。
  • データベースに往復する必要がなく、どこでも ID を生成できます。
  • ほとんどのレプリケーション シナリオではとにかく GUID 列が必要です

GUIDの短所

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

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

RDBM は通常、BTree と呼ばれる大きな分岐係数を持つ検索ツリー (二分探索ツリーの分岐係数は 2) と呼ばれる構造で、主キーの一意性を保証し、キーによる検索を保証します。ここで、連続した整数 ID を使用すると、挿入が発生します。 1つ 木の側面に置き、葉のノードのほとんどをそのまま残します。ランダムな UUID を追加すると、挿入によってインデックス全体のリーフ ノードが分割されます。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top