私のアプリケーションコードでは、これを使用してGUIDを生成しSystem.Guid.NewGuid()
、SQLサーバーDBに保存しています。
GUIDの生成に関していくつか質問があります。
- プログラムを実行したとき、パフォーマンスの点でこれに問題は見つかりませんでしたが、GUIDを生成する他のより良い方法があるかどうかを知りたいと思いました。
System.Guid.NewGuid()
これが.NETコードでGUIDを作成する唯一の方法ですか?
私のアプリケーションコードでは、これを使用してGUIDを生成しSystem.Guid.NewGuid()
、SQLサーバーDBに保存しています。
GUIDの生成に関していくつか質問があります。
System.Guid.NewGuid()
これが.NETコードでGUIDを作成する唯一の方法ですか?によって生成されたGUIDは、SQLServerのGuid.NewGuid
並べ替え順序に従ってシーケンシャルではありません。これは、インデックスにランダムに挿入していることを意味します。これはパフォーマンスの低下につながります。書き込みボリュームが十分に小さい場合は、問題にならない可能性があります。
SQL ServerNEWSEQUENTIALGUID()
関数を使用してシーケンシャルなものを作成することも、intを使用することもできます。
GUIDを生成する別の方法の1つ(私はあなたのPKだと思います)は、テーブルの列を次のように設定することです。
create table MyTable(
MyTableID uniqueidentifier not null default (newid()),
...
このように実装するということは、それらを.Netに設定するか、SQLに設定させるかを選択できることを意味します。
しかし、どちらも「より良い」または「より速い」とは言えません。
質問に答えるには:
.netのSystem.Guid.NewGuid()よりも優れたGUID作成オプションはありますか?
System.Guid.NewGuid()が好ましい選択だと思い切って言います。
しかし、フォローアップの質問については:
...これをSQLサーバーDBに保存します。
答えはあまり明確ではありません。これは長い間ウェブ上で議論されてきました。Googleの「主キーとしてのGUID 」だけで、何時間も読むことができます。
通常、SQLサーバーでGuidを使用する場合、それはテーブルの主キーとして使用するためです。これには多くの優れた利点があります。
ただし、重大な欠点もあります。
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つの可能な回避策です。
NewGuid
一般的に推奨される方法です。シーケンシャル値が必要な場合を除き、その場合はrpcrt関数UuidCreateSequentialをP/Invokeできます。
Private Declare Function UuidCreateSequential Lib "rpcrt4.dll" (ByRef id As Guid) As Integer
(申し訳ありませんが、VBからニックネームが付けられています。必要に応じて、C#または他の.NET言語に変換できることを確認してください)。