SQLite har en interessant måde at håndtere auto-increment-kolonner på. Med auto-inkrementering af kolonner, mener jeg kolonner, der øges automatisk, hver gang nye data indsættes.
Dette ligner en IDENTITY
kolonne i SQL Server eller en AUTO_INCREMENT
kolonne i MySQL
.
Denne artikel forklarer, hvordan du opretter AUTOINCREMENT
kolonner i SQLite.
Opret automatisk en automatisk stigningskolonne
Som standard, når du definerer en kolonne som INTEGER PRIMARY KEY
, vil den automatisk stige, når du indsætter NULL i den kolonne.
Eksempel:
CREATE TABLE Cats(
CatId INTEGER PRIMARY KEY,
CatName
);
I denne tabel er CatId kolonne er en autoincrement-kolonne. Dette skyldes, at det er blevet defineret ved hjælp af INTEGER PRIMARY KEY
.
Når jeg nu indsætter NULL i den kolonne, vises CatId automatiske stigninger i kolonnen:
INSERT INTO Cats VALUES
( NULL, 'Brush' ),
( NULL, 'Scarcat' ),
( NULL, 'Flutter' );
SELECT * FROM Cats;
Resultat:
CatId CatName ---------- ---------- 1 Brush 2 Scarcat 3 Flutter
Det er vigtigt at bemærke, at du kan tilsidesætte AUTOINCREMENT
værdi ved at indsætte din egen værdi. Med andre ord, AUTOINCREMENT
indsætter kun en værdi, hvis du ikke gør det.
Måden det fungerer på er NULL
konverteres automatisk til et heltal, der er et større end den største værdi af den pågældende kolonne over alle andre rækker i tabellen. Hvis tabellen er tom, vil værdien være 1
.
Hvis den største værdi af kolonnen er det størst mulige heltal (9223372036854775807), vil SQLite vælge en ubrugt nøgle tilfældigt. Dette betyder typisk, at den vil genbruge gamle nøgler, der tidligere blev slettet. Hvis en ubrugt nøgle ikke kan findes, skal INSERT
handling mislykkes med en SQLITE_FULL
fejl.
Grundlæggende betyder dette, hvis du tillader DELETE
operationer i tabellen, så er der ingen garanti for, at alle rækker er i orden. Der er en mulighed for, at nogle rækker vil have en højere værdi end rækker indsat på et senere tidspunkt.
Derfor kan du i sådanne tilfælde ikke stole på denne kolonne, hvis du skal bestille tabellen i stigende eller faldende rækkefølge, baseret på rækkefølgen, som rækkerne blev indsat.
Heldigvis, hvis dette er et problem for dig, er der en løsning:AUTOINCREMENT
søgeord.
Brug søgeordet AUTOINCREMENT
Alternativt kan du vælge eksplicit at indstille kolonnen til automatisk stigning ved at bruge AUTOINCREMENT
søgeord.
En fordel ved at bruge denne metode er, at den garanterer, at alle rækker vil være i stigende rækkefølge. Dette skyldes, at den ikke genbruger tidligere slettede nøgler. Hver nøgle vil altid være én mere end den største nøgle, der nogensinde har eksisteret i den tabel. Hvis den størst mulige nøgle tidligere har eksisteret i den tabel, vil den ikke prøv at bruge tidligere slettede nøgler. INSERT
mislykkes med en SQLITE_FULL
fejlkode.
Ulempen ved at bruge AUTOINCREMENT
nøgleordet er, at det bruger ekstra CPU, hukommelse, diskplads og disk I/O-overhead.
Her er et eksempel på oprettelse af en automatisk stigningskolonne med AUTOINCREMENT
søgeord:
CREATE TABLE Dogs(
DogId INTEGER PRIMARY KEY AUTOINCREMENT,
DogName
);
Indsæt nu data og vælg det:
INSERT INTO Dogs VALUES
( NULL, 'Yelp' ),
( NULL, 'Woofer' ),
( NULL, 'Fluff' );
SELECT * FROM Dogs;
Resultat:
DogId DogName ---------- ---------- 1 Yelp 2 Woofer 3 Fluff
Hvis jeg skulle slette Fluff fra denne tabel, indsæt derefter en ny række (ved hjælp af NULL
som DogId), ville det nye DogId være 4. Med andre ord ville det ikke genbruge 3.
Hvis kolonnen var blevet oprettet uden AUTOINCREMENT
søgeord, så ville den næste række genbruge DogId of 3.
Hvis jeg skulle indsætte et DogId på 9223372036854775807 (det størst mulige heltal), ville jeg modtage følgende fejl ved den næste indsættelse, der angiver NULL
for den kolonne:
Error: database or disk is full
Jeg kunne dog udtrykkeligt indsætte en værdi, der er lavere end 9223372036854775807, så længe denne værdi ikke allerede bruges af en anden række, og INSERT
handlingen skulle lykkes uden ovenstående fejl.
Dybest set, når du når 9223372036854775807, vil den automatiske stigning ikke længere virke.
Kolonner defineret uden AUTOINCREMENT
søgeord har ikke dette problem. De vil automatisk gå tilbage og forsøge at finde et ubrugt heltal at bruge i stedet. Men hvis alle heltal er blevet brugt (dvs. tabellen faktisk indeholder 9223372036854775807 rækker), vil selv disse kolonner resultere i ovenstående fejl.