12

データベース内のエンティティの主キーとして Guid を使用します。伝統的に、INSERT 中にデータベースにエンティティの ID を設定させるパターンに従ってきましたが、これは通常、自動インクリメント フィールドなどを使用して物事を処理する方法であるためだと思います。

オブジェクトの構築中にコードでキー割り当てを行う方がはるかに便利であることがますますわかっています。主な理由は次の 2 つです。

  1. オブジェクトのコンストラクターが実行されると、そのすべてのフィールドが初期化されていることがわかります。「中途半端な」オブジェクトが動き回ることはありません。
  2. 操作のバッチを実行する必要があり、そのうちのいくつかはオブジェクトのキーを知っていることに依存している場合、データベースへのラウンドトリップなしで一度にすべて実行できます。

このように物事を行わないやむを得ない理由はありますか? つまり、Guid をキーとして使用する場合、キーの割り当てをデータベースに任せる正当な理由はありますか?

編集: Guid を PK に使用する必要があるかどうかについて多くの人が強い意見を持っています (私は知っていました) が、それは私の質問のポイントではありませんでした。

クラスタリングの問題 (インデックスを適切に設定すれば問題にはならないようです) を除けば、アプリケーション層でキーを作成しないようにする説得力のある理由は見当たりません。

4

9 に答える 9

5

クライアント側でそれらを作成することで、うまくやっていると思います。あなたが言ったように、データベースにそれをさせた場合、そのキーを取得するための何らかの方法を見つける必要があります (実際には何も考えられません)。アイデンティティを使用していた場合、テーブル用に作成された最新のものを取得するために使用できる呼び出しがありますが、そのようなものが GUID 用に存在するかどうかはわかりません。

于 2009-01-30T18:44:44.087 に答える
4

C# でこれを行うと、GUID を再割り当てしてデータベースに保存し直すリスクが生じる可能性があります。データベースに責任を持たせることで、この PK が変更されないことが保証されます。つまり、適切な制約を設定した場合です。そうは言っても、割り当てられた一意のIDを変更できないようにC#コードに同様の制約を設定できますが、すべてのアプリケーションで同じことを行う必要があります...私の意見では、C#でそれを持っていますデータベースには主キーの変更を防ぐメソッドがすでに組み込まれているため、データベースよりもメンテナンスが多いように思えます。

于 2009-01-30T18:44:53.087 に答える
2

興味深い質問です。

従来、私もDB割り当てのGUIDを使用していましたが、最近はWindows Mobileアプリケーションで作業しており、SQL CEデータベースではnewguidが許可されていないため、コードで実行する必要がありました。

SQLレプリケーションを使用して、モバイルデバイスからサーバーにデータを取得します。過去6か月間、40のSQL CEクライアントが、1つのGUIDを見逃したり複製したりすることなく、100000を超えるレコードをSQL2005サーバーに同期して戻しました。

必要な追加のコーディングはごくわずかであり、挿入する前にGUIDを知っていることの利点により、実際には複雑さの一部が軽減されています。

私はパフォーマンスチェックを行っていないので、パフォーマンスは別として、あなたが提案するようにGUID処理を実装しない理由はわかりません。

于 2009-01-30T21:07:26.343 に答える
1

GUIの外部で挿入を行う必要がある場合(別のベンダーからのインポートまたは購入した会社からのデータを考えて、データとマージする必要がある場合)、GUIDは自動的に割り当てられません。それは克服できない問題ではありませんが、それでも考慮すべきことです。

于 2009-01-30T21:05:46.360 に答える
1

GUID はパフォーマンスにとって恐ろしいものです

特に、SQL Server にNEWSEQUENTIALID()があり、値がランダムであるため、挿入時にページ分割が発生しないため、データベースに残します。デフォルト値としてのみ使用できます

于 2009-01-30T18:45:16.317 に答える
0

SQLMenace が指摘したように、標準の GUID はインデックス作成とページングに悪影響を及ぼします。C# では、少しの P/Invoke fun を使用して NEWSEQUENTIALID() のようなシーケンシャル GUID を生成できます。

[DllImport("rpcrt4.dll", SetLastError = true)]
static extern int UuidCreateSequential(out Guid guid);

このようにして、少なくとも GUID を使い続けることができますが、GUID を生成する方法と場所をより柔軟に設定できます。

于 2009-01-30T21:23:29.307 に答える
0

では、時間です。GUID をクライアント側で生成してデータベースに保存するのが最善の方法であると言えます。ただし、たまたま GUID を PK として使用している場合は、次の 1 つのシナリオでのみお勧めします。環境。

データの伝播に非接続モデルを使用している場合 (つまり、PDA/携帯電話アプリ、限られた接続シナリオ向けのラップトップ アプリなど)、クライアント側で生成された PK としての GUID が最適な方法です。

他のすべてのシナリオでは、自動インクリメント ID PK を使用したほうがよいでしょう。

なんで?いくつかの理由があります。まず、行にまたがるクラスター化された PK インデックスを使用すると、パフォーマンスが大幅に向上します。GUID PK とクラスター化されたインデックスはうまく連携しません。NEWSEQUENTIALID を使用しても、GUID の要点を完全に見逃していると思います。第 2 に、状況が強制されない限り (つまり、切断されたモデルを使用する必要がある場合)、すべてをトランザクションのままにして、相互に関連するデータを同時にできるだけ多く挿入する必要があります。

于 2009-01-30T21:52:18.747 に答える
0

クラスタリングの問題 (インデックスを適切に設定すれば問題にはならないようです) は別として、

インデックスとしての GUID は常にひどく乱雑になります。それを回避するための「適切な」セットアップはありません (SQL Server エンジンで NEWSEQUENTIALGUID 関数を使用しない限り)。

IMHO の最大の欠点はサイズです。GUID は 16 バイト、INT は 4 です。PK は、主キーのツリーに格納されるだけでなく、すべての非クラスター化インデックス エントリにも格納されます。

数千のエントリでは大きな違いはないかもしれませんが、数百万または数十億のエントリといくつかの非クラスター化インデックスを含むテーブルがある場合、PK として 16 バイトの GUID と 4 バイトの INT を使用すると、必要なスペースの大きな違い - ディスク上と RAM 内。

マルク

于 2009-01-31T09:29:42.460 に答える