Nei sistemi di database relazionali, un indice di database è uno strumento estremamente potente per il recupero dei dati. In questa guida imparerai a conoscere gli indici univoci, le chiavi primarie e le chiavi primarie composte.
Cos'è un indice di database?
Un Indice di database è un oggetto struttura dati associato a una tabella di database. Viene utilizzato per aumentare la velocità delle query del database (tramite il SQL SELECT
comando). In generale, esistono metodi ben definiti per decidere i tipi di indici da creare. Questo è in gran parte governato dal modo in cui le tabelle in un database si relazionano tra loro e dal modo in cui i dati vengono recuperati.
Perché usare gli indici?
In generale, le query (o le ricerche) in una tabella tramite l'SQL SELECT
i comandi sono sequenziali. La ricerca sequenziale richiede di iniziare dalla parte superiore della tabella e di leggere ogni riga di dati fino a quando non vengono recuperati i dati desiderati. Questo è estremamente inefficiente e può essere un'operazione costosa in termini di velocità.
Gli indici, d'altra parte, utilizzano una funzione hash per calcolare un valore di indice. Fornisce l'accesso diretto alla riga (chiave) interessata nell'indice. Una volta che la riga (chiave) si trova nell'indice, il record dell'indice ha un puntatore direttamente alla riga della tabella richiesta nella query. Questi puntatori vengono stabiliti durante la creazione e la manutenzione dell'indice. La velocità di recupero dei dati quando si utilizzano gli indici è aumentata di ordini di grandezza.
L'anatomia di un indice di database univoco
Una tabella di database può avere uno o più indici associati. Gli indici stessi contengono valori di riga (chiave) da una o più colonne in una tabella. Ha anche un puntatore che punta alle righe della tabella effettive contenenti questi valori chiave. Il numero di righe a cui punta una determinata chiave in un indice dipende dal fatto che l'indice sia un indice univoco o un indice non univoco .
Come suggerisce il nome, un indice univoco contiene chiavi che puntano a una sola riga di dati in una determinata tabella. Gli indici univoci assicurano che ogni riga della tabella contenga valori univoci nelle colonne della tabella indicizzata definite. In effetti, nessuna riga può avere valori identici nelle colonne indicizzate. Inoltre, vengono creati indici univoci su colonne designate come chiave primaria per la tavola. Le chiavi primarie sono definite come una o più colonne che definiscono in modo univoco una riga in una tabella di database.
Gli esempi seguenti mostrano come vengono utilizzate le chiavi primarie e gli indici univoci in SQL. Tutti gli esempi utilizzano una tabella denominata Student
, in un database di esempio denominato exampledb
. Per aggiungere i dati di esempio utilizzare il seguente comando:
INSERT INTO Student(SSNumber, LastName, FirstName)
VALUES
(111111111, Smith, John),
(222222222, Jones, Mary),
(333333333, Hansen, Robert);
Visualizza i dati memorizzati nello Student
tabella:
SELECT * FROM Student;
Dovresti vedere il seguente output:
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 111111111 | Smith | John |
| 222222222 | Jones | Mary |
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
Nota Salvo diversa indicazione, tutti i comandi in questa guida funzionano bene sia su MySQL e PostgreSQL database.
Chiave primaria e indice a colonna singola
Ad esempio, supponiamo che una scuola tenga traccia dei suoi studenti in una tabella denominata Student
. Questa tabella ha colonne associate denominate Student
, SSNumber
, LastName
e FirstName
. Da queste colonne, Student
è la colonna della chiave primaria in quanto identifica in modo univoco ogni riga di dati nello Student
tavolo. Crea un indice univoco (SSIndex
) sul SSNumber
colonna, per facilitare il rapido recupero dei dati dalla tabella. Per eseguire questa query viene utilizzato il seguente comando SQL DDL:
CREATE TABLE Studente (Numero SSN CHAR(9) NOT NULL,Cognome VARCHAR(30) NOT NULL,Nome VARCHAR(20) NOT NULL,CHIAVE PRIMARIA (NumeroSSN));
CREATE UNIQUE INDEX SSIndex ON Student (SSNumber);
Nota Entrambi i comandi SQL precedenti sono delimitati da un punto e virgola (;), che è compatibile con la maggior parte dei sistemi di database relazionali. SSNumber
è specificamente designato come chiave primaria della tabella.
SSIndex
contiene solo informazioni che identificano in modo univoco i dati in ogni riga dello Student
tavolo. Ogni riga di SSIndex
ha un puntatore alla riga corrispondente in Student
tavolo. Questo SSIndex
index consente di evitare una ricerca sequenziale dei dati nella tabella che migliora le prestazioni riducendo al minimo il tempo necessario per la query.
Per trovare le informazioni associate per Robert Hansen
tramite il loro SSNumber
, utilizzare il comando SQL incluso di seguito. Il comando non solo elimina la ricerca sequenziale di Student
tabella ma utilizza anche SSIndex
per fornire l'accesso diretto alla riga di dati richiesta. Ciò è dovuto all'utilizzo di una funzione di hashing e di un puntatore all'indice associato.
SELECT * FROM Student WHERE SSNumber = 333333333;
I dati restituiti dovrebbero essere i seguenti:
+-----------+----------+-----------+
| SSNumber | LastName | FirstName |
+-----------+----------+-----------+
| 333333333 | Hansen | Robert |
+-----------+----------+-----------+
Chiave primaria e indice compositi multicolonna
Gli esempi di questa sezione utilizzano tre tabelle che memorizzano i dati relativi a un campionato di tennis. I tre tavoli sono denominati Player
, League
e Membership
. Un giocatore può giocare in più campionati e la tabella dei membri fornisce tale associazione. Alle tre tabelle sono associate le seguenti colonne:
Le colonne del Player
la tabella viene visualizzata di seguito con PlayedID
come chiave primaria.
+----------+-----------+-----------+
| PlayedID | LastName | FirstName |
+----------+-----------+-----------+
Le colonne della League
la tabella viene visualizzata di seguito con LeagueId
come chiave primaria.
+----------+------------+------------+
| LeagueId | LeagueName | SkillLevel |
+----------+------------+------------+
Le colonne della Membership
le tabelle sono visualizzate di seguito
+----------+-----------+
| PlayedID | LeagueId |
+----------+-----------+
I passaggi seguenti mostrano come creare il Player
, League
e Membership
tabelle.
-
Dal
Player
tabella, ilPlayedID
colonna identifica in modo univoco ogni riga di dati. Crea ilPlayer
tabella seguita da un indice univoco suPlayerId
colonna.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);
-
Dal
League
tabella, ilLeagueId
colonna identifica in modo univoco ogni riga di dati. Crea ilLeague
tabella seguita da un indice univoco suLeagueId
colonna. Di seguito è riportato il comando SQL per eseguire questa operazione: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);
-
Da
Membership
tabella, sia ilPlayedID
eLeagueId
le colonne identificano in modo univoco ogni riga di dati; che è la chiave primaria composita. Crea ilMembership
tabella seguita da un indice composito univoco suPlayedID
eLeagueId
colonne.CREATE TABLE Membership ( PlayerId INT NOT NULL, LeagueId INT NOT NULL, PRIMARY KEY(PlayerId, LeagueId) ); CREATE UNIQUE INDEX MembershipIndex ON Membership (PlayerId, LeagueId);
L'MembershipIndex
è un indice generato da un hash costituito dalla chiave composita(PlayedId
e LeagueId
). Ha puntatori alle righe di dati che rappresenta. L'uso di un tale indice facilita il recupero dei dati rapido e ad accesso diretto, al contrario del recupero sequenziale lineare dei dati. Ad esempio, per determinare tutti i giocatori associati a "Doppio maschile" da diversi record in ciascuna delle tabelle precedenti, puoi emettere il seguente comando SQL:
SELECT Player.LastName, Player.Firstname
FROM Player, Membership
WHERE Membership.LeagueId = 2
AND Membership.PlayerId = Player.PlayerId
Vengono restituiti i seguenti dati:
+----------+-----------+
| LastName | FirstName |
+----------+-----------+
| Smith | John |
| Hansen | Robert |
+-----------+----------+
Senza l'uso di MembershipIndex
e PlayerIndex
, la query precedente verrebbe eseguita molto più lentamente.
Indici non univoci
Un indice non univoco contiene voci che possono puntare a una o più righe per qualsiasi valore chiave specificato. Ad esempio, per cercare per nome di una persona, è necessario creare un indice composito non univoco su una tabella sia per FirstName
e LastName
. Poiché la combinazione di FirstName
e LastName
non può essere garantito che sia univoco, l'indice risultante creato su queste due colonne genera effettivamente un indice non univoco.
Problema di degrado delle prestazioni del database utilizzando gli indici
Sebbene gli indici aiutino la velocità di esecuzione delle query, devono essere aggiornati ogni volta che le colonne indicizzate cambiano o quando le righe della tabella vengono aggiunte o eliminate dal database. Questo può essere dannoso per le prestazioni del database. È importante tenere a mente la quantità di inserimento, eliminazione e modifica richiesta degli indici durante l'utilizzo del database transazionale. Considera cosa è importante per te nell'applicazione di database; la velocità di esecuzione della query o la velocità di manipolazione dei dati. La risposta a questa domanda risiede nel modo in cui viene utilizzata l'applicazione del database, con quale frequenza influisce sulla progettazione del database e nel numero di indici creati.
Conclusione
La creazione e l'utilizzo di indici di database genera risposte rapide per il recupero delle query ed elimina le ricerche di righe sequenziali dalle tabelle. Tuttavia, la manutenzione dell'indice tramite la manipolazione dei dati può avere un impatto negativo sulle prestazioni di un database. I progettisti di database devono essere consapevoli dei compromessi coinvolti nell'utilizzo degli indici di database e tenere a mente l'ottimizzazione per le prestazioni complessive del database.