sql >> Databasteknik >  >> RDS >> SQLite

SQLite AUTOINCREMENT

Sammanfattning :i denna handledning kommer du att lära dig om SQLite AUTOINCREMENT kolumnattribut och när det ska användas i din tabell.

Introduktion till SQLite ROWID tabell

När du skapar en tabell utan att ange WITHOUT ROWID alternativet får du en underförstådd kolumn för automatisk inkrementering som heter rowid . rowid kolumnlager 64-bitars signerat heltal som unikt identifierar en rad i tabellen.

Låt oss se följande exempel.

Skapa först en ny tabell med namnet people som har två kolumner:first_name, och last_name :

CREATE TABLE people (
   first_name TEXT NOT NULL,
   last_name TEXT NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Prova det

För det andra, infoga en rad i people tabell med följande INSERT uttalande:

INSERT INTO people (first_name, last_name)
VALUES('John', 'Doe');Code language: SQL (Structured Query Language) (sql)

Prova det

För det tredje, fråga data från people tabell med följande SELECT uttalande:

SELECT
   rowid,
   first_name,
   last_name
FROM
   people;Code language: SQL (Structured Query Language) (sql)

Prova det

Som du tydligt kan se från utdata skapar SQLite implicit en kolumn med namnet rowid och tilldelar automatiskt ett heltalsvärde när du infogar en ny rad i tabellen.

Observera att du också kan hänvisa till rowid kolumn med dess alias:_rowid_ och oid .

När du skapar en tabell som har en INTEGER PRIMARY KEY kolumnen är denna kolumn aliaset för rowid kolumn.

Följande påstående tar bort tabellen people och återskapar det. Den här gången lägger vi dock till en annan kolumn med namnet person_id vars datatyp är INTEGER och kolumnbegränsningen är PRIMARY KEY :

DROP TABLE people;

CREATE TABLE people (
   person_id INTEGER PRIMARY KEY,
   first_name TEXT NOT NULL,
   last_name TEXT NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Prova det

I det här fallet, person_id kolumnen är faktiskt rowid kolumn.

Hur tilldelar SQLite ett heltalsvärde till rowid kolumn?

Om du inte anger rowid eller så använder du en NULL värde när du infogar en ny rad tilldelar SQLite automatiskt nästa sekventiella heltal, vilket är ett större än den största rowid i bordet. rowid värde börjar på 1.

Det maximala värdet för rowid kolumnen är 9,223,372,036,854,775,807 , vilket är väldigt stort. Om din data når detta maximala värde och du försöker infoga en ny rad, kommer SQLite att hitta ett oanvänt heltal och använda det. Om SQLite inte kan hitta något oanvänt heltal kommer det att utfärda en SQLITE_FULL fel. Utöver det, om du tar bort några rader och infogar en ny rad, kommer SQLite att försöka återanvända rowid värden från de raderade raderna.

Låt oss testa det.

Först infogar du en rad med det maximala värdet i people bord.

INSERT INTO people (person_id,first_name,last_name)
VALUES(	9223372036854775807,'Johnathan','Smith');Code language: SQL (Structured Query Language) (sql)

Prova det

För det andra, infoga en annan rad utan att ange ett värde för person_id kolumn:

INSERT INTO people (first_name,last_name)
VALUES('William','Gate');Code language: SQL (Structured Query Language) (sql)

Prova det

Som tydligt framgår av utgången fick den nya raden ett oanvänt heltal.

Tänk på ett annat exempel.

Skapa först en ny tabell med namnet t1 som har en kolumn:

CREATE TABLE t1(c text);Code language: SQL (Structured Query Language) (sql)

För det andra, infoga några rader i t1 tabell:

INSERT INTO t1(c) VALUES('A');
INSERT INTO t1(c) values('B');
INSERT INTO t1(c) values('C');
INSERT INTO t1(c) values('D');
Code language: SQL (Structured Query Language) (sql)

För det tredje, fråga efter data från t1 tabell:

SELECT rowid, c FROM t1;Code language: SQL (Structured Query Language) (sql)

För det fjärde, ta bort alla rader i t1 tabell:

DELETE FROM t1;Code language: SQL (Structured Query Language) (sql)

För det femte, infoga några rader i t1 tabell:

INSERT INTO t1(c) values('E');
INSERT INTO t1(c) values('F');
INSERT INTO t1(c) values('G');Code language: SQL (Structured Query Language) (sql)

Fråga slutligen data från t1 tabell:

SELECT rowid, c FROM t1;
Code language: SQL (Structured Query Language) (sql)

Som du kan se har raderna 1, 2 och 3 återanvänts för de nya raderna.

SQLite AUTOINCREMENT kolumnattribut

SQLite rekommenderar att du inte använder AUTOINCREMENT attribut eftersom:

AUTOINCREMENT nyckelordet medför extra CPU, minne, diskutrymme och disk I/O-overhead och bör undvikas om det inte är absolut nödvändigt. Det behövs vanligtvis inte.

Dessutom sättet SQLite tilldelar ett värde för AUTOINCREMENT kolumnen något annorlunda från hur den gör för rowid kolumn.

Tänk på följande exempel.

Släpp först och återskapa people tabell. Den här gången använder vi AUTOINCREMENT attributkolumn:

DROP TABLE people;

CREATE TABLE people (
   person_id INTEGER PRIMARY KEY AUTOINCREMENT,
   first_name text NOT NULL,
   last_name text NOT NULL
);Code language: SQL (Structured Query Language) (sql)

Prova det

För det andra, infoga en rad med den maximala rowid värde till people bord.

INSERT INTO people (person_id,first_name,last_name)
VALUES(9223372036854775807,'Johnathan','Smith');Code language: SQL (Structured Query Language) (sql)

Prova det

För det tredje, infoga ytterligare en rad i people bord.

INSERT INTO people (first_name,last_name)
VALUES('John','Smith');Code language: SQL (Structured Query Language) (sql)

Prova det

Den här gången skickade SQLite ett felmeddelande eftersom person_id kolumnen återanvände inte numret som en rowid kolumn.

[Err] 13 - database or disk is fullCode language: SQL (Structured Query Language) (sql)

När ska du använda AUTOINCREMENT kolumnattribut?

Huvudsyftet med att använda attributet AUTOINCREMENT är att förhindra att SQLite återanvänder ett värde som inte har använts eller ett värde från den tidigare raderade raden.

Om du inte har några krav som detta bör du inte använda AUTOINCREMENT attribut i primärnyckeln.

I den här handledningen har du lärt dig hur SQLite AUTOINCREMENT attribut fungerar och hur det påverkar hur SQLite tilldelar värden till primärnyckelkolumnen.


  1. Java-typ för datum/tid när du använder Oracle Date med Hibernate

  2. Vad gör DELIMITER // i en utlösare?

  3. Vad är skillnaden mellan LATERAL JOIN och en underfråga i PostgreSQL?

  4. En databasmodell för en onlineundersökning. Del 3