3

これこれを読んでからこれを読んで(皮肉なことに他の2つを参照しています)、このトピックの議論がどれほど大きいのか疑問に思いますか?私はSQLServerの担当者なので、intの形式で自動生成されるIDを使用する傾向があります。ただし、サーバーとサーバー間の何らかの形式のレプリケーション、またはクライアントとサーバー間の同期が必要になることがわかっている場合は、GUIDをキーとして使用する傾向があります。

質問: 将来この可能性のあるスケーラビリティが必要になる可能性がある場合に備えて、すべてのテーブルで常にGUIDを主キーとして使用する必要がありますか?これにより、スキーマをプラットフォーム間でいつでも移行できるという点で、スキーマがより柔軟になりますか?これは、プラットフォーム固有の機能を埋め込まないことで、(フレーバーに関係なく)ORMの柔軟性を維持するのに役立ちますか?

反応:

@David Archer:あなたのコメントに従って、「自然キー」と言わないように投稿を更新しました。自然キーがそのように定義されているという点で、あなたは正しいです。訂正していただきありがとうございます。

4

6 に答える 6

4

私は、アプリケーションで生成された主キーを好む傾向があり、通常は NHibernate によって実装されている lo/hi アルゴリズムを使用します (プロジェクトで使用している場合)。それ以外の場合は、連続した GUID も同様に機能します。これは私だけのアドバイスではなく、この開発全体を私よりもずっと長く行ってきた何人の人々からのアドバイスです。

DB で生成された主キーを使用する際に見られる問題は、データベースに永続化する前にすべてを設定するのではなく、それらの ID 値を取得するためにデータベースにアクセスする必要があることです。通常、この事実により、NHibernate の作業単位パターンも破られます。アプリで UoW パターンを使用していない場合、明らかにこの欠点は当てはまりません。

PK に GUID を使用している場合は、連続した GUID を使用してインデックスの断片化を解消する必要があります。これにより、別のポスターが言及した「大まかな並べ替え順序」も得られますが、通常は DateInserted 列またはそれらの種類のものに類似しています。

GUID 列での結合は、 4 バイト整数と比べてパフォーマンスのオーバーヘッドがかなり小さいことが示されています。大規模でないデータセットの場合、パフォーマンスの違いは些細なことです。

ナチュラル キーは悪魔のスポーンです。:)

于 2009-07-21T01:05:59.657 に答える
3

生の GUID を主キーとして使用しないでください。これを行うと、データが大幅に断片化されます。SQL Server には、この問題を軽減するのに役立つ "シーケンシャル GUID" を提供する機能があります。このトピックに関する詳細な議論がここにあります。それについての別の優れた議論はここにあります...

これは、ランダム GUID の断片化の量が非常に大きいことを示しています (「断片化率」はできるだけゼロに近づけることをお勧めします)。random guid で使用されるページ数は 40% 増加し、各ページで使用されるスペースの量は少なくなるため、必要なディスク スペースが増加します。

于 2009-07-21T00:34:50.210 に答える
2

SQL Serverのクラスター化キーとしてGUIDを使用しないようにする必要があるという点で、他の回答者のほとんどをサポートしています。本当に必要な場合は、GUIDを主キーとして使用できますが、テーブルをクラスター化しないでください。

主キーは、各行を一意に識別するためのキーの論理的な概念です。ここでは、GUIDは一意であることがほぼ保証されているため、意味があります。

ただし、クラスター化されたキーは、テーブル内の行を物理的に順序付ける物理的な概念であり、ここではランダムな性質のため、GUIDはあまり適していません。これにより、インデックス(したがってテーブルデータ)を何度も再編成し続けても、インデックスが大幅に断片化され、パフォーマンスが低下します。

さらに、クラスター化インデックスキーは、テーブル内の行を検索するためのルックアップ値として使用されているため、テーブル上のすべての非クラスター化インデックスのすべてのエントリにも追加されます。ここでは、 GUID(16バイト)とINT(4バイト)が関係します。ルックアップ値を追跡するためだけに多くのスペースを浪費する可能性があります。

私が知っているプラ​​イマリ/クラスター化インデックスとGUIDの最良の議論は、SQLServerランドのインデックス作成の女王であるKimTrippによる2つの記事です-それらをチェックしてください!

クラスター化されたインデックスに対する彼女の最終的な要件は、小さく、安定していて、ユニークで、できれば増え続けることです。GUIDは、そのうちの2つに違反しています(小さく、増え続けています)。SQL ServerのNEWSEQUENTIALGUID()関数によって生成されたGUIDでさえ、完全かつ真にシーケンシャルではないため、これらも使用しません。

マーク

于 2009-07-21T05:12:27.327 に答える
2

主キーの GUIDS は、本当に必要になることがわかっていない限り (つまり、複数システムの同期など)、避けたいと思います。

SQL Server レプリケーションの世界では、一意性を実現するために、レプリケートされたテーブルの行に GUID が追加されるため、必要に応じて後でこの設計を確立することは十分に可能です。

断片化に関しては、ディスク容量のコストも考慮してください。(テーブルで) 10,000 行未満になる場合、これはおそらく大きな問題ではありませんが、システムが (テーブルで) 10,000 行を超える行をサポートする必要がある場合は、パフォーマンスとディスク ストレージのコスト (およびインデックスの断片化) が見つかります。 Big Ints (大きな整数) + ID (自動番号) を使用すると、ボリュームに合わせて適切にスケーリングできます。

私は自然キーを完全に避けたいと思います-それらの周りでロジックが変更されるリスクでさえ、私見ではリスクが高すぎます(たとえば、それらが突然一意でなくなった場合)。

于 2009-07-21T00:50:07.173 に答える
1

「自然キー」を変更したり複製したりして、使用を検討することができないほど、何度も火傷を負いました。キーにシーケンスまたはGUIDを使用するかどうかの決定は、それらの1つを読んだり話したりすることを期待するかどうかによって決まります。

于 2009-07-21T00:33:02.207 に答える
1

私はこれについてあまり経験がありませんでしたが、GUID を使用して参加すると、うんざりします。4 バイト対 36 バイトは厄介なようです。

ただし、ID フィールド自体ではなく、公開識別子として GUID を使用し始めました。上記の URL 1156712 を見てください。何らかの理由で SO を別の同様のアプリケーション (SU など) とマージする必要がある場合、これらの質問 ID はいずれか一方と衝突し、URL を変更してハードコードされたリンクを台無しにする必要があります。グーグル統計も。一方、すべての要素が GUID を使用して公に識別され、内部結合で int フィールドまたは bigint フィールドが使用された場合、両方の長所を活かすことができます。

このアプローチを使用しても、マージは引き続き可能です。競合が見つかった場合、アプリケーションの残りの部分を中断することなく、新しい内部識別子をオンザフライで生成できます。

于 2009-07-21T00:37:24.673 に答える