SQLite
 sql >> Baza danych >  >> RDS >> SQLite

Jak działa AUTOINCREMENT w SQLite

W SQLite, AUTOINCREMENT kolumna to taka, która używa automatycznie zwiększanej wartości dla każdego wiersza wstawionego do tabeli.

Istnieje kilka sposobów na utworzenie AUTOINCREMENT kolumna:

  • Możesz go utworzyć niejawnie, gdy zdefiniujesz kolumnę jako INTEGER PRIMARY KEY .
  • Możesz go utworzyć jawnie za pomocą AUTOINCREMENT słowo kluczowe. Jedną z wad tej metody jest to, że wykorzystuje dodatkowy procesor, pamięć, miejsce na dysku i obciążenie we/wy dysku.

Obie metody powodują, że kolumna używa zwiększanej wartości za każdym razem, gdy nowy wiersz jest wstawiany z NULL w tej kolumnie.

Istnieją jednak pewne subtelne różnice między sposobem działania każdej metody.

Bez słowa kluczowego AUTOINCREMENT

Kiedy deklarujesz kolumnę jako INTEGER PRIMARY KEY , automatycznie się zwiększy. Dlatego tak naprawdę nie musisz używać AUTOINCREMENT słowo kluczowe, aby mieć kolumnę, która używa automatycznie rosnącej wartości dla każdego wiersza.

Gdy to zrobisz, każdy NULL wartości są konwertowane na bieżący ROWID . Innymi słowy, jeśli wstawisz NULL do tej kolumny, zostanie przekonwertowany na bieżący ROWID .

W rzeczywistości działa to tak, że kolumna staje się aliasem dla ROWID . Możesz uzyskać dostęp do ROWID wartość przy użyciu dowolnej z czterech nazw; nazwa kolumny, ROWID , _ROWID_ lub OID .

Jedna korzyść z pominięcia AUTOINCREMENT słowo kluczowe to zmniejszenie procesora, pamięci, miejsca na dysku i narzutu we/wy dysku.

Ważną wadą jest jednak to, że nie możesz zagwarantować, że wszystkie wiersze zostaną powiększone w kolejności rosnącej. Wynika to ze sposobu, w jaki działa automatyczne zwiększanie przy pominięciu AUTOINCREMENT słowo kluczowe a użycie tego słowa kluczowego.

Gdy pominiesz AUTOINCREMENT słowo kluczowe, raz ROWID jest równa największej możliwej liczbie całkowitej (9223372036854775807), SQLite spróbuje znaleźć nieużywany dodatni ROWID losowo.

Jednak tak długo, jak nigdy nie użyjesz maksymalnego ROWID wartości i nigdy nie usuwasz wpisu w tabeli z największym ROWID , ta metoda wygeneruje monotonicznie rosnący unikalny ROWID s.

Za pomocą słowa kluczowego AUTOINCREMENT

Możesz również jawnie utworzyć kolumny z automatycznym przyrostem. Aby to zrobić, użyj AUTOINCREMENT słowo kluczowe.

Gdy używasz tej metody, do określenia wartości autoinkrementacji używany jest nieco inny algorytm.

Kiedy używasz AUTOINCREMENT słowo kluczowe, ROWID wybrany dla nowego wiersza jest co najmniej o jeden większy niż największy ROWID który kiedykolwiek wcześniej istniał w tej samej tabeli.

Innymi słowy, nie wróci i nie użyje ponownie usuniętych wcześniej ROWID wartości. Po największym możliwym ROWID został wstawiony, nowe wstawki nie są dozwolone. Każda próba wstawienia nowego wiersza zakończy się niepowodzeniem z SQLITE_FULL błąd.

Dlatego użycie tej metody gwarantuje, że ROWID s rosną monotonicznie. Innymi słowy, możesz polegać na tej metodzie, aby mieć ROWID s w porządku rosnącym.

Nie oznacza to jednak, że wartości zawsze będą się zwiększać o 1. Oznacza to po prostu, że nigdy się nie zmniejszą.

Przykład

Oto przykład pokazujący różnicę między niejawnym i jawnym definiowaniem kolumny auto-inkrementacji.

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;

Początkowy wynik:

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

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

Teraz usuńmy ostatni wiersz w każdej tabeli, wstawmy je ponownie, a następnie wybierzmy wynik:

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;

Wynik:

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

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

Podsumowując, Koty tabela została utworzona bez AUTOINCREMENT słowo kluczowe i Psy tabela została utworzona z AUTOINCREMENT słowo kluczowe.

Po usunięciu ostatniego wiersza z Koty tabela, następna INSERT operacja spowodowała ten sam ROWID zostanie ponownie wykorzystana w tym rzędzie.

Jednak Psy stół był inny. Został utworzony za pomocą AUTOINCREMENT słowo kluczowe i dlatego nie może ponownie użyć poprzedniej wartości. Po prostu zwiększa się do następnej wartości, pozostawiając lukę w numeracji.

Maksymalny ROWID

Możemy pójść o krok dalej w poprzednim przykładzie i wstawić nowy wiersz, jawnie używając maksymalnego ROWID możliwe.

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

SELECT * FROM Cats;
SELECT * FROM Dogs;

Wynik:

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

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

OK, więc obie tabele używają największej możliwej liczby całkowitej jako największego ROWID wartości.

Zobaczmy, co się stanie, gdy spróbuję wstawić nowy wiersz do każdej tabeli (bez jawnego określania wartości dla automatycznie zwiększanych kolumn).

Wstaw do Koty tabela:

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

Wynik:

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

Więc Koty stół zakończył się sukcesem. Zauważ jednak, że nowa wartość auto-inkrementacji jest mniejsza niż poprzednia (nie ma innej opcji).

Nie mając żadnej innej kolumny do zapisania daty/godziny wstawienia/zaktualizowania wiersza, można błędnie założyć, że Magnus został wstawiony po Scratchy .

Teraz spróbujmy wstawić nowy wiersz do Psów tabela:

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

Wynik:

Error: database or disk is full

Więc otrzymujemy inny wynik niż Koty tabela.

Otrzymuję ten błąd, ponieważ największy możliwy ROWID jest już używany w tabeli, a ponieważ ta tabela została utworzona za pomocą AUTOINCREMENT słowo kluczowe, nie wróci i nie wyszuka nieużywanego ROWID wartość.

SELECT * FROM Dogs;

Wynik:

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

Co więcej, nadal będę otrzymywał ten błąd, nawet jeśli usunę Maximus z tabeli (np. pies z maksymalnym ROWID wartość).

Spróbujmy:

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

Wynik:

Error: database or disk is full

Więc nie tylko pojawia się błąd, ale także usunąłem Maximus :

SELECT * FROM Dogs;

Wynik:

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

Należy pamiętać, że stanie się to nawet po zmianie ROWID wartość na niższą wartość. Fakt, że użyłem już ROWID 9223372036854775807 oznacza, że ​​AUTOINCREMENT nie będzie już zwiększać się automatycznie.

Dzieje się tak, ponieważ AUTOINCREMENT używa tylko wartości, które są co najmniej o jeden wyższe niż jakakolwiek wartość, która kiedykolwiek istniała w tej samej tabeli .

Od teraz, gdybym chciał nadal wstawiać wartości do tej kolumny, musiałbym jawnie wstawić wartość. Zakłada się, że nie mam już 9223372036854775807 wierszy w tabeli.

Wstawmy ponownie Maximus z niższym ROWID i spróbuj ponownie:

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

Wynik:

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

Teraz spróbujmy wstawić Lickable jeszcze raz, używając AUTOINCREMENT :

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

Wynik:

Error: database or disk is full

Więc nawet jeśli usunąłem wiersz zawierający maksymalny ROWID wartość 9223372036854775807, to nadal uniemożliwia mi automatyczne zwiększanie kolumny.

Dokładnie tak to zostało zaprojektowane. Maksymalny ROWID był wcześniej w tej tabeli, więc AUTOINCREMENT nie zwiększy się automatycznie ponownie w tej tabeli.

Jedynym sposobem dodania nowego wiersza do tej tabeli jest ręczne wstawienie ROWID wartość.

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

Wynik:

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. Automatyczne zwiększanie wartości „id” podczas wstawiania do sqlite

  2. Kopiowanie sqlite w zasobach Android Studio nie działa

  3. Jak naprawić adres URL dostawcy treści, którego nie znaleziono w dostawcy treści na Androida?

  4. Jak stworzyć natywną aplikację na Androida działającą w trybie offline?

  5. Zamów SQLite według daty1530019888000