sql >> Database teknologi >  >> RDS >> Sqlserver

Oprettelse af et indeks på en tabelvariabel

Spørgsmålet er tagget SQL Server 2000, men til gavn for folk, der udvikler på den seneste version, vil jeg tage fat på det først.

SQL Server 2014

Ud over metoderne til at tilføje begrænsningsbaserede indekser diskuteret nedenfor tillader SQL Server 2014 også at specificere ikke-entydige indekser direkte med inline syntaks på tabelvariableerklæringer.

Eksempel på syntaks for det er nedenfor.

/*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*/
);
 

Filtrerede indekser og indekser med inkluderede kolonner kan i øjeblikket ikke erklæres med denne syntaks dog SQL Server 2016 slapper lidt mere af. Fra CTP 3.1 er det nu muligt at erklære filtrerede indekser for tabelvariabler. Ved RTM kan være tilfældet, at inkluderede kolonner også er tilladt, men den nuværende position er, at de "sandsynligvis ikke vil blive til SQL16 på grund af ressourcebegrænsninger"

/*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

Kan jeg oprette et indeks på Navn?

Kort svar:Ja.

DECLARE @TEMPTABLE TABLE (
  [ID]   [INT] NOT NULL PRIMARY KEY,
  [Name] [NVARCHAR] (255) COLLATE DATABASE_DEFAULT NULL,
  UNIQUE NONCLUSTERED ([Name], [ID]) 
  ) 
 

Et mere detaljeret svar er nedenfor.

Traditionelle tabeller i SQL Server kan enten have et klynget indeks eller er struktureret som dynger.

Klyngede indekser kan enten erklæres som unikke for ikke at tillade duplikerede nøgleværdier eller som standard ikke-entydige. Hvis det ikke er unikt, tilføjer SQL Server lydløst en unikifikator til alle dubletnøgler for at gøre dem unikke.

Ikke-klyngede indekser kan også udtrykkeligt erklæres som unikke. Ellers for det ikke-entydige tilfælde tilføjer SQL Server rækkefinderen (klynget indeksnøgle eller RID for en heap) til alle indeksnøgler (ikke kun dubletter), hvilket igen sikrer, at de er unikke.

I SQL Server 2000 - 2012 kan indekser på tabelvariabler kun oprettes implicit ved at skabe en UNIQUE eller PRIMARY KEY begrænsning. Forskellen mellem disse begrænsningstyper er, at den primære nøgle skal være på kolonne(r), der ikke kan nulstilles. De kolonner, der deltager i en unik begrænsning, kan være nullable. (selvom SQL Servers implementering af unikke begrænsninger i nærvær af NULL s er ikke ifølge det, der er angivet i SQL-standarden). En tabel kan også kun have én primær nøgle, men flere unikke begrænsninger.

Begge disse logiske begrænsninger er fysisk implementeret med et unikt indeks. Hvis andet ikke udtrykkeligt er angivet, er PRIMARY KEY bliver det klyngede indeks og unikke begrænsninger, der ikke er klynget, men denne adfærd kan tilsidesættes ved at angive CLUSTERED eller NONCLUSTERED eksplicit med constraint-deklarationen (eksempelsyntaks)

DECLARE @T TABLE
(
A INT NULL UNIQUE CLUSTERED,
B INT NOT NULL PRIMARY KEY NONCLUSTERED
)
 

Som et resultat af ovenstående kan følgende indekser implicit oprettes på tabelvariabler i 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 | +-------------------------------------+-------------------------------------+

Det sidste kræver lidt forklaring. I tabelvariabeldefinitionen i begyndelsen af ​​dette svar ikke unik ikke-klynget indeks på Name er simuleret af en unik indeks på Name,Id (husk på, at SQL Server lydløst ville tilføje den klyngede indeksnøgle til den ikke-entydige NCI-nøgle alligevel).

Et ikke-entydigt klynget indeks kan også opnås ved manuelt at tilføje en IDENTITY kolonne for at fungere som en unikifikator.

DECLARE @T TABLE
(
A INT NULL,
B INT NULL,
C INT NULL,
Uniqueifier INT NOT NULL IDENTITY(1,1),
UNIQUE CLUSTERED (A,Uniqueifier)
)
 

Men dette er ikke en nøjagtig simulering af, hvordan et ikke-entydigt klynget indeks normalt ville blive implementeret i SQL Server, da dette tilføjer "Uniqueifier" til alle rækker. Ikke kun dem, der kræver det.



  1. Online SQL-syntakskontrol, der er i overensstemmelse med flere databaser

  2. Skemadefinitioner af DBMS

  3. Online værktøjer til at prøve SQL design og forespørgsler

  4. Hvordan udføres to mysql-forespørgsler som én i PHP/MYSQL?