SQLite má zajímavý způsob zpracování sloupců automatického přírůstku. Auto-inkrementací sloupců mám na mysli sloupce, které se automaticky zvyšují při každém vložení nových dat.
Je to podobné jako IDENTITY
sloupec v SQL Server nebo AUTO_INCREMENT
v MySQL
.
Tento článek vysvětluje, jak vytvořit AUTOINCREMENT
sloupce v SQLite.
Automaticky vytvořit sloupec automatického zvýšení
Ve výchozím nastavení, když definujete sloupec jako INTEGER PRIMARY KEY
, automaticky se zvýší, kdykoli do tohoto sloupce vložíte hodnotu NULL.
Příklad:
CREATE TABLE Cats(
CatId INTEGER PRIMARY KEY,
CatName
);
V této tabulce CatId sloupec je sloupec s automatickým přírůstkem. Je to proto, že byl definován pomocí INTEGER PRIMARY KEY
.
Nyní, když do tohoto sloupce vložím hodnotu NULL, CatId automatické přírůstky sloupců:
INSERT INTO Cats VALUES
( NULL, 'Brush' ),
( NULL, 'Scarcat' ),
( NULL, 'Flutter' );
SELECT * FROM Cats;
Výsledek:
CatId CatName ---------- ---------- 1 Brush 2 Scarcat 3 Flutter
Je důležité si uvědomit, že AUTOINCREMENT
můžete přepsat hodnotu vložením vlastní hodnoty. Jinými slovy, AUTOINCREMENT
vloží hodnotu pouze v případě, že tak neučiníte.
Funguje to tak, že NULL
se automaticky převede na celé číslo, které je o jedničku větší než největší hodnota daného sloupce nad všemi ostatními řádky v tabulce. Pokud je tabulka prázdná, hodnota bude 1
.
Pokud je největší hodnota sloupce největší možné celé číslo (9223372036854775807), SQLite náhodně vybere nepoužívaný klíč. To obvykle znamená, že znovu použije staré klíče, které byly dříve odstraněny. Pokud nelze najít nepoužívaný klíč, INSERT
operace se nezdaří s SQLITE_FULL
chyba.
V podstatě to znamená, že pokud povolíte DELETE
operací v tabulce, pak není zaručeno, že všechny řádky budou v pořádku. Je možné, že některé řádky budou mít vyšší hodnotu než řádky vložené později.
V takových případech se tedy na tento sloupec nemůžete spolehnout, pokud potřebujete tabulku seřadit vzestupně nebo sestupně podle pořadí, ve kterém byly řádky vloženy.
Naštěstí, pokud je to pro vás problém, existuje řešení:AUTOINCREMENT
klíčové slovo.
Použijte klíčové slovo AUTOINCREMENT
Případně můžete explicitně nastavit sloupec na automatické zvýšení pomocí AUTOINCREMENT
klíčové slovo.
Jednou z výhod použití této metody je, že zaručuje, že všechny řádky budou ve vzestupném pořadí. Je to proto, že znovu nepoužívá dříve smazané klíče. Každý klíč bude vždy o jeden větší než největší klíč, který kdy v dané tabulce existoval. Pokud v této tabulce dříve existoval největší možný klíč, nebude zkuste použít dříve smazané klíče. INSERT
selže s SQLITE_FULL
kód chyby.
Nevýhoda použití AUTOINCREMENT
klíčové slovo je, že využívá extra CPU, paměť, místo na disku a režii I/O disku.
Zde je příklad vytvoření automaticky se zvyšujícího sloupce pomocí AUTOINCREMENT
klíčové slovo:
CREATE TABLE Dogs(
DogId INTEGER PRIMARY KEY AUTOINCREMENT,
DogName
);
Nyní vložte data a vyberte je:
INSERT INTO Dogs VALUES
( NULL, 'Yelp' ),
( NULL, 'Woofer' ),
( NULL, 'Fluff' );
SELECT * FROM Dogs;
Výsledek:
DogId DogName ---------- ---------- 1 Yelp 2 Woofer 3 Fluff
Pokud bych měl odstranit Fluff z této tabulky a poté vložte nový řádek (pomocí NULL
jako DogId), nové DogId bude 4. Jinými slovy, nebude znovu používat 3.
Pokud byl sloupec vytvořen bez AUTOINCREMENT
klíčové slovo, pak další řádek znovu použije DogId z 3.
Pokud bych vložil DogId 9223372036854775807 (největší možné celé číslo), při dalším vložení bych obdržel následující chybu, která specifikuje NULL
pro tento sloupec:
Error: database or disk is full
Mohl bych však explicitně vložit hodnotu, která je nižší než 9223372036854775807, pokud tato hodnota již není používána jiným řádkem, a INSERT
operace by měla být úspěšná bez výše uvedené chyby.
V zásadě, jakmile dosáhnete 9223372036854775807, automatické zvýšení již nebude fungovat.
Sloupce definované bez AUTOINCREMENT
klíčové slovo tento problém nemá. Automaticky se vrátí a pokusí se najít nepoužité celé číslo, které by místo toho použili. Pokud však byla použita všechna celá čísla (tj. tabulka ve skutečnosti obsahuje 9223372036854775807 řádků), pak i tyto sloupce povedou k výše uvedené chybě.