Apa yang harus dilakukan ketika bidang dalam tabel mendekati bilangan bulat 32 bit max ditandatangani atau tidak ditandatangani?

14

Dalam basis data yang diberikan yang menyimpan catatan pengguna dalam bentuk bidang kenaikan-otomatis yang unik (untuk contoh, pesan antar-pengguna) ... apa yang harus dilakukan ketika saatnya tiba dan mendekati jumlah maksimum yang ditandatangani atau tidak ditandatangani dari tipe data saat ini? (A 32-bit INT)? Saya menduga bahwa server database akan meluap ketika mencoba untuk menetapkan (2∧32) -1 nomor untuk entri berikutnya, jadi, bagaimana cara menghindari hal itu terjadi (tanpa mengubah datatype, demi pertanyaan) dan terus menambahkan catatan? Apa yang akan kamu lakukan?

Mengapa saya menggunakan INT dan bukan, misalnya, VARCHAR?

Sudah beberapa hari sejak saya bertanya pada diri sendiri pertanyaan hipotetis ini dan saya ingin tahu apa yang akan dilakukan seorang profesional.

AeroCross
sumber

Jawaban:

12

Anda biasanya akan menggunakan integer daripada varchars karena mereka mengkonsumsi lebih sedikit ruang, telah memahami dengan baik pola penyortiran yang cepat untuk mengindeks dll. Integer adalah tipe data alami dari sebuah CPU, dan karenanya kinerja umumnya optimal. Biasanya integer adalah 4 byte, setara dengan hanya 4 karakter dalam varchar (non-unicode).

Jika Anda khawatir kehabisan ruang dengan tipe INT, cobalah BIGINT, yang memberi Anda angka 8-byte. Batas ini sangat besar, dan Anda mungkin kehabisan ruang disk sebelum Anda mencapai batas catatan :-) Kinerja BIGINT juga akan sangat baik, terutama karena banyak server sekarang 64-bit juga .

Jawaban untuk bagian pertama dari pertanyaan Anda tentang apa yang terjadi ketika Anda kehabisan INTs tidak sederhana, terutama seperti yang Anda katakan tanpa mengubah datatype ke BIGINT. Pada dasarnya tidak banyak yang dapat Anda lakukan, dan apa yang dapat Anda lakukan sangat dibatasi oleh sifat data dalam database Anda. Catatan apa yang asing kunci untuk data ini? Apakah Anda masih membutuhkan semua data dalam tabel itu dan catatan terkait? Dengan asumsi bahwa Anda dapat mengarsipkan banyak data awal (dan data terkait), maka satu-satunya hal yang dapat saya sarankan adalah memindahkan data dari tabel (misalkan 1 hingga X juta catatan pertama), lalu mengatur ulang seed identitas ke 1. Ada segala macam alasan meskipun saya tidak akan merekomendasikannya - misalnya ada banyak bit kode yang saya lihat yang melakukan hal-hal seperti memeriksa nilai maksimum bidang id, untuk melihat apa yang baru saja ditambahkan, dan itu tidak akan berhasil (dan tidak boleh dilakukan). Juga, orang berasumsi bahwa catatan N dibuat sebelum N +1. Saya kira tidak ada jawaban yang mudah.

Akhirnya, saya tidak tahu tentang MySQL, tetapi SQL Server akan memberikan kesalahan overflow jika Anda mencapai batasnya.

Miles D
sumber
1
Saya senang dengan jawaban yang begitu mendetail. Terima kasih atas penjelasan kesepakatan VARCHAR, INT dan BIGINT. Karena pertanyaannya adalah hipotesis, saya ingin tahu apa yang akan terjadi jika batas BIGINT tercapai. Pertanyaan itu diajukan oleh sebuah posting yang saya lihat tentang facebook menggunakan INT dan mencapai batasnya, dan saya melihatnya sebagai sangat mungkin. Pengarsipan akan berfungsi, atau membuat tabel kedua dengan pernyataan kondisional (yang, seperti yang Anda katakan, akan membutuhkan skrip untuk diperbarui juga, dan itu akan sangat kompleks). Secara keseluruhan, jawaban yang bagus. Saya menghargai waktu yang dibutuhkan.
AeroCross
9

Satu hal yang terlewatkan adalah bahwa banyak orang memulai nomor otomatis atau identitas pada 1 sehingga kehilangan setengah dari kisaran yang mungkin segera (untuk ditandatangani)

Anda cukup mendefinisikan ulang angka untuk mulai dari -1, kenaikan -1 dalam kasus ini.

Dapat diperdebatkan, jika Anda pernah berharap untuk mengisi kolom identitas Anda maka Anda harus merancang ini dan menggunakan tipe data yang lebih luas di awal.

Lihat pertanyaan terakhir ini tentang SO: SQL Server 2008: apa yang terjadi jika identitas melampaui nilai maksimal int?

gbn
sumber
Itu logis saya akan menggunakan tipe data yang lebih luas (untuk tabel yang akan berapa jumlah data), tetapi karena itu adalah pertanyaan hipotetis, saya ingin wawasan. Jika ditandatangani, itu mungkin berhasil (tapi saya akan sedikit aneh memiliki kunci primer dengan angka negatif, IMHO) dan saya pikir itu cukup pintar. Ini akan memberi waktu bagi DBA untuk mengarsipkan data positif dan memulai lagi. Jika tidak ditandatangani, well ... masalah.
AeroCross
Atau dengan menggunakan selisih -1 dari -1, mulai dari (-2147483648) dan selisih dengan 1. Tapi ya, setelah Anda melewati INT_MAX maka Anda disemprot dengan cukup baik dan perlu meninjau kembali desain, dan menghapus indeks lama menggantikannya dengan yang lebih besar baru. dan jika Anda lulus BIGINT tanpa tanda tangan maka saya ingin bekerja di tim Anda;)
jcolebrand
PostgreSQL menggunakan urutan untuk menghasilkan nomor id; pernyataan CREATE SEQUENCE memungkinkan Anda menentukan CYCLE, yang hanya akan membungkus jika Anda mencapai nilai maksimum. (Atau nilai minimum, jika Anda pergi ke arah lain.) Opsi CYCLE adalah dalam standar SQL sekarang. (Setidaknya sejak 2003.)
Mike Sherrill 'Cat Recall'
4

Overflow BIGINT? Ha ha. Pertama-tama cari tahu bagaimana mencapai keabadian. INT UNSIGNED (4 miliar) cukup sulit untuk dijangkau. 100 INSERT per detik akan mendekati INT yang meluap dalam setahun. BIGINT akan memakan waktu beberapa miliar tahun.

Untuk memperbaikinya: ALTER TABLE foo MODIFY COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; Tetapi itu akan memakan waktu berjam-jam karena akan menyalin di atas meja (yang memiliki hampir 4 miliar baris, kan?) Dan membangun kembali semua indeks sekunder. Plan Ahea d.

Umumnya ketika Anda mencoba untuk menyimpan angka yang terlalu besar untuk sebuah bidang (mis., 999 dalam TINYINT UNSIGNED), itu akan secara diam-diam menutupnya ke max untuk bidang (255 dalam kasus ini). Mungkin ada "Peringatan", tetapi kebanyakan orang tidak repot-repot memeriksa peringatan. Jika ini adalah bidang UNIK, atau ada KUNCI ASING, Anda mungkin mendapatkan kesalahan yang lebih serius.

CHAR atau VARCHAR diam-diam terpotong ke tempat yang tersedia.

Rick James
sumber