SQLite
 sql >> база данни >  >> RDS >> SQLite

Как работи AUTOINCREMENT в SQLite

В SQLite, AUTOINCREMENT колоната е тази, която използва автоматично увеличена стойност за всеки ред, който е вмъкнат в таблицата.

Има няколко начина, по които можете да създадете AUTOINCREMENT колона:

  • Можете да го създадете имплицитно, когато дефинирате колоната като INTEGER PRIMARY KEY .
  • Можете да го създадете изрично с AUTOINCREMENT ключова дума. Един недостатък на този метод е, че използва допълнителен процесор, памет, дисково пространство и дискови входно/изходни разходи.

И двата метода карат колоната да използва нарастваща стойност всеки път, когато се вмъкне нов ред с NULL в тази колона.

Има обаче някои фини разлики между начина, по който работи всеки метод.

Без ключовата дума AUTOINCREMENT

Когато декларирате колона като INTEGER PRIMARY KEY , той автоматично ще се увеличи. Следователно всъщност не е необходимо да използвате AUTOINCREMENT ключова дума, за да има колона, която използва автоматично нарастваща стойност за всеки ред.

Когато направите това, всеки NULL стойностите се преобразуват в текущия ROWID . С други думи, ако въведете NULL в тази колона, тя ще бъде преобразувана в текущия ROWID .

Всъщност начинът, по който работи е, че колоната става псевдоним за ROWID . Можете да получите достъп до ROWID стойност, като използвате някое от четирите имена; името на колоната, ROWID , _ROWID_ или OID .

Едно предимство от пропускането на AUTOINCREMENT ключова дума е, че намалява процесора, паметта, дисковото пространство и разходите за вход/изход на диска.

Важен недостатък обаче е, че не можете да гарантирате, че всички редове ще бъдат увеличени във възходящ ред. Това се дължи на начина, по който работи автоматичното увеличаване при пропускане на AUTOINCREMENT ключова дума спрямо използването на тази ключова дума.

Когато пропуснете AUTOINCREMENT ключова дума, веднъж ROWID е равно на възможно най-голямото цяло число (9223372036854775807), SQLite ще се опита да намери неизползван положителен ROWID на случаен принцип.

Въпреки това, стига никога да не използвате максималния ROWID стойност и никога не изтривате записа в таблицата с най-големия ROWID , този метод ще генерира монотонно нарастващ уникален ROWID с.

С ключовата дума AUTOINCREMENT

Можете също така изрично да създавате автоматично увеличаващи се колони. За да направите това, използвайте AUTOINCREMENT ключова дума.

Когато използвате този метод, се използва малко по-различен алгоритъм за определяне на автоматично увеличената стойност.

Когато използвате AUTOINCREMENT ключова дума, ROWID избраният за новия ред е поне един по-голям от най-големия ROWID което е някога преди е съществувал в същата таблица.

С други думи, няма да се върне и да използва повторно изтрития ROWID стойности. Веднъж възможно най-големият ROWID е вмъкнат, не са разрешени нови вмъквания. Всеки опит за вмъкване на нов ред ще се провали с SQLITE_FULL грешка.

Следователно използването на този метод гарантира, че ROWID s се увеличават монотонно. С други думи, можете да разчитате на този метод за наличието на ROWID s във възходящ ред.

Това обаче не означава, че стойностите винаги ще се увеличават с 1. Това просто означава, че те никога няма да намалеят.

Пример

Ето пример за демонстриране на разликата между имплицитно и изрично дефиниране на колона с автоматично увеличение.

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;

Първоначален резултат:

CatId       CatName   
----------  ----------
1           Brush     
2           Scarcat   
3           Flutter  

DogId       DogName   
----------  ----------
1           Yelp      
2           Woofer    
3           Fluff      

Сега нека изтрием последния ред във всяка таблица, вмъкнете редовете отново, след което изберете резултата:

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;

Резултат:

CatId       CatName   
----------  ----------
1           Brush     
2           Scarcat   
3           New Flutter

DogId       DogName   
----------  ----------
1           Yelp      
2           Woofer    
4           New Fluff 

За да обобщим, Котките таблицата е създадена без AUTOINCREMENT ключова дума и Кучета таблицата е създадена с AUTOINCREMENT ключова дума.

След като изтриете последния ред от Котки таблица, следващият INSERT операцията доведе до същия ROWID се използва повторно за този ред.

Въпреки това, вкучетата масата беше различна. Създаден е с AUTOINCREMENT ключова дума и следователно не може да използва повторно предишната стойност. Просто се увеличава до следващата стойност, оставяйки празнина в номерацията.

Максимален ROWID

Можем да вземем предишния пример още една стъпка и да вмъкнем нов ред, като изрично използваме максималния ROWID възможно.

INSERT INTO Cats VALUES ( 9223372036854775807, 'Magnus' );
INSERT INTO Dogs VALUES ( 9223372036854775807, 'Maximus' );

SELECT * FROM Cats;
SELECT * FROM Dogs;

Резултат:

CatId                 CatName             
--------------------  --------------------
1                     Brush               
2                     Scarcat             
3                     New Flutter         
9223372036854775807   Magnus              

DogId                 DogName             
--------------------  --------------------
1                     Yelp                
2                     Woofer              
4                     New Fluff           
9223372036854775807   Maximus             

Добре, така че и двете таблици използват най-голямото възможно цяло число като най-голямото им ROWID стойности.

Нека видим какво се случва, когато се опитам да вмъкна нов ред във всяка таблица (без изрично да посоча стойност за автоматично увеличаващите се колони).

Вмъкнете в Котки таблица:

INSERT INTO Cats VALUES ( NULL, 'Scratchy' );
SELECT * FROM Cats;

Резултат:

CatId                 CatName             
--------------------  --------------------
1                     Brush               
2                     Scarcat             
3                     New Flutter         
267244677462397326    Scratchy            
9223372036854775807   Magnus              

И така, Котките масата беше успешна. Забележете обаче, че новата стойност за автоматично нарастване е по-ниска от предишната стойност (няма друга опция).

Без да има друга колона за записване на датата/часа, когато редът е бил вмъкнат/актуализиран, може да се предположи погрешно, че Магнус беше вмъкнат след Scratchy .

Сега нека се опитаме да вмъкнем нов ред в Кучетата таблица:

INSERT INTO Dogs VALUES ( NULL, 'Lickable' );

Резултат:

Error: database or disk is full

Така получаваме различен резултат от Котките таблица.

Получих тази грешка, защото най-големият възможен ROWID вече се използва в таблицата и тъй като тази таблица е създадена с AUTOINCREMENT ключова дума, няма да се върне и да търси неизползван ROWID стойност.

SELECT * FROM Dogs;

Резултат:

DogId                 DogName             
--------------------  --------------------
1                     Yelp                
2                     Woofer              
4                     New Fluff           
9223372036854775807   Maximus             

Освен това ще продължа да получавам тази грешка, дори ако изтрия Maximus от таблицата (т.е. кучето с максимален ROWID стойност).

Нека опитаме:

DELETE FROM Dogs WHERE DogId = 9223372036854775807;
INSERT INTO Dogs VALUES ( NULL, 'Lickable' );

Резултат:

Error: database or disk is full

Така че не само получаваме грешка, но и изтрих Maximus :

SELECT * FROM Dogs;

Резултат:

DogId                 DogName             
--------------------  --------------------
1                     Yelp                
2                     Woofer              
4                     New Fluff           

Важно е да се отбележи, че това ще се случи дори ако сменя ROWID стойност на по-ниска стойност. Фактът, че вече съм използвал ROWID от 9223372036854775807, означава, че AUTOINCREMENT вече няма да се увеличава автоматично.

Това е така, защото AUTOINCREMENT използва само стойности, които са поне една по-високи от всяка стойност, която някога е съществувала в същата таблица .

Оттук нататък, ако искам да продължа да вмъквам стойности в тази колона, ще трябва изрично да вмъкна стойността. Това предполага, че вече нямам 9223372036854775807 реда в таблицата.

Нека вмъкнем отново Максимус с по-нисък ROWID и опитайте отново:

INSERT INTO Dogs VALUES ( 5, 'Maximus' );
SELECT * FROM Dogs;

Резултат:

DogId                 DogName             
--------------------  --------------------
1                     Yelp                
2                     Woofer              
4                     New Fluff           
5                     Maximus            

Сега нека се опитаме да вмъкнем Lickable още веднъж с помощта на AUTOINCREMENT :

INSERT INTO Dogs VALUES ( NULL, 'Lickable' );

Резултат:

Error: database or disk is full

Така че, въпреки че изтрих реда, който съдържа максималния ROWID стойност на 9223372036854775807, все още не ми позволява автоматично да увеличавам колоната.

Точно така е проектирана. Максималният ROWID е бил преди това в тази таблица и така AUTOINCREMENT няма да се увеличава автоматично отново в тази таблица.

Единственият начин да добавите нов ред към тази таблица е да вмъкнете ръчно ROWID стойност.

INSERT INTO Dogs VALUES (6, 'Lickable');
SELECT * FROM Dogs;

Резултат:

DogId                 DogName             
--------------------  --------------------
1                     Yelp                
2                     Woofer              
4                     New Fluff           
5                     Maximus             
6                     Lickable            


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Показване на резултатите от заявката на SQLite с помощта на вертикален изход

  2. задайте правилно sqlite db в android

  3. Дата и час в SQLite

  4. SQLite JSON_GROUP_OBJECT()

  5. как да получите изображение от drawable според техните имена в базата данни sqlite и след това да го покажете в изглед на списък