Otázka je označena jako SQL Server 2000, ale ve prospěch lidí vyvíjejících nejnovější verzi se jí budu věnovat jako první.
SQL Server 2014
Kromě metod přidávání indexů založených na omezení popsaných níže SQL Server 2014 také umožňuje zadat nejedinečné indexy přímo s vloženou syntaxí v deklaracích proměnných tabulky.
Příklad syntaxe je uveden níže.
/*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*/
);
Filtrované indexy a indexy se zahrnutými sloupci nelze aktuálně deklarovat s touto syntaxí, nicméně SQL Server 2016 uvolňuje to trochu dále. Od CTP 3.1 je nyní možné deklarovat filtrované indexy pro proměnné tabulky. U RTM to může v případě, že zahrnuté sloupce jsou také povoleny, ale současná pozice je taková, že se "pravděpodobně nedostanou do SQL16 kvůli omezení zdrojů"
/*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
Mohu vytvořit index na Name?
Krátká odpověď:Ano.
DECLARE @TEMPTABLE TABLE (
[ID] [INT] NOT NULL PRIMARY KEY,
[Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
UNIQUE NONCLUSTERED ([Name], [ID])
)
Podrobnější odpověď je níže.
Tradiční tabulky na serveru SQL Server mohou mít seskupený index nebo jsou strukturovány jako haldy.
Seskupené indexy mohou být buď deklarovány jako jedinečné, aby byly zakázány duplicitní hodnoty klíče, nebo jako výchozí mohou být nejedinečné. Pokud není jedinečný, SQL Server tiše přidá jedinečný identifikátor ke všem duplicitním klíčům, aby byly jedinečné.
Neklastrované indexy lze také explicitně deklarovat jako jedinečné. V opačném případě pro nejedinečný případ SQL Server přidá lokátor řádků (sdružený indexový klíč nebo RID pro haldu) ke všem indexovým klíčům (nejen duplikátům), čímž opět zajistí, že jsou jedinečné.
V SQL Server 2000–2012 lze indexy proměnných tabulky vytvořit pouze implicitně vytvořením UNIQUE
nebo PRIMARY KEY
omezení. Rozdíl mezi těmito typy omezení spočívá v tom, že primární klíč musí být na sloupcích bez možnosti null. Sloupce účastnící se jedinečného omezení mohou mít hodnotu null. (ačkoli implementace jedinečných omezení SQL Serveru v přítomnosti NULL
s neodpovídá specifikaci ve standardu SQL). Také tabulka může mít pouze jeden primární klíč, ale několik jedinečných omezení.
Obě tato logická omezení jsou fyzicky implementována pomocí jedinečného indexu. Pokud není výslovně uvedeno jinak, PRIMARY KEY
se stane seskupeným indexem a jedinečná omezení nebudou seskupená, ale toto chování lze přepsat zadáním CLUSTERED
nebo NONCLUSTERED
explicitně s deklarací omezení (příklad syntaxe)
DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)
V důsledku výše uvedeného mohou být v SQL Server 2000 - 2012 implicitně vytvořeny následující indexy pro proměnné tabulky.
+-------------------------------------+-------------------------------------+
| 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 |
+-------------------------------------+-------------------------------------+
To poslední vyžaduje trochu vysvětlení. V definici proměnné tabulky na začátku této odpovědi nejedinečné neshlukovaný index na Name
je simulován jedinečným index na Name,Id
(připomeňme, že SQL Server by stejně tiše přidal klíč clusteru indexu k nejedinečnému klíči NCI).
Nejedinečného seskupeného indexu lze také dosáhnout ručním přidáním IDENTITY
sloupec, aby fungoval jako jedinečný identifikátor.
DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
Toto však není přesná simulace toho, jak by nejedinečný seskupený index byl normálně implementován v SQL Server, protože to přidává "Uniqueifier" do všech řádků. Nejen ty, které to vyžadují.