SQL Serverの主キーに最適なのはどれですか?
いくつかのサンプルコードがあります:
例:
CREATE TABLE new_employees
(employeeId UNIQUEIDENTIFIER DEFAULT NEWID(),
fname VARCHAR(20) )
GO
INSERT INTO new_employees(fname) VALUES ('Karin')
GO
例:
CREATE TABLE new_employees
(
employeeId int IDENTITY(1,1),
fname varchar (20)
);
INSERT new_employees
(fname)
VALUES
('Karin');
[材料コード](または材料のIDであるビジネスコード。例:顧客識別子)
例:
CREATE TABLE new_employees(
[ClientId] [varchar](20) NOT NULL,
[fName] [varchar](20) NULL
)
INSERT new_employees
(ClientID, fname)
VALUES
('C0101000001',--customer identifier,e.g.'C0101000001' a user-defined code.
'Karin');
3つのタイプID列から主キーを選択するためのアドバイス、またはその他の選択肢を教えてください。
ありがとう!
GUID
は、主キーの自然な選択のように思われるかもしれません。本当に必要な場合は、テーブルの主キーに使用することを主張できます。私が強くお勧めするのはしないでくださいGUID
列をクラスタリングキーとして使用することです。特に指定しない限り、SQLServerはデフォルトで実行します。
あなたは本当に2つの問題を区別する必要があります:
主キーは論理構造であり、テーブル内のすべての行を一意かつ確実に識別する候補キーの1つです。これは実際には何でもかまいません-INT
、GUID
、文字列-シナリオに最も適したものを選択してください。
クラスタリングキー(テーブルの「クラスター化インデックス」を定義する1つまたは複数の列)-これはphysicalストレージ関連のことです。ここでは、小さくて安定した、増え続けるデータ型が最適です-デフォルトのオプションとしてINT
またはBIGINT
。
デフォルトでは、SQL Serverテーブルの主キーはクラスタリングキーとしても使用されますが、そのようにする必要はありません。以前のGUIDベースのプライマリ/クラスター化キーを2つの別々のキー(GUID
のプライマリ(論理)キーと別のクラスター化(順序付け)キー)に分割すると、個人的にパフォーマンスが大幅に向上しました。 INT IDENTITY(1,1)
列。
Kimberly Tripp -Queen of Indexing-などが何度も述べています-クラスタリングキーとしてのGUID
'最適です。ランダムであるため、ページとインデックスの断片化が大きくなり、一般的にパフォーマンスが低下します。
はい、わかっています。SQLServer2005以降にはnewsequentialid()
がありますが、それでも完全にシーケンシャルではないため、GUID
と同じ問題が発生します。顕著にそうです。
次に、考慮すべき別の問題があります。テーブルのクラスタリングキーは、テーブルのすべての非クラスター化インデックスのすべてのエントリにも追加されます。したがって、できるだけ小さくする必要があります。通常、テーブルの大部分には2億行以上のINT
で十分です。また、クラスタリングキーとしてのGUID
と比較すると、ディスク上の数百メガバイトのストレージを節約できます。およびサーバーメモリ内。
迅速な計算-プライマリキーおよびクラスタリングキーとしてINT
とGUID
を使用:
合計:25MB対106MB-そしてそれはただ1つのテーブルにあります!
キンバリー・トリップの優れたものである、もう少し考えるべき食べ物を読んで、もう一度読んで、消化してください!本当に、それはSQLServerのインデックス作成の福音です。
非常に正当な理由がない限り、ほとんどすべての「実際の」データテーブルにINT IDENTITY
をデフォルトとして使用することをお勧めします。主キー-一意であり、安定しており(変更されない)、狭く、増加し続けています-クラスタリングに必要なすべての優れたプロパティ SQL Serverテーブルの高速で信頼性の高いパフォーマンスのための鍵!
これらすべてのプロパティを持つ「自然」キー値がある場合は、代理キーの代わりにそれを使用することもできます。しかし、two最大の可変長文字列。私の意見では、それぞれ20文字はこれらの要件を満たしていません。
[〜#〜]アイデンティティ[〜#〜]
[〜#〜]プロ[〜#〜]
[〜#〜]短所[〜#〜]
[〜#〜] guid [〜#〜]
[〜#〜]プロ[〜#〜]
それらは{多かれ少なかれ}一意であることが保証されているため、複数のテーブル/データベース/インスタンス/サーバー/ネットワーク/データセンターがそれらを個別に生成し、衝突することなくマージできます。
一部の形式のレプリケーションに必要です。
[〜#〜]短所[〜#〜]
テーブルを設計する際に考慮する必要があることの1つは、データをある場所から別の場所に複製、シャーディング、またはその他の方法で移動する必要があるかどうかです。たぶん、データは他のアプリケーションによって生成されており、あなたのアプリケーションと同期しておく必要があります。その一例は、データを作成してサーバーと同期するモバイルアプリです。そのようなことが当てはまる、または当てはまる可能性がある場合は、UNIQUEIDENTIFIER
を主キーに使用することをお勧めします。
UNIQUEIDENTIFIER
データ型は、クラスター化インデックスとして使用するとパフォーマンスが低下します。はい、newsequentialid()
を使用できますが、値が他のデバイスで生成されている場合は役に立ちません。クラスター化インデックスは、INT
やBIGINT
のようなシーケンシャルで狭いデータ型で使用するのが最適であるというのがコンセンサスのようです。
ストレージスペースの問題に関心がない場合は、IDENTITY
クラスターキーとUNIQUEIDENTIFIER
主キー。 cluster keyIDENTITY
列を作成し、それをクラスター化インデックスに使用します(ただし、主キーとしては使用しません)。挿入は引き続き順次行われ、狭いデータ型であるという要望を満たします。これで、UNIQUEIDENTIFIER
を主キーとして使用できます。これにより、必要なときにデータを移動、複製、および/またはシャーディングすることができます。
クラスターキーには、挿入をシーケンシャルに保ち、他のすべての非クラスター化インデックスがデータを検索するときに指すものにする以外の目的はありません。特定のクエリ。 クラスターキーは完全に破棄され、一意性はUNIQUEIDENTIFIER
主キー。
これは、クラスター化インデックスにIDENTITYとUNIQUEIDENTIFIERを使用したときに内部で何が起こるかを示す優れた記事です。
GUIDは大きいですが、このテーブルまたはそれ、このサーバーまたはそれなど、どこでも一意であるという利点があります。GUIDがあれば、他のすべてがわかります。それが役立つ場合は、すばらしいですが、オーバーヘッドで支払い、支払いを続け、支払い、支払いを行います。
マテリアルコードは、色や分類コードなどの小さな不変のキーに対してのみ実際に機能します。 Rは常に赤、Gは緑、1バイトなどです。
ID列は、マテリアルコードがない場合、自然キーが複数のマテリアルコードで構成されている場合、自然キーがすでに他のID列やGUIDで構成されている場合、または自然キーが変更可能である場合に独自に機能します。はい、GUIDを使用できますが、すべての点で整数列の方がはるかに効率的です。
SQL 2012で使用できるもう1つのオプションは、データベースレベルのID列のようなシーケンスです。これは、シーケンスを多くのテーブルで使用できるという意味で、GUIDとID列の中間に位置するため、特定の値から、行だけでなくテーブルも認識できますが、引き続き使用できます。データに十分だと思われる場合は、INTまたはBIGINT(またはSMALLINT!)。これは、特定の目的にとっては気の利いたものであり、OO worldのオブジェクトIDのようなものです。
多くのORMまたは軽量ORMは、テーブルに単一列の主キー、できれば整数列があることを期待しており、INT IDENTITYPK以外ではうまく機能しない可能性があることに注意してください。