Natknąłem się na ten post ( Jaka jest różnica między tinyint, smallint, mediumint, bigint i int w MySQL? ) I zdałem sobie sprawę, że PostgreSQL nie obsługuje liczb całkowitych bez znaku.
Czy ktoś może pomóc wyjaśnić, dlaczego tak jest?
Przez większość czasu używam liczb całkowitych bez znaku jako automatycznie zwiększanego klucza podstawowego w MySQL. W takim projekcie, jak mogę temu zaradzić, przenosząc moją bazę danych z MySQL do PostgreSQL?
Dzięki.
postgresql
unsigned-integer
Adrian Hoe
źródło
źródło
serial
(1 do 2147483647) lubbigserial
(1 do 9223372036854775807). 64-bitowa liczba całkowita ze znakiem prawdopodobnie oferuje więcej niż wystarczającą ilość miejsca.Odpowiedzi:
Jest już odpowiedź, dlaczego w postgresql brakuje typów bez znaku. Jednak sugerowałbym użycie domen dla typów niepodpisanych.
http://www.postgresql.org/docs/9.4/static/sql-createdomain.html
Domena jest podobna do typu, ale z dodatkowym ograniczeniem.
Na konkretny przykład możesz użyć
Oto co daje psql, kiedy próbuję nadużywać tego typu.
źródło
Nie ma go w standardzie SQL, więc ogólna potrzeba jego implementacji jest mniejsza.
Zbyt wiele różnych typów liczb całkowitych sprawia, że system rozwiązywania typów jest bardziej kruchy, więc istnieje pewien opór przed dodawaniem kolejnych typów do miksu.
To powiedziawszy, nie ma powodu, dla którego nie można tego zrobić. To po prostu dużo pracy.
źródło
to_char
wzór.Możesz użyć ograniczenia CHECK, np .:
Ponadto, PostgreSQL ma
smallserial
,serial
ibigserial
typy dla automatycznego.źródło
2^32-1
, tymczasem liczba int ze znakiem może wzrosnąć do2^31-1
.NULL
iCHECK
są całkowicie ortogonalne. Możesz miećNULL
/NOT NULL
kolumny z lub bezCHECK
. Zwróć uwagę, że zgodnie z dokumentacją na postgresql.org/docs/9.4/ddl-constraints.html ,CHECK
zwracanie wartości NULL do TRUE, więc jeśli naprawdę chcesz zapobiec NULL, użyjNOT NULL
zamiast tego (lub dodatkowoCHECK
).integer
(nie bez losowego, przynajmniej dodatniego lub ujemnego wyniku)Rozmowa o DOMENACH jest interesująca, ale nie dotyczy jedynego możliwego źródła tego pytania. Dążenie do liczby int bez znaku polega na podwojeniu zakresu liczb całkowitych przy tej samej liczbie bitów, jest to argument wydajności, a nie chęć wykluczenia liczb ujemnych, każdy wie, jak dodać ograniczenie sprawdzające.
Kiedy zapytany przez kogoś o tym , Tome Lane stwierdził:
Co to jest „POLA”? Google dał mi 10 wyników, które są bez znaczenia . Nie jestem pewien, czy jest to myśl politycznie niepoprawna, a zatem ocenzurowana. Dlaczego to wyszukiwane hasło nie daje żadnych wyników? Cokolwiek.
Możesz implementować niepodpisane liczby int jako typy rozszerzeń bez większych problemów. Jeśli zrobisz to za pomocą funkcji C, nie będzie żadnych kar za wydajność. Nie musisz rozszerzać parsera, aby zajmował się literałami, ponieważ PgSQL ma tak łatwy sposób interpretowania łańcuchów jako literałów, po prostu wpisz '4294966272' :: uint4 jako swoje literały. Rzuty też nie powinny być wielkim problemem. Nie musisz nawet robić wyjątków zakresów, możesz po prostu traktować semantykę '4294966273' :: uint4 :: int jako -1024. Lub możesz zgłosić błąd.
Gdybym tego chciał, zrobiłbym to. Ale ponieważ używam Javy po drugiej stronie SQL, ma to dla mnie niewielką wartość, ponieważ Java również nie ma tych liczb całkowitych bez znaku. Więc nic nie zyskuję. Jestem już zirytowany, gdy dostaję BigInteger z kolumny biginta, kiedy powinien pasować do long.
Inna sprawa, gdybym miał potrzebę przechowywania typów 32-bitowych lub 64-bitowych, mogę użyć odpowiednio PostgreSQL int4 lub int8, pamiętając tylko, że naturalna kolejność lub arytmetyka nie będą działać niezawodnie. Nie ma to jednak wpływu na przechowywanie i odzyskiwanie.
Oto jak mogę zaimplementować proste bez znaku int8:
Najpierw użyję
minimum 2 funkcje
uint8_in
iuint8_out
muszę najpierw zdefiniować.trzeba to zaimplementować w C uint8_funcs.c. Więc skorzystam ze złożonego przykładu z tego miejsca i uproszczę to:
no cóż, albo możesz po prostu znaleźć to już zrobione .
źródło
Zgodnie z najnowszą dokumentacją, pojedyncza liczba całkowita jest obsługiwana, ale w tabeli nie ma liczby całkowitej bez znaku. Jednak typ seryjny jest podobny do bez znaku, z wyjątkiem tego, że zaczyna się od 1, a nie od zera. Ale górna granica jest taka sama jak przypalona. Tak więc system naprawdę nie ma niepodpisanego wsparcia. Jak zauważył Piotr, drzwi są otwarte do realizacji wersji bez znaku. Kod może wymagać częstej aktualizacji, po prostu zbyt dużo pracy z mojego doświadczenia w programowaniu w C.
https://www.postgresql.org/docs/10/datatype-numeric.html
źródło
Postgres ma niepodpisane typ całkowitą, która jest bez wiedzy wiele:
OID
.Nie jest to jednak typ numeryczny i próba wykonania na nim jakichkolwiek działań arytmetycznych (a nawet operacji bitowych) zakończy się niepowodzeniem. Poza tym to tylko 4 bajty (
INTEGER
), nie ma odpowiadającego mu typu 8 bajtów (BIGINT
) bez znaku.Więc nie jest dobrym pomysłem używanie tego samemu i zgadzam się ze wszystkimi innymi odpowiedziami, że w projekcie bazy danych Postgresql powinieneś zawsze używać kolumny
INTEGER
lubBIGINT
dla swojego seryjnego klucza podstawowego - zaczynając od negacji (MINVALUE
) lub pozwalając na to wrap around (CYCLE
), jeśli chcesz wyczerpać całą domenę.Jest to jednak przydatne do konwersji wejścia / wyjścia, jak migracja z innego DBMS. Wstawienie wartości
2147483648
do kolumny z liczbami całkowitymi spowoduje wyświetlenie komunikatu „ BŁĄD: liczba całkowita poza zakresem ”, podczas gdy użycie wyrażenia2147483648::OID
działa dobrze.Podobnie, wybierając kolumnę z liczbą całkowitą jako tekst z
mycolumn::TEXT
, w pewnym momencie otrzymasz wartości ujemne, alemycolumn::OID::TEXT
zawsze otrzymasz liczbę naturalną.Zobacz przykład na dbfiddle.uk .
źródło