INT üzerinde TINYINT ne zaman kullanılır?


91

Genelde, her zaman Ints kullanırım. Teoride bunun en iyi uygulama olmadığını biliyorum, çünkü verileri saklamak için garanti edilecek en küçük veri türünü kullanmanız gerekir .

Örneğin, tinyintsaklayacağınız tek verinin 1, 0 veya boş olduğunu bildiğiniz zaman kullanmak daha iyidir (bunu daha sonra 2 veya 3'e genişletme şansı çok azdır).

Bununla birlikte, bunu yapmamın tek nedeni depolama amaçlı - 4 bayt yerine bir satırda 1 bayt kullanmak.

Sabit diskinizde yer kazanmak dışında, sadece kullanmanın tinyint(veya smallinthatta hatta bigint) kullanımının etkileri nelerdir int?


2
Bu çok hoş bir soru (+1). MySQL SELECT ... PROCEDURE ANALYZE () işlevine sahiptir ve bu da tablonun verilen SELECT için sahip olması gereken en küçük veri tiplerini önerir. Bu kısmen cevabımın arkasındaki ilham kaynağı oldu.
RolandoMySQLDBA 23:11

3
Güzel bir soru, ama hassas olanı küçültmek aralığı 0-255. Bit alanı 0 veya 1'dir (veya NULL). Bir minik için depolama maliyeti 1 bayttır. Bir tablodaki her 8 bit alan 1 baytlık bir depolama alanına mal olur. msdn.microsoft.com/en-us/library/ms187745.aspx ve msdn.microsoft.com/en-us/library/ms177603.aspx
billinkc

@billinkc Doğru. Bu nedenle, sütunu 2 veya 3 değerlerini içerecek şekilde genişletme olasılığından bahsettim. 2 veya 3 eklerseniz, tinyint kullanmak zorundasınız (en küçük ölçekte).
Richard,

1
"Örneğin, depolayacağınız tek verinin 1, 0 veya boş olduğunu bildiğiniz zaman tinyint kullanmak daha iyidir (bunu daha sonra 2 veya 3'e genişletmek için çok küçük bir şans)." Böyle bir şey için ENUM kullanırdım. Bunlar bit alanları olarak depolanır ve burada çoğu kişinin belirttiği gibi, kayıt başına küçük tasarruflar tüm veritabanı boyunca büyük tasarruflar sağlar - sütun dizine eklenmişse bile.

2
@ user6665 I'd use an ENUM for such a thing.SQL Server'da değil, herhangi bir numaralandırmaya sahip olmadığı için yapmazsınız .
underscore_d

Yanıtlar:


92

Disk alanı ucuz ... Mesele bu değil!

Depolama alanı açısından düşünmeyi bırakın, bunun yerine arabellek havuzu ve depolama bant genişliği hakkında düşünün . En uçta ise CPU önbellek ve bellek veriyolu bant genişliği . Bağlantılı makale, zayıf kümelenmiş anahtar seçimi (INT - GUID ve Sıralı GUID) ile ilgili sorunları vurgulayan serinin bir parçasıdır, ancak baytların yapabileceği farkı vurgulamaktadır.

En önemli mesaj tasarım konularıdır. Fark, VLDB bölgesine ulaşana kadar belirli bir sunucuda ayrı bir veritabanında görünmeyecek, ancak birkaç bayt kaydedebiliyorsanız, neden olmasın?

Daha önceki bir soruda açıklanan çevreyi hatırlatıyorum . SQL örneği başına 50 MB-50 GB arasında değişen boyutta 400'den fazla veritabanı. Her ortam için kayıt başına, tablo başına, veritabanı başına birkaç baytı fırçalamak önemli bir fark yaratabilir.


29

Diğer cevaplara ek olarak ...

Satırlar ve dizin girişleri 8 k sayfada saklanır. Böylece, satır başına 3 baytlık bir milyon satır diskte 3 MB değildir: sayfa başına satır sayısını etkiler ("sayfa yoğunluğu").

Aynısı nvarchar için varchar, smalldatetime datetime, int tinyint vb. İçin de geçerlidir.

Düzenle, Haziran 2013

http://sqlblog.com/blogs/joe_chang/archive/2013/06/16/load-test-manifesto.aspx

Bu makalede

Önemli kriterler kardinalite ve sayfa / satır oranıdır.

Bu nedenle, veri tipi seçimi önemli


5
İyi bir nokta. Mutlak bir en kötü durum örneği, sütun eklemek istediğiniz tamamen sabit uzunlukta sütunlardan oluşan bir 4028 baytlık satırdır. Bir küçük resim eklemek sizi 4030'a (sayfa başına 2 satır) götürür, ancak bir int sizi sınırın üzerine getirir (sayfa başına 1 satır, sayfa başına 4028 bayt).
Mark Storey-Smith,

Bir keresinde int vs bigint üzerinde bir performans testi yaptım. 1 milyon kaydı saklamak, zaman ve depolamayı karşılaştırmak ve bunları birer birer almak, yine performansı ölçmek. Büyük farklılıklar görmedim. İnt vs tinyint için aynı performans testini yapacağım. Uygulamaların% 80'i için ihmal edilebileceğini, daha tutarlı veri türlerine ve daha az bakım maliyetlerine neden olabileceğini düşünüyorum.
Saeed Neamati,

1
@SaeedNeamati Sen isteyebilirsiniz makaleye yeniden okumasını gelen Mark'ın cevap ( " - Ben ... Bu her zaman duymak ... biz daha sonra performansı hakkında endişe edeceğiz? Haydi bu işi bitirelim ... Hiç duydunuz ") ve burada GBN en . Bence eve götürmek, verimsiz bir seçimin çizgilerini doğru ölçekte göstereceği ve OP'nin bağırsaklarının yanlış olmadığı anlamına geliyor.
00’de

14

Bu sadece dikkate değer bir tablo saklama alanı değil. İnt sütununun bir bileşik anahtarın parçası olduğu dizinleri kullanırsanız, dizin sayfalarının olabildiğince dolu olmasını doğal olarak istersiniz; bu, dizin girişlerinin mümkün olduğu kadar küçük olmasını sağlar.

BTREE sayfalarındaki dizin girişlerini incelemenin daha küçük veri türleriyle biraz daha hızlı olacağını kesinlikle beklerdim. Bununla birlikte, endeks girişlerine dahil olan herhangi bir VARCHAR, INT yerine TINYINT kullanmaktan kaynaklanan performans artışlarını dengeleyebilir (geçersiz kılar).

Bununla birlikte, dizin girişleri bileşik girişlere sahipse ve tümü tam sayıysa, tam sayılar ne kadar küçük olursa, o kadar iyi ve hızlı olur.


13

Veritabanları büyüyünce her şey karmaşıklık kazanır:

  • Bakım pencerelerinin büyütülmesi veya yeniden planlanması gerekiyor
  • yedeklemeler (günün sonundaki tam yedekleme çok saçma bir zaman alıcı haline gelir, bu nedenle bir farkına veya hatta günlük yedeklemesine ihtiyaç duyar ve haftada bir, belki de ayda bir kere tam doldurma yapmanız gerekir)
  • performanslar bakım zaman alıcı olur (çok milyon satırlık bir masa üzerinde bir endeks oluşturmak yürütmek için önemsiz bir zaman gerektirmez) ve yeniden planlanması gerekir ve masa genişse daha kötüleşir ...
  • Ve 100Gb yedeklemesini ağ üzerinden iletmek, bir parça kek dediğim şey değildir - özellikle ağ (bilinmeyen bir nedenden dolayı) 75 Gb işaretine bağlantıyı bırakma konusunda inatçıysa ... (bir kurulumla oldu) ağdaki eşlenmiş bir sürücüye yedekleme yapıyordu - ağ) ...

Peki bununla ilgili ne tür veriler yapmalı? HER ŞEY. Satır boyutlarının gerekenden daha büyük kullanılması, satırların sayfaya birden fazla kaydın kaydedilemeyecek şekilde olması durumunda veritabanı sayfalarının gerekenden önce doldurulmasına ve hatta boşa harcanmasına neden olur. Sonuç, yazmak ve okumak için daha fazla sayfa gerekir, önbelleğe almak için daha fazla RAM belleği kullanılır (daha büyük kayıtlar daha büyük bellek gerektirir). Veri türleriniz diskten gerekenden daha büyük olarak belirtildiğinden, dizinleriniz de aynı soruna neden olur - özellikle, oluşturulan 2 BIGINT sütun birincil anahtarını kümelendiyseniz, oluşturulan diğer tüm dizinler bu birincil anahtarı tanımlarına dolaylı olarak kopyalar.

Milyonlarca satırlık bir tablodaki bazı sütunların, hatta FK'ed'i milyonlarca sıraya çıkaracak küçük bir tabloya sahip olduğunu biliyorsanız, verilerini depolamak için 4 baytlık bir tamsayıya ihtiyaç duymaz, ancak 2 bayt olur. yeterli - SMALLINT kullanın . 0-255 aralığında değerler yeterliyse, TINYINT . Evet / Hayır bayrağı? Orada BIT .


9

tinyintVs için intdisk alanı, sayfa bölmeleri ve bakım süresi gibi belirgin farklar olsa da, bunların hiçbiri için olmazdı varchar.

Öyleyse neden tüm metin alanlarını açıklamıyorsunuz varchar(4000), çünkü yine de sadece gerekli alanı kullanacak. Daha da fazlası, verilerinizin asla kesilmeyeceği garanti edilir.

Cevap elbette:

  1. Niyetlerinizin açıklanması (hiç kimse bir isim alanının neden 4000 karakter olması gerektiğini anlayamayacağından)
  2. Kimsenin adının tamamını biyografiye girmediğinden emin olmak istediğinizde onaylama.

Bu aynı sebepler için tinyintde geçerli .


3
Bu daha eski bir konu, ancak açıklama ve doğrulama tek sebep değil. VARCHAR (4000) olması gereken VARCHAR (20) olması gereken bir şey için sorgu planınız, bellek ve CPU gereksinimlerinizin bu sütunda olması gerekenlerin katları olduğunu düşünecektir. Bunu yapmak için zaman ayırmadım, ancak bunu VARCHAR (20) için bir sorgu planına bakarak muhtemelen VARCHAR (4000) olarak değiştirip tahmini maliyetleri kontrol edebileceğinizi tahmin ediyorum.

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.