Saya menemukan posting ini ( Apa perbedaan antara tinyint, smallint, mediumint, bigint dan int di MySQL? ) Dan menyadari bahwa PostgreSQL tidak mendukung unsigned integer.
Adakah yang bisa membantu menjelaskan mengapa demikian?
Sebagian besar waktu, saya menggunakan unsigned integer sebagai kunci primer bertambah otomatis di MySQL. Dalam desain seperti itu, bagaimana saya bisa mengatasinya ketika saya mem-port database saya dari MySQL ke PostgreSQL?
Terima kasih.
postgresql
unsigned-integer
Adrian Hoe
sumber
sumber
serial
(1 hingga 2147483647) ataubigserial
(1 hingga 9223372036854775807). Integer 64bit yang ditandatangani mungkin menawarkan lebih dari cukup ruang.Jawaban:
Sudah terjawab mengapa postgresql tidak memiliki tipe unsigned. Namun saya akan menyarankan untuk menggunakan domain untuk tipe unsigned.
http://www.postgresql.org/docs/9.4/static/sql-createdomain.html
Domain seperti sebuah tipe tetapi dengan batasan tambahan.
Untuk contoh konkret Anda bisa menggunakan
Inilah yang psql berikan ketika saya mencoba menyalahgunakan tipe.
sumber
Ini tidak ada dalam standar SQL, jadi dorongan umum untuk mengimplementasikannya lebih rendah.
Memiliki terlalu banyak tipe bilangan bulat yang berbeda membuat sistem resolusi tipe lebih rapuh, jadi ada beberapa hambatan untuk menambahkan lebih banyak tipe ke dalam campuran.
Meski begitu, tidak ada alasan mengapa itu tidak bisa dilakukan. Itu hanya banyak pekerjaan.
sumber
to_char
pola.Anda dapat menggunakan batasan PERIKSA, misalnya:
Juga, PostgreSQL memiliki
smallserial
,serial
, danbigserial
jenis untuk auto-increment.sumber
2^32-1
, sementara int yang ditandatangani bisa naik2^31-1
.NULL
danCHECK
sepenuhnya ortogonal. Anda dapat memilikiNULL
/NOT NULL
kolom dengan atau tanpaCHECK
. Perhatikan saja, sesuai dokumentasi di postgresql.org/docs/9.4/ddl-constraints.html ,CHECK
mengembalikan nilai NULL ke TRUE, jadi jika Anda benar-benar ingin mencegah NULL, gunakanNOT NULL
sebagai gantinya (atau sebagai tambahanCHECK
).integer
(tidak tanpa membuatnya menjadi positif atau negatif secara acak, setidaknya ..)Pembicaraan tentang DOMAIN menarik tetapi tidak relevan dengan satu-satunya kemungkinan asal pertanyaan itu. Keinginan untuk unsigned int adalah untuk menggandakan rentang int dengan jumlah bit yang sama, ini adalah argumen efisiensi, bukan keinginan untuk mengecualikan angka negatif, semua orang tahu bagaimana menambahkan batasan cek.
Ketika ditanya oleh seseorang tentang hal itu , Tome Lane menyatakan:
Apa itu "POLA"? Google memberi saya 10 hasil yang tidak berarti . Tidak yakin apakah itu pemikiran yang salah secara politis dan karena itu disensor. Mengapa istilah pencarian ini tidak membuahkan hasil? Masa bodo.
Anda dapat mengimplementasikan unsigned int sebagai jenis ekstensi tanpa terlalu banyak kesulitan. Jika Anda melakukannya dengan fungsi-C, maka tidak akan ada penalti kinerja sama sekali. Anda tidak perlu memperluas parser untuk menangani literal karena PgSQL memiliki cara yang mudah untuk menafsirkan string sebagai literal, cukup tulis '4294966272' :: uint4 sebagai literal Anda. Pemain juga seharusnya tidak menjadi masalah besar. Anda bahkan tidak perlu melakukan pengecualian rentang, Anda cukup memperlakukan semantik '4294966273' :: uint4 :: int sebagai -1024. Atau Anda bisa membuat kesalahan.
Jika saya menginginkan ini, saya akan melakukannya. Tetapi karena saya menggunakan Java di sisi lain SQL, bagi saya nilainya kecil karena Java juga tidak memiliki bilangan bulat yang tidak ditandatangani. Jadi saya tidak mendapatkan apa-apa. Saya sudah kesal jika saya mendapatkan BigInteger dari kolom bigint, padahal harus muat menjadi panjang.
Hal lain, jika saya memiliki kebutuhan untuk menyimpan tipe 32 bit atau 64 bit, saya dapat menggunakan PostgreSQL int4 atau int8 masing-masing, hanya dengan mengingat bahwa urutan natural atau aritmatika tidak akan bekerja dengan andal. Tapi menyimpan dan mengambil tidak terpengaruh olehnya.
Berikut adalah bagaimana saya dapat mengimplementasikan unsigned int8 sederhana:
Pertama saya akan gunakan
minimal 2 fungsi
uint8_in
danuint8_out
saya harus mendefinisikan terlebih dahulu.perlu menerapkan ini di C uint8_funcs.c. Jadi saya menggunakan contoh kompleks dari sini dan membuatnya sederhana:
ah baiklah, atau Anda bisa menemukannya sudah selesai .
sumber
Menurut dokumentasi terbaru, integer yang dihanguskan didukung tetapi tidak ada integer yang tidak bertanda tangan dalam tabel. Namun, tipe serialnya mirip dengan unsigned kecuali dimulai dari 1 bukan dari nol. Tapi batas atasnya sama dengan hangus. Jadi sistem benar-benar tidak memiliki dukungan tanpa tanda tangan. Seperti yang ditunjukkan oleh Peter, pintu terbuka untuk mengimplementasikan versi unsigned. Kode mungkin harus banyak diperbarui, terlalu banyak pekerjaan dari pengalaman saya bekerja dengan pemrograman C.
https://www.postgresql.org/docs/10/datatype-numeric.html
sumber
Postgres memang memiliki tipe unsigned integer yang tanpa sepengetahuan banyak:
OID
.Ini bukan tipe numerik , dan mencoba melakukan aritmatika (atau bahkan operasi bitwise) dengannya akan gagal. Juga, ini hanya 4 byte (
INTEGER
), tidak adaBIGINT
tipe unsigned 8 byte ( ) yang sesuai.Jadi bukan ide yang baik untuk menggunakan ini sendiri, dan saya setuju dengan semua jawaban lain bahwa dalam desain database Postgresql Anda harus selalu menggunakan kolom
INTEGER
atauBIGINT
untuk kunci utama serial Anda - memulainya dengan negatif (MINVALUE
) atau mengizinkannya untuk membungkus (CYCLE
) jika Anda ingin menghabiskan domain penuh.Namun, ini cukup berguna untuk konversi input / output, seperti migrasi Anda dari DBMS lain. Memasukkan nilai
2147483648
ke dalam kolom integer akan menghasilkan " ERROR: integer out of range ", sementara ekspresi2147483648::OID
bekerja dengan baik.Demikian pula, saat memilih kolom integer sebagai teks
mycolumn::TEXT
, Anda akan mendapatkan nilai negatif di beberapa titik, tetapi denganmycolumn::OID::TEXT
Anda akan selalu mendapatkan bilangan asli.Lihat contoh di dbfiddle.uk .
sumber