質問にはSQL Server 2000のタグが付いていますが、最新バージョンで開発している人々のために、最初にそれについて説明します。
SQL Server 2014
以下で説明する制約ベースのインデックスを追加する方法に加えて、SQL Server 2014では、一意でないインデックスをテーブル変数宣言のインライン構文で直接指定することもできます。
そのための構文例を以下に示します。
/*SQL Server 2014+ compatible inline index syntax*/
DECLARE @T TABLE (
C1 INT INDEX IX1 CLUSTERED, /*Single column indexes can be declared next to the column*/
C2 INT INDEX IX2 NONCLUSTERED,
INDEX IX3 NONCLUSTERED(C1,C2) /*Example composite index*/
);
フィルターされたインデックスと含まれている列を持つインデックスは、現在この構文では宣言できませんが、SQL Server 2016ではこれがさらに緩和されています。CTP 3.1から、テーブル変数のフィルター選択されたインデックスを宣言できるようになりました。RTMによって可能付属の列も許可されている場合であってもよいが、現在の位置は、彼らがいることである「可能性が高いため、リソースの制約にSQL16にそれをすることはありません」
/*SQL Server 2016 allows filtered indexes*/
DECLARE @T TABLE
(
c1 INT NULL INDEX ix UNIQUE WHERE c1 IS NOT NULL /*Unique ignoring nulls*/
)
SQL Server 2000〜2012
Nameにインデックスを作成できますか?
短い答え:はい。
DECLARE @TEMPTABLE TABLE (
[ID] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
UNIQUE NONCLUSTERED ([Name], [ID])
)
より詳細な回答は以下のとおりです。
SQL Serverの従来のテーブルは、クラスター化インデックスを持つことも、ヒープとして構造化することもできます。
クラスター化インデックスは、重複するキー値を許可しないように一意として宣言するか、デフォルトで非一意にすることができます。一意でない場合、SQL Serverは重複キーに一意の識別子を追加して、それらを一意にします。
非クラスター化インデックスは、一意として明示的に宣言することもできます。それ以外の場合、一意でない場合、SQL Server は行ロケーター(クラスター化インデックスキーまたはヒープのRID)をすべてのインデックスキー(重複するだけでなく)に追加します。これにより、再び一意になります。
SQL Server 2000-2012では、テーブル変数のインデックスは、UNIQUE
またはPRIMARY KEY
制約を作成することによってのみ暗黙的に作成できます。これらの制約タイプの違いは、主キーがnullを許容しない列になければならないことです。一意性制約に参加している列はnull可能になる場合があります。(ただし、NULL
sが存在する場合のSQL Serverの一意の制約の実装は、SQL標準で指定されているものではありません)。また、テーブルは1つの主キーのみを持つことができますが、一意の制約は複数持つことができます。
これらの論理制約はどちらも、一意のインデックスを使用して物理的に実装されます。明示的に指定されていない場合、PRIMARY KEY
クラスター化されたインデックスと非クラスター化された一意の制約になりますが、この動作は、制約宣言を指定するCLUSTERED
かNONCLUSTERED
明示的に指定することでオーバーライドできます(構文例)
DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)
上記の結果として、SQL Server 2000-2012のテーブル変数に次のインデックスを暗黙的に作成できます。
+-------------------------------------+-------------------------------------+
| Index Type | Can be created on a table variable? |
+-------------------------------------+-------------------------------------+
| Unique Clustered Index | Yes |
| Nonunique Clustered Index | |
| Unique NCI on a heap | Yes |
| Non Unique NCI on a heap | |
| Unique NCI on a clustered index | Yes |
| Non Unique NCI on a clustered index | Yes |
+-------------------------------------+-------------------------------------+
最後のものは少し説明が必要です。この回答の先頭にテーブル変数の定義では非ユニーク上の非クラスタ化インデックスName
によってシミュレートされたユニーク上のインデックスName,Id
(SQL Serverは黙って非ユニークNCIキーにクラスタ化インデックスキーを追加することをリコールとにかく)。
一意でないクラスタ化インデックスはIDENTITY
、一意の識別子として機能する列を手動で追加することでも実現できます。
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
ただし、これはすべての行に「一意名」を追加するため、一意でないクラスター化インデックスが実際にSQL Serverに実際に実装される方法の正確なシミュレーションではありません。それを必要とする人だけではありません。