Przechodzę z MySQL na PostgreSQL i zastanawiałem się, jak mogę wykonać automatyczne zwiększenie wartości. W dokumentach PostgreSQL widziałem typ danych „seryjny”, ale podczas korzystania z niego występują błędy składniowe (w wersji 8.0).
578
Odpowiedzi:
Tak, SERIAL jest równoważną funkcją.
SERIAL to po prostu makro czasu tabeli wokół sekwencji. Nie możesz zmienić SERIAL na istniejącą kolumnę.
źródło
"Table"
a"table"
następnie po prostu zostaw go nie cytowany i kanonizuj gotable
. Konwencja po prostu nigdy nie używa cudzysłowów w Pg. Możesz, jeśli chcesz, używać różnych nazw liter do wyglądu, po prostu nie wymagaj tego:CREATE TABLE fooBar ( .. ); SELECT * FROM fooBar;
będzie działać, jak będzieSELECT * FROM foobar
.Możesz użyć dowolnego innego typu danych całkowitych , takiego jak
smallint
.Przykład:
Lepiej jest używać własnego typu danych niż szeregowego typu danych użytkownika .
źródło
CREATE SEQUENCE
postgresql.org/docs/8.1/interactive/sql-createsequence.html ) . JEDNAK nie jestem pewien, dlaczego zmieniłeś właściciela.Jeśli chcesz dodać sekwencję do identyfikatora w tabeli, która już istnieje, możesz użyć:
źródło
ALTER COLUMN user_id
?ERROR: syntax error at or near "DEFAULT"
jakieś sugestie?Choć wygląda na to, że sekwencje są odpowiednikiem auto_increment MySQL, istnieją pewne subtelne, ale ważne różnice:
1. Zwiększenie liczby nieudanych zapytań Sekwencja / numer seryjny
Kolumna szeregowa jest zwiększana w przypadku nieudanych zapytań. Prowadzi to do fragmentacji z powodu nieudanych zapytań, a nie tylko usuwania wierszy. Na przykład uruchom następujące zapytania w bazie danych PostgreSQL:
Powinieneś otrzymać następujące dane wyjściowe:
Zauważ, jak uid zmienia się z 1 na 3 zamiast 1 na 2.
Dzieje się tak nadal, jeśli ręcznie utworzysz własną sekwencję za pomocą:
Jeśli chcesz przetestować, jak różni się MySQL, uruchom następujące polecenie w bazie danych MySQL:
Powinieneś otrzymać następujące bez frustracji :
2. Ręczne ustawienie wartości kolumny szeregowej może spowodować, że przyszłe zapytania nie będą działać.
Zwrócił na to uwagę @trev w poprzedniej odpowiedzi.
Aby to zasymulować ręcznie, ustaw UID na 4, który później „zderzy się”.
Dane tabeli:
Uruchom kolejną wkładkę:
Dane tabeli:
Teraz, jeśli uruchomisz inną wstawkę:
Nie powiedzie się z następującym komunikatem o błędzie:
W przeciwieństwie do tego MySQL poradzi sobie z tym z wdziękiem, jak pokazano poniżej:
Teraz wstaw kolejny wiersz bez ustawiania UID
Zapytanie nie kończy się niepowodzeniem, UID po prostu przeskakuje do 5:
Testy przeprowadzono na MySQL 5.6.33, dla Linuksa (x86_64) i PostgreSQL 9.4.9
źródło
Począwszy od Postgres 10, obsługiwane są również kolumny tożsamości zdefiniowane w standardzie SQL:
tworzy kolumnę tożsamości, której nie można zastąpić, chyba że zostanie o to wyraźnie poproszony. Następująca wstawka zakończy się niepowodzeniem z kolumną zdefiniowaną jako
generated always
:Można to jednak zmienić:
Podczas korzystania z opcji
generated by default
jest to zasadniczo to samo zachowanie, co istniejącaserial
implementacja:Gdy wartość jest podawana ręcznie, sekwencję podstawową należy również dostosować ręcznie - tak samo jak w przypadku
serial
kolumny.Kolumna tożsamości nie jest domyślnie kluczem podstawowym (podobnie jak
serial
kolumna). Jeśli ma to być jeden, ograniczenie klucza podstawowego należy zdefiniować ręcznie.źródło
Przykro mi, aby powtórzyć stare pytanie, ale było to pierwsze pytanie / odpowiedź Przepełnienie stosu, które pojawiło się w Google.
Ten post (który pojawił się jako pierwszy w Google) mówi o używaniu bardziej zaktualizowanej składni PostgreSQL 10: https://blog.2ndquadrant.com/postgresql-10-identity-columns/
co się dzieje:
Mam nadzieję, że to pomoże :)
źródło
GENERATED … AS IDENTITY
polecenia są standardowym SQL. Najpierw dodano w SQL: 2003 , a następnie wyjaśniono w SQL: 2008 . Zobacz funkcje # T174 i F386 i T178.Musisz uważać, aby nie wstawić bezpośrednio do pola SERIAL lub sekwencji, w przeciwnym razie zapis nie powiedzie się, gdy sekwencja osiągnie wstawioną wartość:
źródło
W kontekście zadanego pytania i odpowiedzi na komentarz @ sereja1c, tworzenie
SERIAL
niejawnie tworzy sekwencje, więc w powyższym przykładzie-CREATE TABLE
tworzyłoby domyślnie sekwencjęfoo_id_seq
dla kolumny szeregowejfoo.id
. DlategoSERIAL
[4 bajty] jest dobry ze względu na łatwość użycia, chyba że potrzebujesz określonego typu danych dla swojego identyfikatora.źródło
Ten sposób na pewno zadziała, mam nadzieję, że pomoże:
Możesz to sprawdzić szczegóły w następnym linku: http://www.postgresqltutorial.com/postgresql-serial/
źródło
Od PostgreSQL 10
źródło