In SQLite, een AUTOINCREMENT
kolom is er een die een automatisch verhoogde waarde gebruikt voor elke rij die in de tabel wordt ingevoegd.
Er zijn een aantal manieren waarop u een AUTOINCREMENT
. kunt maken kolom:
- U kunt het impliciet maken als u de kolom definieert als
INTEGER PRIMARY KEY
. - Je kunt het expliciet maken met de
AUTOINCREMENT
trefwoord. Een nadeel van deze methode is dat het extra CPU, geheugen, schijfruimte en schijf-I/O-overhead gebruikt.
Beide methoden zorgen ervoor dat de kolom een oplopende waarde gebruikt telkens wanneer een nieuwe rij wordt ingevoegd met NULL
in die kolom.
Er zijn echter enkele subtiele verschillen tussen hoe elke methode werkt.
Zonder het AUTOINCREMENT-zoekwoord
Wanneer u een kolom declareert als INTEGER PRIMARY KEY
, wordt deze automatisch verhoogd. Daarom hoeft u de AUTOINCREMENT
. niet te gebruiken zoekwoord om een kolom te hebben die een automatisch oplopende waarde gebruikt voor elke rij.
Wanneer u dit doet, wordt elke NULL
waarden worden geconverteerd naar de huidige ROWID
. Met andere woorden, als u NULL
. invoegt in die kolom, wordt het geconverteerd naar de huidige ROWID
.
De manier waarop het werkt, is dat de kolom een alias wordt voor de ROWID
. U heeft toegang tot de ROWID
waarde door een van de vier namen te gebruiken; de kolomnaam, ROWID
, _ROWID_
, of OID
.
Een voordeel van het weglaten van de AUTOINCREMENT
sleutelwoord is dat het CPU, geheugen, schijfruimte en schijf-I/O-overhead vermindert.
Een belangrijk nadeel is echter dat u niet kunt garanderen dat alle rijen in oplopende volgorde worden verhoogd. Dit komt door de manier waarop automatisch verhogen werkt bij het weglaten van de AUTOINCREMENT
zoekwoord versus het gebruik van dat zoekwoord.
Wanneer u de AUTOINCREMENT
. weglaat zoekwoord, eenmaal ROWID
gelijk is aan het grootst mogelijke gehele getal (9223372036854775807), zal SQLite proberen een ongebruikte positieve ROWID
te vinden willekeurig.
Zolang u echter nooit de maximale ROWID
. gebruikt waarde en u verwijdert nooit het item in de tabel met de grootste ROWID
, genereert deze methode monotoon toenemende unieke ROWID
v.
Met het AUTOINCREMENT-zoekwoord
U kunt ook expliciet automatisch oplopende kolommen maken. Gebruik hiervoor de AUTOINCREMENT
trefwoord.
Wanneer u deze methode gebruikt, wordt een iets ander algoritme gebruikt om de automatisch verhoogde waarde te bepalen.
Wanneer u de AUTOINCREMENT
. gebruikt zoekwoord, de ROWID
gekozen voor de nieuwe rij is minstens één groter dan de grootste ROWID
dat heeft ooit bestond eerder in diezelfde tabel.
Met andere woorden, het gaat niet terug en hergebruikt eerder verwijderde ROWID
waarden. Eens de grootst mogelijke ROWID
is ingevoegd, zijn geen nieuwe invoegingen toegestaan. Elke poging om een nieuwe rij in te voegen mislukt met een SQLITE_FULL
fout.
Daarom garandeert het gebruik van deze methode dat de ROWID
s nemen monotoon toe. Met andere woorden, u kunt op deze methode vertrouwen om ROWID
. te hebben s in oplopende volgorde.
Dit betekent echter niet dat de waarden altijd met 1 zullen toenemen. Het betekent alleen dat ze nooit zullen afnemen.
Voorbeeld
Hier is een voorbeeld om het verschil aan te tonen tussen het impliciet en expliciet definiëren van een kolom voor automatisch ophogen.
CREATE TABLE Cats(
CatId INTEGER PRIMARY KEY,
CatName
);
CREATE TABLE Dogs(
DogId INTEGER PRIMARY KEY AUTOINCREMENT,
DogName
);
INSERT INTO Cats VALUES
( NULL, 'Brush' ),
( NULL, 'Scarcat' ),
( NULL, 'Flutter' );
INSERT INTO Dogs VALUES
( NULL, 'Yelp' ),
( NULL, 'Woofer' ),
( NULL, 'Fluff' );
SELECT * FROM Cats;
SELECT * FROM Dogs;
Eerste resultaat:
CatId CatName ---------- ---------- 1 Brush 2 Scarcat 3 Flutter DogId DogName ---------- ---------- 1 Yelp 2 Woofer 3 Fluff
Laten we nu de laatste rij in elke tabel verwijderen, de rijen opnieuw invoegen en het resultaat selecteren:
DELETE FROM Cats WHERE CatId = 3;
DELETE FROM Dogs WHERE DogId = 3;
INSERT INTO Cats VALUES ( NULL, 'New Flutter' );
INSERT INTO Dogs VALUES ( NULL, 'New Fluff' );
SELECT * FROM Cats;
SELECT * FROM Dogs;
Resultaat:
CatId CatName ---------- ---------- 1 Brush 2 Scarcat 3 New Flutter DogId DogName ---------- ---------- 1 Yelp 2 Woofer 4 New Fluff
Om samen te vatten, de Katten tabel is gemaakt zonder de AUTOINCREMENT
zoekwoord, en de Honden tabel is gemaakt met de AUTOINCREMENT
zoekwoord.
Na het verwijderen van de laatste rij uit de Cats tabel, de volgende INSERT
operatie resulteerde in dezelfde ROWID
wordt hergebruikt voor die rij.
Echter, de Honden tafel was anders. Het is gemaakt met de AUTOINCREMENT
zoekwoord en daarom kan het de vorige waarde niet opnieuw gebruiken. Het wordt gewoon verhoogd naar de volgende waarde, waardoor er een gat in de nummering blijft.
Maximale ROWID
We kunnen het vorige voorbeeld een stap verder nemen en een nieuwe rij invoegen door expliciet de maximale ROWID
te gebruiken mogelijk.
INSERT INTO Cats VALUES ( 9223372036854775807, 'Magnus' );
INSERT INTO Dogs VALUES ( 9223372036854775807, 'Maximus' );
SELECT * FROM Cats;
SELECT * FROM Dogs;
Resultaat:
CatId CatName -------------------- -------------------- 1 Brush 2 Scarcat 3 New Flutter 9223372036854775807 Magnus DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 9223372036854775807 Maximus
OK, dus beide tabellen gebruiken het grootst mogelijke gehele getal als hun grootste ROWID
waarden.
Laten we eens kijken wat er gebeurt als ik een nieuwe rij in elke tabel probeer in te voegen (zonder expliciet een waarde op te geven voor de automatisch oplopende kolommen).
Invoegen in de Katten tafel:
INSERT INTO Cats VALUES ( NULL, 'Scratchy' );
SELECT * FROM Cats;
Resultaat:
CatId CatName -------------------- -------------------- 1 Brush 2 Scarcat 3 New Flutter 267244677462397326 Scratchy 9223372036854775807 Magnus
Dus de Katten tafel is gelukt. Merk echter op dat de nieuwe waarde voor automatisch ophogen lager is dan de vorige waarde (het heeft geen andere optie).
Zonder een andere kolom om de datum/tijd vast te leggen waarop de rij is ingevoegd/bijgewerkt, zou men ten onrechte kunnen aannemen dat Magnus werd ingevoegd na Scratchy .
Laten we nu proberen een nieuwe rij in te voegen in de Honden tafel:
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );
Resultaat:
Error: database or disk is full
We krijgen dus een ander resultaat dan de Katten tafel.
Ik kreeg deze fout omdat de grootst mogelijke ROWID
al in de tabel wordt gebruikt, en omdat deze tabel is gemaakt met de AUTOINCREMENT
zoekwoord, zal het niet teruggaan en zoeken naar een ongebruikte ROWID
waarde.
SELECT * FROM Dogs;
Resultaat:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 9223372036854775807 Maximus
Bovendien blijf ik deze fout krijgen, zelfs als ik Maximus . verwijder uit de tabel (d.w.z. de hond met de maximale ROWID
waarde).
Laten we het proberen:
DELETE FROM Dogs WHERE DogId = 9223372036854775807;
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );
Resultaat:
Error: database or disk is full
We krijgen dus niet alleen een foutmelding, maar ik heb ook Maximus . verwijderd :
SELECT * FROM Dogs;
Resultaat:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff
Het is belangrijk op te merken dat dit ook gebeurt als ik de ROWID
. wijzig waarde naar een lagere waarde. Het feit dat ik al een ROWID van 9223372036854775807 heb gebruikt, betekent dat AUTOINCREMENT
wordt niet meer automatisch verhoogd.
Dit komt omdat AUTOINCREMENT
gebruikt alleen waarden die ten minste één hoger zijn dan enige waarde die ooit eerder in diezelfde tabel heeft bestaan .
Als ik voortaan waarden in deze kolom wilde blijven invoegen, zou ik de waarde expliciet moeten invoegen. Dit veronderstelt dat ik nog geen 9223372036854775807 rijen in de tabel heb.
Laten we Maximus opnieuw invoegen met een lagere ROWID
en probeer het opnieuw:
INSERT INTO Dogs VALUES ( 5, 'Maximus' );
SELECT * FROM Dogs;
Resultaat:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 5 Maximus
Laten we nu proberen Lickable . in te voegen nogmaals, met behulp van AUTOINCREMENT
:
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );
Resultaat:
Error: database or disk is full
Dus ook al heb ik de rij verwijderd die de maximale ROWID
bevat waarde van 9223372036854775807, het nog voorkomt dat ik de kolom automatisch kan verhogen.
Dit is precies hoe het is ontworpen. De maximale ROWID
heeft eerder in deze tabel gestaan en dus AUTOINCREMENT
wordt niet automatisch opnieuw verhoogd in die tabel.
De enige manier om een nieuwe rij aan die tabel toe te voegen, is door handmatig de ROWID
. in te voegen waarde.
INSERT INTO Dogs VALUES (6, 'Lickable');
SELECT * FROM Dogs;
Resultaat:
DogId DogName -------------------- -------------------- 1 Yelp 2 Woofer 4 New Fluff 5 Maximus 6 Lickable