GUIDは、主キーの自然な選択のように思われるかもしれません。本当に必要な場合は、テーブルの主キーにGUIDを使用することを主張することもできます。 やらないことを強くお勧めします GUID列をクラスタリングキーとして使用します 、特に指定しない限り、SQLServerはデフォルトで実行します。
本当に2つの問題を区別する必要があります:
-
主キー は論理構造であり、テーブル内のすべての行を一意かつ確実に識別する候補キーの1つです。これは実際には何でもかまいません-
INT
、GUID
、文字列-シナリオに最も適したものを選択してください。 -
クラスタリングキー (テーブルの「クラスター化インデックス」を定義する1つまたは複数の列)-これは物理的 ストレージ関連のことですが、ここでは、小さくて安定した、増え続けるデータ型が最適です-
INT
またはBIGINT
デフォルトオプションとして。
デフォルトでは、SQL Serverテーブルの主キーはクラスタリングキーとしても使用されますが、そのようにする必要はありません。以前のGUIDベースのプライマリ/クラスター化キーを2つの別個のキー(GUIDのプライマリ(論理)キーと別個のINT IDENTITY(1,1)
列。
キンバリー・トリップ(インデックス作成の女王)や他の人たちが何度も述べているように、GUID
クラスタリングキーは最適ではないため、ランダムであるため、ページとインデックスの断片化が大きくなり、一般的にパフォーマンスが低下します。
はい、わかっています-newsequentialid()
があります SQL Server 2005以降では、それでも完全にシーケンシャルではないため、GUID
と同じ問題が発生します。 -少し目立たないように。
次に、考慮すべき別の問題があります。テーブルのクラスタリングキーは、テーブルのすべての非クラスター化インデックスのすべてのエントリにも追加されます。したがって、可能な限り小さいことを確認する必要があります。通常、INT
GUID
と比較すると、大多数のテーブルには20億行以上で十分です。 クラスタリングキーとして、ディスクとサーバーメモリに数百メガバイトのストレージを節約できます。
クイック計算-INT
を使用 対GUID
プライマリキーおよびクラスタリングキーとして:
- 1'000'000行のベーステーブル(3.8MB対15.26MB)
- 6つの非クラスター化インデックス(22.89MB対91.55MB)
合計:25MB対106MB -そしてそれはただ1つのテーブルにあります!
もう少し考えてみてください-キンバリー・トリップの素晴らしいもの-読んで、もう一度読んで、消化してください!これは、SQLServerのインデックス作成の福音です。
- 主キーおよび/またはクラスター化キーとしてのGUID
- クラスター化されたインデックスの議論は続く
- 増え続けるクラスタリングキー-クラスター化されたインデックスの討論..........再び!
- ディスクスペースは安価です-それはそうではありません ポイント!
PS:もちろん、数百行または数千行を扱っている場合、これらの引数のほとんどは実際にはあまり影響を与えません。ただし、数万または数十万の行に入る場合、または数百万の行を数え始めた場合-その後 これらの点は非常に重要であり、理解することが非常に重要になります。
更新: PKGUID
が必要な場合 主キー(クラスタリングキーではない)としての列、および別の列MYINT
(INT IDENTITY
)クラスタリングキーとして-これを使用します:
CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
MyINT INT IDENTITY(1,1) NOT NULL,
.... add more columns as needed ...... )
ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)
CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)
基本的に:明示的にする必要があります PRIMARY KEY
に伝えます NONCLUSTERED
であるという制約 (それ以外の場合は、デフォルトでクラスター化されたインデックスとして作成されます)-次に、CLUSTERED
として定義された2番目のインデックスを作成します。
これは機能します。パフォーマンスのために「再設計」する必要がある既存のシステムがある場合は、これは有効なオプションです。新しいシステムの場合、最初から始めて、レプリケーションシナリオを使用していない場合は、常にID INT IDENTITY(1,1)
を選択します。 クラスタ化された主キーとして-他の何よりもはるかに効率的です!