Въпросът е маркиран като 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
ограничение. Разликата между тези типове ограничения е, че първичният ключ трябва да бъде върху колона(и) без нула. Колоните, участващи в уникално ограничение, могат да бъдат нулеви. (въпреки че изпълнението от SQL Server на уникални ограничения при наличието на NULL
s не съответства на това, посочено в SQL стандарта). Също така една таблица може да има само един първичен ключ, но множество уникални ограничения.
И двете от тези логически ограничения са физически реализирани с уникален индекс. Ако не е изрично посочено друго, 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, тъй като това добавя "Uniqueifier" към всички редове. Не само тези, които го изискват.