In relationele databasesystemen is een database-index is een extreem krachtig hulpmiddel voor het ophalen van gegevens. In deze handleiding leert u over unieke indexen, primaire sleutels en samengestelde primaire sleutels.
Wat is een database-index?
Een database-index is een gegevensstructuurobject dat is gekoppeld aan een databasetabel. Het wordt gebruikt om de snelheid van databasequery's te verhogen (via de SQL SELECT
opdracht). Over het algemeen zijn er goed gedefinieerde methoden om te bepalen welke typen indexen moeten worden gemaakt. Dit wordt grotendeels bepaald door hoe tabellen in een database zich tot elkaar verhouden en hoe gegevens worden opgehaald.
Waarom indexen gebruiken?
In het algemeen vragen (of zoekacties) in een tabel via de SQL SELECT
commando zijn sequentieel. Sequentieel opzoeken vereist dat u bovenaan de tabel begint en elke rij gegevens leest totdat de gewenste gegevens zijn opgehaald. Dit is extreem inefficiënt en kan een dure operatie zijn in termen van snelheid.
Indexen daarentegen gebruiken een hashfunctie om een indexwaarde te berekenen. Het biedt directe toegang tot de betreffende rij (sleutel) in de index. Zodra die rij (sleutel) zich in de index bevindt, heeft het indexrecord een verwijzing naar de tabelrij die vereist is in de query. Deze wijzers worden vastgesteld tijdens het maken van een index en het onderhouden van de index. De snelheid van het ophalen van gegevens bij het gebruik van indexen wordt met ordes van grootte verhoogd.
De anatomie van een unieke database-index
Een databasetabel kan een of meer bijbehorende indexen hebben. Indexen zelf bevatten rij (sleutel) waarden uit een of meer kolommen in een tabel. Het heeft ook een aanwijzer die verwijst naar werkelijke tabelrijen die deze sleutelwaarden bevatten. Het aantal rijen waarnaar een bepaalde sleutel in een index verwijst, is afhankelijk van of de index een unieke index is. of een niet-unieke index .
Zoals de naam al aangeeft, bevat een unieke index sleutels die naar slechts één gegevensrij in een bepaalde tabel verwijzen. Unieke indexen zorgen ervoor dat elke rij in de tabel unieke waarden bevat in de gedefinieerde geïndexeerde tabelkolommen. In feite kunnen geen twee rijen identieke waarden hebben in de geïndexeerde kolommen. Bovendien worden unieke indexen gemaakt op kolommen die zijn aangewezen als een primaire sleutel voor de tafel. Primaire sleutels worden gedefinieerd als een of meer kolommen die op unieke wijze een rij in een databasetabel definiëren.
De onderstaande voorbeelden laten zien hoe primaire sleutels en unieke indexen worden gebruikt in SQL. Alle voorbeelden gebruiken een tabel met de naam Student
, in een voorbeelddatabase met de naam exampledb
. Gebruik de volgende opdracht om de voorbeeldgegevens toe te voegen:
INSERT INTO Student(SSNumber, LastName, FirstName)
VALUES
(111111111, Smith, John),
(222222222, Jones, Mary),
(333333333, Hansen, Robert);
Bekijk de gegevens die zijn opgeslagen in de Student
tafel:
SELECT * FROM Student;
U zou de volgende uitvoer moeten zien:
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 111111111 | Smith | John |
| 222222222 | Jones | Mary |
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
Opmerking Tenzij anders vermeld, werken alle opdrachten in deze handleiding goed op zowel MySQL en PostgreSQL databases.
Primaire sleutel en index met één kolom
Neem bijvoorbeeld aan dat een school haar leerlingen bijhoudt in een tabel met de naam Student
. Deze tabel heeft bijbehorende kolommen met de naam Student
, SSNumber
, LastName
, en FirstName
. Uit deze kolommen, Student
is de primaire sleutelkolom omdat het elke rij met gegevens in de Student
uniek identificeert tafel. Maak een unieke index (SSIndex
) op het SSNumber
kolom, om het snel ophalen van gegevens uit de tabel te vergemakkelijken. De volgende SQL DDL-opdracht wordt gebruikt om deze query uit te voeren:
MAAK TABEL Student (SSNumber CHAR (9) NOT NULL,Achternaam VARCHAR (30) NOT NULL,Voornaam VARCHAR (20) NOT NULL, PRIMAIRE SLEUTEL (SSNumber));
CREATE UNIQUE INDEX SSIndex ON Student (SSNumber);
Opmerking Beide SQL-opdrachten hierboven worden gescheiden door een puntkomma (;), die compatibel is met de meeste relationele databasesystemen. SSNumber
is specifiek aangewezen als de primaire sleutel van de tabel.
SSIndex
bevat alleen informatie die gegevens uniek identificeert in elke rij van de Student
tafel. Elke rij van SSIndex
heeft een verwijzing naar de bijbehorende rij in de Student
tafel. Deze SSIndex
index stelt u in staat om een opeenvolgende zoekopdracht van gegevens in de tabel te vermijden, wat de prestaties verbetert door de tijd die nodig is voor de zoekopdracht te minimaliseren.
Om de bijbehorende informatie voor Robert Hansen
te vinden via hun SSNumber
, gebruik dan de onderstaande SQL-opdracht. De opdracht elimineert niet alleen het sequentiële zoeken van Student
tabel maar gebruikt ook de SSIndex
om directe toegang tot de vereiste gegevensrij te bieden. Dit is dankzij het gebruik van een hash-functie en de bijbehorende indexaanwijzer.
SELECT * FROM Student WHERE SSNumber = 333333333;
De geretourneerde gegevens moeten de volgende zijn:
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
Multi-column samengestelde primaire sleutel en index
In de voorbeelden van deze sectie worden drie tabellen gebruikt die gegevens over een tenniscompetitie opslaan. De drie tafels heten Player
, League
, en Membership
. Een speler kan in meerdere competities spelen en de ledentabel geeft die associatie weer. Aan de drie tabellen zijn de volgende kolommen gekoppeld:
De kolommen van de Player
tabel worden hieronder weergegeven met PlayedID
als de primaire sleutel.
+----------+-----------+-----------+
| PlayedID | LastName | FirstName |
+----------+-----------+-----------+
De kolommen van de League
tabel worden hieronder weergegeven met LeagueId
als de primaire sleutel.
+----------+------------+------------+
| LeagueId | LeagueName | SkillLevel |
+----------+------------+------------+
De kolommen van het Membership
tabel worden hieronder weergegeven
+----------+-----------+
| PlayedID | LeagueId |
+----------+-----------+
De onderstaande stappen laten zien hoe u de Player
. maakt , League
, en Membership
tabellen.
-
Van de
Player
tabel, dePlayedID
kolom identificeert op unieke wijze elke rij met gegevens. Maak dePlayer
tabel gevolgd door een unieke index op dePlayerId
kolom.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);
-
Van de
League
tabel, deLeagueId
kolom identificeert op unieke wijze elke rij met gegevens. Maak deLeague
tabel gevolgd door een unieke index op deLeagueId
kolom. Hieronder volgt het SQL-commando om deze bewerking uit te voeren: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);
-
Van het
Membership
tabel, zowel dePlayedID
enLeagueId
kolommen identificeren elke rij met gegevens op unieke wijze; wat de samengestelde primaire sleutel is. Maak hetMembership
tabel gevolgd door een unieke samengestelde index op dePlayedID
enLeagueId
kolommen.CREATE TABLE Membership ( PlayerId INT NOT NULL, LeagueId INT NOT NULL, PRIMARY KEY(PlayerId, LeagueId) ); CREATE UNIQUE INDEX MembershipIndex ON Membership (PlayerId, LeagueId);
De MembershipIndex
is een door hash gegenereerde index die bestaat uit de Composite Key(PlayedId
en LeagueId
). Het heeft verwijzingen naar de gegevensrijen die het vertegenwoordigt. Het gebruik van een dergelijke index vergemakkelijkt het snel ophalen van gegevens met directe toegang, in tegenstelling tot het lineair opeenvolgend ophalen van gegevens. Om bijvoorbeeld alle spelers te bepalen die zijn gekoppeld aan "Herendubbel" uit verschillende records in elk van de bovenstaande tabellen, kunt u het volgende SQL-commando geven:
SELECT Player.LastName, Player.Firstname
FROM Player, Membership
WHERE Membership.LeagueId = 2
AND Membership.PlayerId = Player.PlayerId
De volgende gegevens worden geretourneerd:
+----------+-----------+
| LastName | FirstName |
+----------+-----------+
| Smith | John |
| Hansen | Robert |
+-----------+----------+
Zonder het gebruik van de MembershipIndex
en PlayerIndex
, zou de bovenstaande query aanzienlijk langzamer worden uitgevoerd.
Niet-unieke indexen
Een niet-unieke index bevat items die kunnen verwijzen naar een of meer rijen voor bepaalde sleutelwaarden. Als u bijvoorbeeld op de naam van een persoon wilt zoeken, moet u een niet-unieke samengestelde index op een tabel maken voor zowel FirstName
en LastName
. Sinds de combinatie van FirstName
en LastName
niet gegarandeerd uniek is, genereert de resulterende index die op die twee kolommen is gemaakt in feite een niet-unieke index.
Probleem met verslechtering van databaseprestaties bij gebruik van indexen
Hoewel indexen de uitvoeringssnelheid van query's ondersteunen, moeten ze worden bijgewerkt wanneer geïndexeerde kolommen veranderen of wanneer tabelrijen worden toegevoegd aan of verwijderd uit de database. Dit kan nadelig zijn voor de prestaties van de database. Het is belangrijk om rekening te houden met de hoeveelheid invoeging, verwijdering en wijziging die vereist is voor uw indexen tijdens het gebruik van de transactionele database. Bedenk wat voor u belangrijk is in de databasetoepassing; de snelheid van het uitvoeren van query's of de snelheid van gegevensmanipulatie. Het antwoord op die vraag ligt in hoe de databasetoepassing wordt gebruikt, hoe vaak deze het ontwerp van de database beïnvloedt en het aantal indexen dat wordt gemaakt.
Conclusie
Het maken en gebruiken van database-indexen genereert snelle reacties voor het ophalen van query's en elimineert opeenvolgende zoekacties van rijen uit tabellen. Indexonderhoud door middel van gegevensmanipulatie kan echter nadelige gevolgen hebben voor de prestaties van een database. Databaseontwerpers moeten zich bewust zijn van de compromissen bij het gebruik van database-indexen en rekening houden met optimalisatie voor de algehele databaseprestaties.