0

私のアプリケーションコードでは、これを使用してGUIDを生成しSystem.Guid.NewGuid()、SQLサーバーDBに保存しています。

GUIDの生成に関していくつか質問があります。

  1. プログラムを実行したとき、パフォーマンスの点でこれに問題は見つかりませんでしたが、GUIDを生成する他のより良い方法があるかどうかを知りたいと思いました。
  2. System.Guid.NewGuid()これが.NETコードでGUIDを作成する唯一の方法ですか?
4

4 に答える 4

5

によって生成されたGUIDは、SQLServerのGuid.NewGuid並べ替え順序に従ってシーケンシャルではありません。これは、インデックスにランダムに挿入していることを意味します。これはパフォーマンスの低下につながります。書き込みボリュームが十分に小さい場合は、問題にならない可能性があります。

SQL ServerNEWSEQUENTIALGUID()関数を使用してシーケンシャルなものを作成することも、intを使用することもできます。

于 2012-06-29T14:12:38.733 に答える
2

GUIDを生成する別の方法の1つ(私はあなたのPKだと思います)は、テーブルの列を次のように設定することです。

create table MyTable(
    MyTableID uniqueidentifier not null default (newid()),
...

このように実装するということは、それらを.Netに設定するか、SQLに設定させるかを選択できることを意味します。

しかし、どちらも「より良い」または「より速い」とは言えません。

于 2012-06-29T14:12:01.823 に答える
2

質問に答えるには:

.netのSystem.Guid.NewGuid()よりも優れたGUID作成オプションはありますか?

System.Guid.NewGuid()が好ましい選択だと思い切って言います。

しかし、フォローアップの質問については:

...これをSQLサーバーDBに保存します。

答えはあまり明確ではありません。これは長い間ウェブ上で議論されてきました。Googleの「主キーとしてのGUID 」だけで、何時間も読むことができます。

通常、SQLサーバーでGuidを使用する場合、それはテーブルの主キーとして使用するためです。これには多くの優れた利点があります。

  • データベースにアクセスせずに新しい値を簡単に生成できます
  • ローカルで生成されたGUIDが主キーの衝突を引き起こさないことを合理的に確信できます

ただし、重大な欠点もあります。

  • 主キーがクラスター化インデックスでもある場合、大量の新しい行を挿入すると、多くのIO(ディスク操作)とインデックスの更新が発生します。
  • Guidは、代理キーの他の一般的な代替手段であるintと比較して非常に大きくなります。テーブル上の他のすべてのインデックスにはクラスター化インデックスキーが含まれているため、GUIDとintを使用すると、インデックスの成長がはるかに速くなります。
  • これらのインデックスはより多くのメモリを必要とするため、これもより多くのIOを引き起こします

IOの問題を軽減するために、SQL Server 2005では新しいNEWSEQUENTIALGUID()関数が導入されました。この関数を使用して、新しい行を挿入するときにシーケンシャルGUIDを生成できます。しかし、それを使用しようとしている場合は、データベースを生成するためにデータベースに接続する必要があるため、オフラインでデータベースを生成する可能性が失われます。この状況でも、通常のGUIDを生成して使用できます。

独自のシーケンシャルGUIDをロールする方法についての記事もWeb上にたくさんあります。1つのサンプル:

http://www.codeproject.com/Articles/388157/GUIDs-as-fast-primary-keys-under-multiple-database

私はそれらのどれもテストしていないので、それらがどれほど優れているかを保証することはできません。興味深いかもしれないいくつかの情報が含まれているので、私はその特定のサンプルを選びました。具体的には:

Microsoft SQL Serverの1つの偏心は、最下位6バイト(つまり、Data4ブロックの最後の6バイト)に従ってGUID値を並べ替えることであるため、さらに複雑になります。したがって、SQL Serverで使用するシーケンシャルGUIDを作成する場合は、シーケンシャル部分を最後に配置する必要があります。他のほとんどのデータベースシステムは、最初にそれを必要とします。

編集:問題はバルクコピーを使用して大量のデータを挿入することに関するものと思われるため、シーケンシャルGUIDがおそらく必要になります。挿入する前にGUID値を知る必要がない場合は、JonEgertonによる回答問題を解決するための1つの良い方法になります。事前にGUID値を知る必要がある場合は、挿入時に使用する順次GUIDを生成するか、回避策を使用する必要があります。

考えられる回避策の1つは、シードされたINTを主キー(およびクラスター化インデックス)として使用し、Guid値を一意のインデックスを持つ個別の列として使用するようにテーブルを変更することです。Guidを挿入すると、シードされたintがクラスター化されたインデックスになる間、Guidが提供されます。その後、行が連続して挿入され、生成されたGuidは、後でレコードをフェッチするための代替キーとして引き続き使用できます。これが実行可能な解決策であるかどうかはわかりませんが、少なくとも1つの可能な回避策です。

于 2012-06-29T14:52:45.087 に答える
0

NewGuid一般的に推奨される方法です。シーケンシャル値が必要な場合を除き、その場合はrpcrt関数UuidCreateSequentialをP/Invokeできます。

Private Declare Function UuidCreateSequential Lib "rpcrt4.dll" (ByRef id As Guid) As Integer

(申し訳ありませんが、VBからニックネームが付けられています。必要に応じて、C#または他の.NET言語に変換できることを確認してください)。

于 2012-06-29T14:17:51.663 に答える