Czy w sqlite jest automatyczna inkrementacja?

109

Próbuję utworzyć tabelę z autoinkrementacjąprimary key w Sqlite3 . Nie jestem pewien, czy jest to naprawdę możliwe, ale mam nadzieję, że będę musiał wyznaczyć tylko inne pola.

Na przykład:

CREATE TABLE people (id integer primary key auto increment, first_name varchar(20), last_name varchar(20));

Potem, kiedy dodałem wartość, miałem nadzieję, że wystarczy mi:

INSERT INTO people
VALUES ("John", "Smith");

Czy to w ogóle możliwe?

Pracuję sqlite3pod cygwinWindows 7.

ewok
źródło

Odpowiedzi:

167

Otrzymujesz jeden za darmo o nazwie ROWID. To jest w każdej tabeli SQLite, czy o to prosisz, czy nie.

Jeśli dołączysz kolumnę typu INTEGER PRIMARY KEY, kolumna ta wskazuje na (jest aliasem) automatyczną kolumnę ROWID.

ROWID (pod jakąkolwiek nazwą go nazwiesz) jest przypisywana wartości za każdym razem, gdy WSTAWISZ wiersz, zgodnie z oczekiwaniami. Jeśli jawnie przypiszesz wartość inną niż NULL do INSERT, otrzyma określoną wartość zamiast automatycznego zwiększania. Jeśli jawnie przypiszesz wartość NULL do INSERT, otrzyma następną wartość z automatycznego zwiększania.

Powinieneś także unikać:

 INSERT INTO people VALUES ("John", "Smith");

I użyć

 INSERT INTO people (first_name, last_name) VALUES ("John", "Smith");

zamiast. Pierwsza wersja jest bardzo delikatna - jeśli kiedykolwiek dodasz, przeniesiesz lub usuniesz kolumny w definicji tabeli, INSERT albo zakończy się niepowodzeniem, albo wygeneruje niepoprawne dane (z wartościami w niewłaściwych kolumnach).

Larry Lustig
źródło
53
ROWID to nie to samo, co prawdziwe autoinkrementacja, ponieważ TA SAMA wartość może zostać wygenerowana więcej niż raz. Na przykład w przypadku pustej tabeli wstawienie 3 wierszy daje trzeciemu wierszowi ROWID 3 zgodnie z oczekiwaniami. Jednak wstaw 2 wiersze, usuń ostatni i wstaw kolejny, daje trzeciemu wstawionemu wierszowi ROWID 2, tak samo jak drugi wiersz. W związku z tym istnieje oczywisty poważny problem, jeśli tabele odwołują się do identyfikatorów ROWID w tabeli, w której występują operacje usuwania, i gdzie operacje usuwania lub zerowania wartości ROWID nie są również wykonywane w powiązanych tabelach.
Nick
10
W przypadku, gdy odpowiedź nie jest oczywista, możesz użyć ROWID w wybranej instrukcji, np.select rowid from people;
Colin D
@Nick tylko po to, by uzupełnić twój pomysł: więc automatyczne zwiększanie jest środkiem bezpieczeństwa. I nie mówimy o zderzeniu dwóch rzędów w ROWID.
YoussefDir
69

Tak, jest to możliwe. Zgodnie z FAQ SQLite :

Zadeklarowana kolumna INTEGER PRIMARY KEYbędzie automatycznie zwiększana.

Matt Hulse
źródło
12
Zastrzeżeniem, jak wspomniał Uku, a także wyjaśniono w dokumentacji, jest to, że musisz podać NULL dla identyfikatora, aby to zadziałało.
Matt Hulse
22
Tylko trzeba użyć NULL jeśli pominąć listę kolumn do wstawienia - nigdy dobrej praktyki. Jeśli określisz kolumny, możesz po prostu pominąć kolumnę z automatycznym przyrostem, a otrzyma ona następną wartość.
Larry Lustig
5
Kolejne zastrzeżenie: wpisz „INTEGER…” dokładnie tak, jak podano powyżej. Skróty „INT ...” NIE będą działać.
Marcin Wojnarski
27

Stan na dzień dzisiejszy - czerwiec 2018 r


Oto, co oficjalna dokumentacja SQLite ma do powiedzenia na ten temat (pogrubienie i kursywa są moje):

  1. W AUTOINCREMENT nakłada słów kluczowych dodatkowy procesor, pamięć, przestrzeń na dysku, a dysk I / O napowietrznych i należy unikać, jeśli nie jest to bezwzględnie konieczne. Zwykle nie jest to potrzebne.

  2. W SQLite kolumna typu INTEGER PRIMARY KEY jest aliasem dla ROWID (z wyjątkiem tabel BEZ ROWIDU), który jest zawsze 64-bitową liczbą całkowitą ze znakiem.

  3. W przypadku INSERT, jeśli kolumna ROWID lub INTEGER PRIMARY KEY nie ma jawnie określonej wartości, zostanie ona automatycznie wypełniona nieużywaną liczbą całkowitą, zwykle o jedną większą niż największy aktualnie używany ROWID . Dzieje się tak niezależnie od tego, czy słowo kluczowe AUTOINCREMENT jest używane, czy nie.

  4. Jeśli słowo kluczowe AUTOINCREMENT pojawia się po INTEGER PRIMARY KEY , powoduje to zmianę algorytmu automatycznego przypisywania ROWID, aby zapobiec ponownemu wykorzystaniu ROWID przez cały okres istnienia bazy danych. Innymi słowy, celem AUTOINCREMENT jest zapobieganie ponownemu wykorzystaniu ROWID z wcześniej usuniętych wierszy.


źródło
11

Czytałeś to? Jak utworzyć pole AUTOINCREMENT.

INSERT INTO people
VALUES (NULL, "John", "Smith");
Uku Loskit
źródło
Więc mówisz, że to, co próbuję zrobić, nie jest możliwe, ale mogę coś symulować. Muszę użyć wartości null we wkładce?
ewok
1
nie musisz nic robić, ale zawsze wstawiaj NULL jako identyfikator, po prostu wyjaśnia, jak sqlite robi to wewnętrznie.
Uku Loskit
7
Wartość NULL na INSERT jest wymagana tylko wtedy, gdy nie określisz listy kolumn jako INSERT (w takim przypadku potrzebujesz liczby wartości dokładnie pasujących do liczby kolumn i musisz użyć NULL jako symbolu zastępczego). Jednak wykonanie instrukcji INSERT bez określenia listy kolumn nigdy nie jest dobrą praktyką. Jeśli określisz listę kolumn, po prostu pomiń zarówno kolumnę autoincrement, jak i wartość NULL, a otrzymasz oczekiwany wynik.
Larry Lustig
4

Nie należy podawać AUTOINCREMENTsłowa kluczowego near PRIMARY KEY. Przykład tworzenia klucza podstawowego z funkcją autoincrement i wstawiania:

$ sqlite3 ex1

CREATE TABLE IF NOT EXISTS room(room_id INTEGER PRIMARY KEY, name VARCHAR(25) NOT NULL, home_id VARCHAR(25) NOT NULL);

INSERT INTO room(name, home_id) VALUES ('test', 'home id test');

INSERT INTO room(name, home_id) VALUES ('test 2', 'home id test 2');

SELECT * FROM room;

da:

1|test|home id test
2|test 2|home id test 2
Denis Kutlubaev
źródło
4

Oprócz rowid możesz zdefiniować własne pole automatycznego zwiększania wartości, ale nie jest to zalecane. Zawsze jest lepszym rozwiązaniem, gdy używamy rowid, który jest automatycznie zwiększany.

Do AUTOINCREMENTnakłada słów kluczowych dodatkowy procesor, pamięć, przestrzeń na dysku, a dysk I / O napowietrznych i należy unikać, jeśli nie jest to bezwzględnie konieczne. Zwykle nie jest to potrzebne.

Przeczytaj tutaj, aby uzyskać szczegółowe informacje.

sonvx
źródło
najwyraźniej rowid nie zawsze jest zwiększany automatycznie, zobacz komentarz Nicka
rogerdpack
1
Nie prawda. Automatyczne zwiększanie jest lepsze pod pewnymi względami, ponieważ nie wykorzystuje ponownie identyfikatorów - dość ważny wymóg dla wielu systemów.
O'Rooney,
4

SQLite AUTOINCREMENT to słowo kluczowe używane do automatycznego zwiększania wartości pola w tabeli. Możemy automatycznie zwiększać wartość pola, używając słowa kluczowego AUTOINCREMENT podczas tworzenia tabeli z określoną nazwą kolumny, aby ją automatycznie zwiększać.

Słowo kluczowe AUTOINCREMENT może być używane tylko z polem INTEGER. Składnia:

Podstawowe użycie słowa kluczowego AUTOINCREMENT jest następujące:

CREATE TABLE table_name(
   column1 INTEGER AUTOINCREMENT,
   column2 datatype,
   column3 datatype,
   .....
   columnN datatype,
);

Na przykład patrz poniżej: Rozważmy utworzenie tabeli COMPANY w następujący sposób:

sqlite> CREATE TABLE TB_COMPANY_INFO(
   ID INTEGER PRIMARY KEY   AUTOINCREMENT,
   NAME           TEXT      NOT NULL,
   AGE            INT       NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

Teraz wstaw następujące rekordy do tabeli TB_COMPANY_INFO:

INSERT INTO TB_COMPANY_INFO (NAME,AGE,ADDRESS,SALARY)
VALUES ( 'MANOJ KUMAR', 40, 'Meerut,UP,INDIA', 200000.00 );

Teraz wybierz rekord

SELECT *FROM TB_COMPANY_INFO
ID      NAME            AGE     ADDRESS             SALARY
1       Manoj Kumar     40      Meerut,UP,INDIA     200000.00
mkumar0304
źródło
2

Wiem, że ta odpowiedź jest trochę spóźniona.
Celem mojej odpowiedzi jest odniesienie się do wszystkich, jeśli napotkają tego typu wyzwanie z SQLite teraz lub w przyszłości i mają z tym trudności.

Teraz, patrząc wstecz na twoje zapytanie, powinno wyglądać mniej więcej tak.

CREATE TABLE people (id integer primary key autoincrement, first_name varchar(20), last_name varchar(20));

To działa z mojej strony. Tak jak tak

wprowadź opis obrazu tutaj

Na wypadek, gdybyś pracował z SQLite, proponuję sprawdzić przeglądarkę DB dla SQLite . Działa również na różnych platformach.

Kent Aguilar
źródło
0

To, co robisz, jest poprawne, ale poprawna składnia „automatycznego inkrementacji” nie powinna zawierać spacji:

CREATE TABLE people (id integer primary key autoincrement, first_name string, last_name string);

(Zwróć też uwagę, że zmieniłem twoje varchar na ciągi znaków. To dlatego, że SQLite wewnętrznie przekształca varchar w ciąg, więc po co się przejmować?)

wtedy twoja wkładka powinna być, w języku SQL jak najbardziej standardowym:

INSERT INTO people(id, first_name, last_name) VALUES (null, 'john', 'doe');

chociaż prawdą jest, że jeśli pominiesz identyfikator, zostanie on automatycznie zwiększony i przypisany, osobiście wolę nie polegać na automatycznych mechanizmach, które mogą się zmienić w przyszłości.

Uwaga na temat autoinkrementacji: chociaż, jak wielu zauważyło, nie jest to zalecane przez osoby korzystające z SQLite, nie podoba mi się automatyczne ponowne wykorzystywanie identyfikatorów usuniętych rekordów, jeśli nie jest używane automatyczne zwiększanie. Innymi słowy, ja podoba że identyfikator usuniętego rekordu nigdy, przenigdy nie pojawi się ponownie.

HTH

Luca Nanetti
źródło
Pod tym względem całkowicie podzielam to, co mówi O'Rooney.
Luca Nanetti