I relationelle databasesystemer, et databaseindeks er et ekstremt kraftfuldt værktøj til datahentning. I denne vejledning lærer du om unikke indekser, primærnøgler og sammensatte primærnøgler.
Hvad er et databaseindeks?
Et databaseindeks er et datastrukturobjekt forbundet med en databasetabel. Det bruges til at øge hastigheden af databaseforespørgsler (via SQL SELECT
). kommando). Generelt er der veldefinerede metoder til at beslutte, hvilke typer indeks der skal oprettes. Dette er i høj grad styret af, hvordan tabeller i en database relaterer til hinanden, og hvordan data hentes.
Hvorfor bruge indekser?
Generelt forespørgsler (eller opslag) i en tabel via SQL SELECT
kommandoer er sekventielle. Sekventielt opslag kræver, at man starter øverst i tabellen og læser hver række data, indtil de ønskede data er hentet. Dette er ekstremt ineffektivt og kan være en dyr operation med hensyn til hastighed.
Indekser, på den anden side, bruger en hash-funktion til at beregne en indeksværdi. Det giver direkte adgang til den berørte række (nøgle) i indekset. Når denne række (nøgle) er placeret i indekset, har indeksposten en pegepind direkte til den tabelrække, der kræves i forespørgslen. Disse pointere etableres under indeksoprettelse og indeksvedligeholdelse. Hastigheden af datahentning ved brug af indekser øges i størrelsesordener.
Anatomien af et unikt databaseindeks
En databasetabel kan have et eller flere tilknyttede indekser. Indekser indeholder selv rækkeværdier (nøgle) fra en eller flere kolonner i en tabel. Den har også en markør, der peger på faktiske tabelrækker, der indeholder disse nøgleværdier. Antallet af rækker, der peges på af en given nøgle i et indeks, afhænger af, om indekset er et unikt indeks eller et ikke-unikt indeks .
Som navnet antyder, indeholder et unikt indeks nøgler, der kun peger på én datarække i en given tabel. Unikke indekser sikrer, at hver række i tabellen indeholder unikke værdier i de definerede indekserede tabelkolonner. Faktisk kan to rækker ikke have identiske værdier i de indekserede kolonner. Desuden oprettes unikke indekser på kolonner, der er udpeget som en primær nøgle til bordet. Primære nøgler er defineret som en eller flere kolonner, der entydigt definerer en række i en databasetabel.
Eksemplerne nedenfor viser, hvordan primærnøgler og unikke indekser bruges i SQL. Alle eksemplerne bruger en tabel med navnet Student
, i en eksempeldatabase ved navn exampledb
. For at tilføje eksempeldata skal du bruge følgende kommando:
INSERT INTO Student(SSNumber, LastName, FirstName)
VALUES
(111111111, Smith, John),
(222222222, Jones, Mary),
(333333333, Hansen, Robert);
Se de data, der er gemt i Student
tabel:
SELECT * FROM Student;
Du bør se følgende output:
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 111111111 | Smith | John |
| 222222222 | Jones | Mary |
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
Bemærk Medmindre andet er nævnt, fungerer alle kommandoerne i denne guide godt på både MySQL og PostgreSQL databaser.
Enkelt kolonne primær nøgle og indeks
Antag som et eksempel, at en skole holder styr på sine elever i en tabel med navnet Student
. Denne tabel har tilknyttede kolonner med navnet Student
, SSNumber
, LastName
og FirstName
. Fra disse kolonner, Student
er den primære nøglekolonne, da den entydigt identificerer hver række data i Student
bord. Opret et unikt indeks (SSIndex
) på SSNumber
kolonne, for at lette hurtig hentning af data fra tabellen. Følgende SQL DDL-kommando bruges til at udføre denne forespørgsel:
OPRET TABEL Elev (SSNumber CHAR(9) NOT NULL,Efternavn VARCHAR(30) NOT NULL,FirstName VARCHAR(20) NOT NULL,PRIMARY KEY (SSNumber));
CREATE UNIQUE INDEX SSIndex ON Student (SSNumber);
Bemærk Begge SQL-kommandoer ovenfor er afgrænset af et semikolon (;), som er kompatibelt med de fleste relationelle databasesystemer. SSNumber
er specifikt udpeget som tabellens primære nøgle.
SSIndex
indeholder kun information, der entydigt identificerer data i hver række af Student
bord. Hver række af SSIndex
har en markør til dens tilsvarende række i Student
bord. Dette SSIndex
indeks giver dig mulighed for at undgå en sekventiel søgning af data i tabellen, der forbedrer ydeevnen ved at minimere den nødvendige tid til forespørgslen.
For at finde de tilhørende oplysninger for Robert Hansen
via deres SSNumber
, brug SQL-kommandoen inkluderet nedenfor. Kommandoen eliminerer ikke kun den sekventielle søgning af Student
tabel, men bruger også SSIndex
at give direkte adgang til den nødvendige datarække. Dette er i kraft af at bruge en hashing-funktion og tilhørende indeksmarkør.
SELECT * FROM Student WHERE SSNumber = 333333333;
De returnerede data skal være følgende:
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
Multi-column-composite-primær nøgle og indeks
Dette afsnits eksempler bruger tre tabeller, der gemmer data relateret til en tennisliga. De tre borde hedder Player
, League
og Membership
. En spiller kan spille i flere ligaer, og medlemstabellen giver den forening. De tre tabeller har følgende kolonner tilknyttet:
Kolonnerne i Player
tabellen vises nedenfor med PlayedID
som den primære nøgle.
+----------+-----------+-----------+
| PlayedID | LastName | FirstName |
+----------+-----------+-----------+
Kolonnerne i League
tabellen vises nedenfor med LeagueId
som den primære nøgle.
+----------+------------+------------+
| LeagueId | LeagueName | SkillLevel |
+----------+------------+------------+
Kolonnerne i Membership
tabellen vises nedenfor
+----------+-----------+
| PlayedID | LeagueId |
+----------+-----------+
Trinene nedenfor viser dig, hvordan du opretter Player
, League
og Membership
tabeller.
-
Fra
Player
tabellen,PlayedID
kolonne identificerer entydigt hver række data. OpretPlayer
tabel efterfulgt af et unikt indeks påPlayerId
kolonne.CREATE TABLE Player ( PlayedID INT NOT NULL, LastName VARCHAR(30) NOT NULL, FirstName VARCHAR(20) NOT NULL, PRIMARY KEY (PlayedID) ); CREATE UNIQUE INDEX PlayerIndex ON Player (PlayedID);
-
Fra
League
tabel,LeagueId
kolonne identificerer entydigt hver række data. OpretLeague
tabel efterfulgt af et unikt indeks påLeagueId
kolonne. Følgende er SQL-kommandoen til at udføre denne handling:CREATE TABLE League ( LeagueId INT NOT NULL, LeagueName VARCHAR(50) NOT NULL, SkilLevel VARCHAR(20) NOT NULL, PRIMARY KEY (LeagueId) ); CREATE UNIQUE INDEX LeagueIndex ON League (LeagueId);
-
Fra
Membership
tabellen, bådePlayedID
ogLeagueId
kolonner identificerer entydigt hver række data; som er den sammensatte primærnøgle. OpretMembership
tabel efterfulgt af et unikt sammensat indeks påPlayedID
ogLeagueId
kolonner.CREATE TABLE Membership ( PlayerId INT NOT NULL, LeagueId INT NOT NULL, PRIMARY KEY(PlayerId, LeagueId) ); CREATE UNIQUE INDEX MembershipIndex ON Membership (PlayerId, LeagueId);
MembershipIndex
er et hash-genereret indeks bestående af den sammensatte nøgle(PlayedId
og LeagueId
). Den har pointere til datarækkerne, som den repræsenterer. Brugen af et sådant indeks letter hurtig datahentning med direkte adgang i modsætning til lineær sekventiel datahentning. For f.eks. at bestemme alle de spillere, der er knyttet til "Herredouble" fra flere poster i hver af tabellerne ovenfor, kan du udstede følgende SQL-kommando:
SELECT Player.LastName, Player.Firstname
FROM Player, Membership
WHERE Membership.LeagueId = 2
AND Membership.PlayerId = Player.PlayerId
Følgende data returneres:
+----------+-----------+
| LastName | FirstName |
+----------+-----------+
| Smith | John |
| Hansen | Robert |
+-----------+----------+
Uden brug af MembershipIndex
og PlayerIndex
, ville forespørgslen ovenfor udføres betydeligt langsommere.
Ikke-unique indekser
Et ikke-unik indeks indeholder poster, der kan pege på en eller flere rækker for en given nøgleværdi. For at søge på en persons navn er det f.eks. nødvendigt at oprette et ikke-unikt sammensat indeks på en tabel for både FirstName
og LastName
. Siden kombinationen af FirstName
og LastName
kan ikke garanteres for at være unikt, det resulterende indeks, der er oprettet på disse to kolonner, genererer effektivt et ikke-unik indeks.
Problem med forringelse af databaseydelse ved brug af indekser
Mens indekser hjælper med at udføre forespørgslers hastighed, skal de opdateres, når indekserede kolonner ændres, eller når tabelrækker tilføjes eller slettes fra databasen. Dette kan være skadeligt for databasens ydeevne. Det er vigtigt at huske på mængden af indsættelse, sletning og ændring, der kræves af dine indekser under brug af transaktionsdatabase. Overvej, hvad der er vigtigt for dig i databaseapplikationen; hastigheden for udførelse af forespørgsler eller hastigheden af datamanipulation. Svaret på det spørgsmål ligger i, hvordan databaseapplikationen bruges, hvor ofte den påvirker designet af databasen og antallet af oprettede indekser.
Konklusion
Oprettelse og brug af databaseindekser genererer hurtige forespørgselshentningssvar og eliminerer sekventielle rækkeopslag fra tabeller. Indeksvedligeholdelse gennem datamanipulation kan dog have en skadelig indvirkning på en databases ydeevne. Databasedesignere skal være opmærksomme på de afvejninger, der er involveret, når de bruger databaseindekser og huske på optimering af databasens overordnede ydeevne.