Zaten birkaç tane daha olduğu için buraya başka bir cevap eklemekte tereddüt ediyorum, ancak ya henüz yapılmayan ya da net bir şekilde yapılmayan birkaç noktaya değinmek gerekiyor.
Birincisi: Do not her zaman kullanma NVARCHAR
. Bu çok tehlikeli ve genellikle maliyetli bir tutum / yaklaşımdır. Ve bu "demek iyi değildir asla belli bir problem çözme en etkili aracı bazen, ve ortak çalışma etrafında bir yapmanın beri kullanımı imleçlerini" WHILE
döngü hemen hemen her zaman daha yavaş olacaktır düzgün yapılması İmleç.
"Her zaman" terimini kullanmanız gereken tek zaman, "her zaman durum için en iyisini yapmayı" tavsiye etmektir. Özellikle geliştirme süresindeki kısa vadeli kazançları dengelemeye çalışırken (yönetici: "şu ana kadar bilmediğiniz bir özelliğe ihtiyacımız var - bir hafta öncesine!") Belirlemek genellikle zor bir şeydir. dönem bakım maliyetleri (başlangıçta 3 aylık bir projede 3 aylık bir projeyi tamamlamak için ekibe baskı yapan yönetici: "Neden bu performans sorunları yaşıyoruz? Esnekliği olmayan X'i nasıl yapabilirdik? Ödeyemeyiz? Bunu düzeltmek için bir veya iki sprint. Öncelikli ürünlerimize geri dönebilmek için bir hafta içinde ne yapabiliriz? Ve kesinlikle tasarımda daha fazla zaman harcamamız gerekiyor, böylece bu olmaya devam etmiyor! ").
İkincisi: @ gbn'nin cevabı, yol% 100 net olmadığında belirli veri modelleme kararları verirken dikkate alınması gereken bazı önemli noktalara değiniyor. Ancak dikkate alınması gereken daha çok şey var:
- işlem günlüğü dosyalarının boyutu
- çoğaltma süresi (çoğaltma kullanılıyorsa)
- ETL'ye kadar geçen süre (ETLing ise)
- günlükleri uzak bir sisteme göndermek ve geri yüklemek için gereken süre (Günlük Gönderimi kullanılıyorsa)
- yedeklerin boyutu
- yedeklemenin tamamlanması için geçen süre
- geri yükleme yapmak için gereken süre (bu bir gün önemli olabilir ;-)
- tempdb için gerekli boyut
- tetikleyicilerin performansı (tempdb'de saklanan eklenen ve silinen tablolar için)
- satır sürüm oluşturma performansı (sürüm deposu tempdb olduğundan SNAPSHOT ISOLATION kullanılıyorsa)
- CFO, geçen yıl bir SAN'a az önce 1 milyon dolar harcadıklarını söylediğinde yeni disk alanı elde etme yeteneği ve bu nedenle ek depolama alanı için 250 bin dolar daha yetki almayacaklar
- INSERT ve UPDATE işlemlerini yapmak için gereken süre
- dizin bakımı yapmak için gereken süre
- vb, vb.
Alanın boşa harcanması , tüm sistem üzerinde büyük bir kademeli etkiye sahiptir . Bu konuda açık bir ayrıntıya giren bir makale yazdım: Disk Ucuz! ORLY? (ücretsiz kayıt gereklidir; üzgünüm bu politikayı kontrol etmiyorum).
Üçüncüsü: Bazı cevaplar yanlış bir şekilde "bu küçük bir uygulama" yönüne odaklanırken, bazıları doğru şekilde "uygun olanı kullan" ı önerirken, cevapların hiçbiri OP'ye gerçek bir rehberlik sağlamamıştır Soruda belirtilen önemli bir ayrıntı bu onların okulları için bir web sayfası olması. Harika! Yani şunu önerebiliriz:
- Öğrenci ve / veya Fakülte adları için alanlar olmalıdır muhtemelen olmak
NVARCHAR
zamanla, sadece daha büyük olasılıkla diğer kültürlerden isimleri oralara gösterilmesini olacağını oluyor, çünkü.
- Ama sokak adresi ve şehir adları için? Uygulamanın amacı belirtilmedi (yardımcı olurdu), ancak adres kayıtlarının varsa, sadece belirli bir coğrafi bölgeye (yani tek bir dil / kültür) ait olduğunu varsayarak
VARCHAR
, uygun Kod Sayfası ( alanın Harmanlamasından belirlenir).
- Eyalet ve / veya Ülke ISO kodlarını saklıyorsanız ( ISO kodlarının sabit uzunluklu, insan tarafından okunabilir ve standart olduğu için
INT
/ depolanmasına gerek yoktur TINYINT
:) CHAR(2)
iki harf kodu için kullanın ve CHAR(3)
3 harf kodu kullanıyorsanız. Ve gibi bir ikili Harmanlama kullanmayı düşünün Latin1_General_100_BIN2
.
- Posta kodlarını (posta kodlarını) saklıyorsanız
VARCHAR
, AZ dışında herhangi bir harf kullanmamak uluslararası bir standart olduğu için kullanın. Ve evet, VARCHAR
posta kodları sayı olmadığından, dizeler olduğundan ve bazılarının önde gelen "0" ına sahip oldukları için yalnızca ABD posta kodlarını saklasanız ve INT'yi saklamasanız bile kullanın . Ve gibi bir ikili Harmanlama kullanmayı düşünün Latin1_General_100_BIN2
.
- E-posta adreslerini ve / veya URL'leri saklıyorsanız,
NVARCHAR
her ikisi de artık Unicode karakterler içerebileceğinden kullanın .
- ve bunun gibi....
Dördüncüsü: Artık, NVARCHAR
veriye güzelce uyan VARCHAR
("güzelce uyuyor" = "?" Ye dönüşmeyen) veriler için gerekenden iki kat daha fazla yer kapladığınıza ve bir şekilde, sihirle uygulama büyüdüğü gibi ve şimdi, çoğu satırın standart ASCII olduğu ancak bazılarının Unicode karakterleri içerdiği bu alanlardan en az birinde milyonlarca kayıt var, bu nedenle saklamanız gerekiyor NVARCHAR
:
SQL Server 2008 - 2016 RTM kullanıyorsanız ve Enterprise Edition kullanıyorsanız VEYA SQL Server 2016 SP1 (Veri Sıkıştırmayı tüm sürümlerde kullanılabilir yapan) veya daha yeni bir sürüm kullanıyorsanız, Veri Sıkıştırma'yı etkinleştirebilirsiniz . Veri Sıkıştırma, NCHAR
ve NVARCHAR
alanlardaki Unicode verilerini sıkıştırabilir (ancak "her zaman" olmaz) . Belirleyici faktörler:
NCHAR(1 - 4000)
ve UnicodeNVARCHAR(1 - 4000)
için Standart Sıkıştırma Şemasını kullanın , ancak yalnızca SQL Server 2008 R2'den başlayarak VE yalnızca IN ROW verileri için değil, OVERFLOW! Bu normal ROW / PAGE sıkıştırma algoritmasından daha iyi görünmektedir.
NVARCHAR(MAX)
ve XML
(ve ben de tahmin VARBINARY(MAX)
, TEXT
ve NTEXT
) (değil LOB veya DOLDU sayfalarında satırda kapalı) en az SAYFA sıkıştırılmış olabilir ama SIRA veriler olduğunu değil sıkıştırılmış sıra. Tabii ki, PAGE sıkıştırması satır içi değerin boyutuna bağlıdır: VARCHAR (MAX) ile test ettim ve 6000 karakter / bayt satırın sıkıştırmayacağını, ancak 4000 karakter / bayt satırın yaptığını gördüm.
- Herhangi bir OFF ROW verisi, LOB veya OVERLOW = Sizin İçin Sıkıştırma Yok!
Enterprise Edition'da değil , SQL Server 2005 veya 2008-2016 RTM kullanıyorsanız , iki alanınız olabilir: bir VARCHAR
ve bir NVARCHAR
. Örneğin, çoğunlukla tüm temel ASCII karakterleri (0 - 127 değerleri) olan ve bu nedenle VARCHAR
de Unicode karakterlere uyan URL'leri sakladığınızı varsayalım . Şemanız aşağıdaki 3 alanı içerebilir:
...
URLa VARCHAR(2048) NULL,
URLu NVARCHAR(2048) NULL,
URL AS (ISNULL(CONVERT(NVARCHAR([URLa])), [URLu])),
CONSTRAINT [CK_TableName_OneUrlMax] CHECK (
([URLa] IS NOT NULL OR [URLu] IS NOT NULL)
AND ([URLa] IS NULL OR [URLu] IS NULL))
);
Bu modelde yalnızca[URL]
hesaplanan sütundan SEÇ . Eklemek ve güncellemek için, dönüştürmenin gelen değeri değiştirip değiştirmediğini görerek hangi alanın kullanılacağını belirlersiniz NVARCHAR
:
INSERT INTO TableName (..., URLa, URLu)
VALUES (...,
IIF (CONVERT(VARCHAR(2048), @URL) = @URL, @URL, NULL),
IIF (CONVERT(VARCHAR(2048), @URL) <> @URL, NULL, @URL)
);
Gelen değerleri GZIP'e girebilir VARBINARY(MAX)
ve çıkış yolundan açabilirsiniz :
- SQL Server 2005-2014 için: SQLCLR kullanabilirsiniz. SQL # (yazdığım bir SQLCLR kütüphanesi) Ücretsiz sürümünde Util_GZip ve Util_GUnzip ile birlikte geliyor
- SQL Server 2016 ve daha yeni sürümler için: GZip olan yerleşik
COMPRESS
ve DECOMPRESS
işlevleri kullanabilirsiniz .
SQL Server 2017 veya daha yenisini kullanıyorsanız, tabloyu Kümelenmiş Sütun Dizini Oluşturma konusuna bakabilirsiniz.
Bu henüz geçerli bir seçenek olmasa da, SQL Server 2019, UTF-8 in VARCHAR
/ CHAR
datatypes için yerel destek sunar . Şu anda kullanılabilmesi için çok fazla hata var, ancak düzeltildiyse, bu bazı senaryolar için bir seçenektir . Bu yeni özelliğin ayrıntılı bir analizi için lütfen " SQL Server 2019'da Yerel UTF-8 Desteği: Kurtarıcı veya Sahte Peygamber? "