Tablodaki bir alan, imzalı veya imzasız maksimum 32 bit tam sayıya yaklaştığında ne yapmalı?


14

Kullanıcı kayıtlarını benzersiz bir otomatik artış alanı biçiminde tutan herhangi bir veritabanında (örneğin, kullanıcılar arası mesajlar için) ... zaman geldiğinde ve maksimum işaretli veya işaretsiz sayıya yaklaşıldığında ne yapmalı Mevcut veri tipinin? (32 bit INT)? Ben veritabanı sunucusunun (2∧32) -1 numarasını bir sonraki girişe atamaya çalışırken taşacağını tahmin ediyorum, bu yüzden, nasıl olmasını önlemek için (veri türünü değiştirmeden, soru uğruna) ve kayıt eklemeye devam etmek istiyor musunuz? Sen ne yapardın?

Neden INT'leri kullanıyorum, örneğin VARCHARS'ı kullanmıyorum?

Kendime bu varsayımsal soruyu sorduğumdan bu yana birkaç gün geçti ve bir uzmanın ne yapacağını bilmek istiyorum.

Yanıtlar:


12

Genelde varchar yerine tamsayılar kullanırsınız çünkü daha az yer kaplarlar, iyi anlaşılmış sıralama düzeni endekslenirler, vb. Tipik olarak bir tamsayı 4 bayttır (bir unicode olmayan) varchar içinde sadece 4 karaktere eşdeğerdir.

Bir INT türüyle alanınız tükenmesinden endişe ediyorsanız, 8 baytlık sayıları veren BIGINT'i deneyin. Bu sınır oldukça büyük ve bu kayıt sınırına ulaşmadan önce muhtemelen disk alanınız tükenecek :-) BIGINT'in performansı da çok iyi olacak, özellikle de birçok sunucu şimdi 64-bit olduğu için .

INT'lerde bittiğinde ne olacağına dair sorunuzun ilk kısmının cevabı, özellikle de veri türünü BIGINT olarak değiştirmeden söylediğiniz gibi basit değildir. Temelde yapabileceğiniz pek bir şey yoktur ve yapabileceğiniz şey, veritabanınızdaki verilerin doğasıyla çok sınırlıdır. Bu veriler için hangi kayıtlar yabancı anahtarlıdır? Tablodaki tüm verilere ve ilgili kayıtlara hala ihtiyacınız var mı? Birçok başlangıç ​​verisini (ve ilgili verilerini) arşivleyebileceğiniz varsayımına göre, önerebileceğim tek şey verileri tablodan çıkarmak (ilk 1'den X milyon kayıtlara diyelim) ve sonra kimlik tohumunu 1'e sıfırlama. Bunu tavsiye etmememe rağmen her türlü neden var - örneğin bir id alanının maksimum değerini kontrol etmek gibi şeyler yaptığımı gördüğüm birçok kod parçası var, yeni eklenenleri görmek için, bu işe yaramaz (ve yapılmamalıdır). Ayrıca, insanlar N kaydının N + 1'den önce oluşturulduğunu varsayarlar. Bence kolay bir cevap yok.

Son olarak, MySQL hakkında bilmiyorum, ancak sınıra ulaştıysanız SQL Server bir taşma hatası verir.


1
Bu kadar ayrıntılı bir cevaptan memnunum. VARCHAR, INT ve BIGINT anlaşmasının açıklaması için teşekkürler. Soru varsayımsal olduğu için, eğer BIGINT sınırına da ulaşılırsa ne olacağını merak ediyorum. Soru, INT'leri kullanarak ve sınıra ulaşan facebook hakkında gördüğüm bir mesajla ortaya çıktı ve tamamen mümkün olduğunu görüyorum. Arşivleme çalışır veya koşullu bir ifadeyle ikinci bir tablo oluşturur (söylediğiniz gibi komut dosyalarının da güncellenmesini gerektirir ve oldukça karmaşıktır). Genel olarak, harika bir cevap. Geçen zamanı takdir ediyorum.
AeroCross

9

Göz ardı edilen bir nokta, birçok halkın otomatik numarayı veya kimliği 1'de başlatması ve böylece olası aralığın yarısını derhal kaybetmesidir (imzalı)

Bu durumda -1 ile başlayacak şekilde sayıyı yeniden tanımlamanız yeterlidir.

Muhtemelen, kimlik sütununuzu doldurmayı umuyorsanız, bunu tasarlamalı ve başlangıçta daha geniş bir veri türü kullanmalısınız.

Bu son soruyu görün SO: SQL Server 2008: kimlik int'in maksimum değerini aşarsa ne oldu?


Daha geniş bir veri türü kullanacağım mantıklı (bu miktardaki veriyi nasıl yapacak bir tablo için), ancak varsayımsal bir soru olduğu için biraz bilgi istedim. İmzalanmışsa, bu işe yarayabilir (ancak negatif sayılarla birincil bir anahtara sahip olmak biraz garip olurdu, IMHO) ve bence oldukça zekice. DBA'nın olumlu verileri arşivlemesi ve yeniden başlaması zaman alacaktı. İmzasızsa, iyi ... sorunlar.
AeroCross

Alternatif olarak -1'den -1 artışını kullanmaya başlayın, (-2147483648) değerinden başlayın ve 1 ile artırın. Ancak evet, INT_MAX'ı geçtikten sonra oldukça iyi bir şekilde evlendiniz ve tasarımı tekrar gözden geçirmeniz ve eski dizini kaldırmanız gerekiyor yeni bir büyük ile. ve imzasız BIGINT'i geçerseniz ekibinizde işe gelmek istiyorum;)
jcolebrand

PostgreSQL, kimlik numaraları oluşturmak için dizileri kullanır; CREATE SEQUENCE ifadesi, maksimum değere ulaşırsanız etrafı saran CYCLE'ı belirtmenize olanak tanır. (Ya da diğer yöne gidiyorsanız minimum değer.) CYCLE seçeneği şimdi SQL standartlarında. (En az 2003'ten beri.)
Mike Sherrill 'Cat Recall'

4

BÜYÜK taşma? Haha. İlk önce ölümsüzlüğe nasıl ulaşılacağını öğrenin. INT UNSIGNED (4 milyar) ulaşmak için yeterince zor. Saniyede 100 INSERT, bir yılda taşan INT'ye yaklaşacaktır. BIGINT birkaç milyar yıl alacaktı.

Düzeltmek için: ALTER TABLE foo COLUMN kimliğini değiştir BIGINT UNSIGNED NOT NULL AUTO_INCREMENT; Ama bu saatler alacak çünkü masanın üzerine kopyalanacak (4 milyar sıraya yakın, değil mi?) Ve tüm ikincil dizinleri yeniden oluşturacak. Önceden planlamak.

Genellikle bir alan için çok büyük bir sayı saklamaya çalıştığınızda (örn. TINYINT AMAÇLI 999), sessizce alanın maks. Değerine sınırlar (bu durumda 255). Bir "Uyarı" olabilir, ancak çoğu kişi uyarıları kontrol etmekle uğraşmaz. EŞSİZ bir alan veya YABANCI TUŞLAR varsa, daha ciddi bir hata alabilirsiniz.

CHAR veya VARCHAR mevcut alana sessizce kesilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.