4

そのため、同僚と私は、GUID である主キーを生成するのにどちらの方法が適しているかについて議論しています。

エンティティ 4 で .NET 4.0 を使用し、ストアド プロシージャを使用して選択/挿入/更新を行っています。

彼は、コードで GUID プライマリ キーを作成し、Guid クラスを使用して、または作成された Sequential GUID クラスを使用して、挿入の一部としてそれを返したいと考えています。

newid() または newsequentialid() のいずれかを使用して、挿入時に SQL Server によって GUID が作成されるようにします。

彼の方法に対する私の主張は、複数の挿入を行う必要がある場合、各挿入の GUID を取得するためにラウンドトリップを行う必要があるため、外部キー制約の関係を維持する必要があるということです。さらに、この方法を使用すると、挿入ごとに数回往復する必要があります。

SQLを使用して行うことについての彼の主張は、挿入が発生する前にキーにアクセスできず、コードの他の部分で使用するために主キーguidを元に戻すために挿入が発生するのを待たなければならないということです。このようにして、ストアド プロシージャへの 1 つの接続を確立し、すべての挿入を処理できます。

では、シングルインサートにはどの方法が適しているのでしょうか? トランザクションでの複数の挿入には、どの方法が適していますか?

4

2 に答える 2

12

GUID は主キーの自然な選択のように思われるかもしれません。どうしても必要な場合は、テーブルの PRIMARY KEY に GUID を使用することをお勧めします。特に使用しないように指示しない限り、SQL Server はデフォルトでこれを行います

2 つの問題を区別する必要があります。

1)主キーは論理構造であり、テーブル内のすべての行を一意かつ確実に識別する候補キーの 1 つです。これは、INT、GUID、文字列など、実際には何でもかまいません。シナリオに最も適したものを選択してください。

2)クラスタリング キー(テーブルの "クラスター化インデックス" を定義する列) - これは物理ストレージに関連するものであり、ここでは、小さくて安定した、増え続けるデータ型が最適です - INTまたは BIGINT をデフォルトのオプションとして使用します。

デフォルトでは、SQL Server テーブルの主キーはクラスタリング キーとしても使用されますが、そうである必要はありません。以前の GUID ベースのプライマリ/クラスター化されたキーを、GUID のプライマリ (論理) キーと、別の INT IDENTITY(1, 1) 列。

インデックス作成の女王であるKimberly Trippや他の人が何度も述べているように、クラスタリング キーとしての GUID は最適ではありません。そのランダム性のために、大量のページとインデックスの断片化が発生し、一般的にパフォーマンスが低下するからです。

はい、私は知っnewsequentialid()ています-SQL Server 2005以降にあります-しかし、それでさえ真に完全にシーケンシャルではなく、GUIDと同じ問題に悩まされています-少し目立たないだけです. GUIDを主張する場合は、少なくともnewsequentialid()サーバーでメソッドを使用してください。

次に、考慮すべき別の問題があります。テーブルのクラスター化キーは、テーブルのすべての非クラスター化インデックスのすべてのエントリにも追加されるため、できるだけ小さくする必要があります。通常、大多数のテーブルには 20 億行以上の INT で十分です。また、クラスタリング キーとしての GUID と比較すると、ディスクとサーバー メモリのストレージを数百メガバイト節約できます。

簡単な計算 - INT と GUID をプライマリおよびクラスタリング キーとして使用:

  • 1'000'000 行のベース テーブル (3.8 MB 対 15.26 MB)
  • 6 つの非クラスター化インデックス (22.89 MB 対 91.55 MB)

合計: 25 MB 対 106 MB - これは 1 つのテーブルでの計算です!

もう少し考えてみましょう - Kimberly Tripp の優れたもの - 読んで、もう一度読んで、消化してください! これは、まさに SQL Server のインデックス作成の福音です。

マルク

于 2011-04-07T15:49:57.560 に答える
1

このような質問があるときは、「SQL Serverはセットが得意なので、得意なことを実行させてください」とか、「1はNの特定のケースにすぎない」と自分に言い聞かせます。

シングルインサートにはどちらの方法が適していますか?

単一の挿入時間は、同期SQL呼び出しのどちらのアプローチでも同じになります。ただし、「彼の」アプローチでは、シークレンのGUIDメソッドがSQLサーバーほど優れていないため、シーク時間の問題がさらに発生します(おそらく、グローバルな一意性が失われます)。また、必然的に複数の挿入を行う必要がある場合は、コードベースが分割されます。

トランザクションでの複数の挿入に適した方法はどれですか?

セットベースの挿入(挿入/選択)と単一行の挿入(挿入)について議論している場合、クライアントへの戻りは高価な部分になるため、セットベースは複数の挿入で勝ちます。

これが私なら、挿入するオブジェクトのシリアル化されたコレクションを取得し、出力句を使用して挿入/選択を行うSPを作成します。このページの「例B.IDと計算列でのOUTPUTの使用」を確認してください。sqlサーバーはGUIDを作成し(スタックしている場合)、クライアントに戻るか、SPで次のステートメントを実行して、挿入によって生成された出力テーブルに基づいて子行を挿入します。

于 2011-04-07T20:09:42.587 に答える