CHAR mı VARCHAR mı? Sabit ve Değişken Uzunluklu Metin Sütunları
CHAR, tanımlanan uzunluğa kadar boşlukla doldurulan sabit uzunluklu metin tipidir; VARCHAR ise yalnız girilen değeri saklayan değişken uzunluklu tiptir. Seçim, veri değerlerinin uzunluğunun ne kadar sabit olduğuna ve kullandığınız veritabanının bu tipleri nasıl işlediğine bağlıdır.
Bir bakışta
- CHAR kısa değeri boşlukla doldurur, VARCHAR olduğu gibi saklar. Bu fark hem depolama alanını hem karşılaştırma ve birleştirme sonuçlarını etkiler.
- Parantez içindeki uzunluk her veritabanında aynı anlama gelmez. SQL Server'da bu değer bayt, PostgreSQL ve MySQL'de karakter sayısıdır.
- PostgreSQL'de CHAR'ın performans avantajı yoktur. PostgreSQL belgeleri, ek depolama nedeniyle CHAR'ın genellikle en yavaş seçenek olduğunu ve çoğu durumda VARCHAR ya da TEXT'in tercih edilmesini önerir.
- Türkçe karakterler bayt hesabını değiştirir. UTF-8'de ç, ş, ğ gibi harfler birden fazla bayt kaplar; bayt tabanlı uzunlukta sığacak karakter sayısı azalır.
- Uzun değer davranışı veritabanına göre değişir. Fazla uzun değer bazı durumlarda hata verir, bazı durumlarda sessizce kırpılır; bu fark veri kaybının kaynağı olabilir.
Ortak zemin: ikisi de metin saklar
CHAR ve VARCHAR, SQL standardında tanımlı iki karakter veri tipidir ve ilişkisel veritabanlarının neredeyse hepsinde bulunur. İkisi de bir uzunluk sınırıyla tanımlanır, CHAR(n) ve VARCHAR(n) biçiminde. Sütun tanımı yapıldıktan sonra sorgularda ikisi de aynı metin fonksiyonlarıyla, aynı LIKE ve karşılaştırma işleçleriyle kullanılır.
Temel fark depolama biçimindedir. CHAR sabit uzunlukludur: tanımlanandan kısa bir değer, uzunluk tamamlanana kadar sağdan boşlukla doldurulur. VARCHAR değişken uzunlukludur: yalnız girilen değeri ve uzunluğunu gösteren küçük bir ek bilgiyi saklar. Örneğin CHAR(n) olarak tanımlanmış bir sütuna kısa bir kod yazıldığında, saklanan değer kodun sonuna eklenmiş boşluklarla birlikte tam uzunluktadır; aynı kod VARCHAR(n) sütununda yalnız kendi uzunluğu kadar yer kaplar.
Bu basit fark, üç yerde sonuç doğurur: depolama alanı, sondaki boşlukların karşılaştırmada nasıl ele alındığı ve uzun değerlerin nasıl işlendiği. Üçünde de veritabanları birbirinden farklı davranır.
Ölçüt ölçüt CHAR ve VARCHAR
- Ölçüt: Uzunluk. CHAR: sabit; her değer tanımlanan uzunlukta saklanır. / VARCHAR: değişken; değer kendi uzunluğu kadar saklanır.
- Ölçüt: Doldurma. CHAR: kısa değerler sağdan boşlukla doldurulur. / VARCHAR: doldurma yapılmaz; girilen sondaki boşluklar korunur.
- Ölçüt: Ek bilgi. CHAR: uzunluk bilgisi gerekmez. / VARCHAR: değerin uzunluğunu tutan küçük bir ön ek saklanır.
- Ölçüt: Uygun veri. CHAR: uzunluğu hep aynı olan değerler; ülke ya da para birimi kodu, sabit uzunluklu referans kodları. / VARCHAR: uzunluğu değişen değerler; ad, e-posta, adres, açıklama.
- Ölçüt: Alan kullanımı. CHAR: değerler kısa kaldıkça boşa alan harcar. / VARCHAR: değer kadar alan kullanır.
- Ölçüt: Karşılaştırma. CHAR: sondaki boşluklar çoğu veritabanında anlamsız sayılır. / VARCHAR: sondaki boşlukların anlamlı olup olmadığı veritabanına ve harmanlamaya bağlıdır.
Microsoft'un SQL Server belgesi pratik bir kural verir: sütundaki değerlerin uzunluğu tutarlıysa CHAR, belirgin biçimde değişiyorsa VARCHAR, değişken ve çok uzun olabiliyorsa VARCHAR(max) kullanın.
Lehçe farkları: SQL Server, PostgreSQL ve MySQL
Aynı tip adı her veritabanında aynı davranmaz. En önemli farklar şunlardır.
SQL Server: Parantez içindeki uzunluk karakter sayısı değil, bayt cinsinden uzunluktur. Microsoft belgesi bunun yaygın bir yanılgı olduğunu açıkça vurgular. Tek baytlık kodlamada bayt ve karakter sayısı aynıdır; UTF-8 gibi çok baytlı kodlamada ise bir karakter birden fazla bayt kaplayabildiği için sütuna sığan karakter sayısı azalır. VARCHAR(max) çok uzun metinler için kullanılır. Bildirimde uzunluk yazılmazsa varsayılan uzunluk tek karakterdir; CAST ve CONVERT içinde uzunluk yazılmazsa varsayılan farklıdır. Bu yüzden uzunluğu her zaman açıkça yazmak gerekir.
PostgreSQL: Uzunluk karakter sayısıdır. Belgeler, üç tip arasında performans farkı olmadığını, CHAR'ın ek depolama nedeniyle genellikle en yavaşı olduğunu ve çoğu durumda TEXT ya da VARCHAR kullanılmasını önerir. Uzunluksuz VARCHAR her uzunlukta metni kabul eder. Fazla uzun bir değer eklemek hata verir; ancak değeri açıkça VARCHAR(n) tipine dönüştürürseniz sessizce kırpılır.
MySQL: Uzunluk karakter sayısıdır. CHAR değerleri saklanırken boşlukla doldurulur, okunurken sondaki boşluklar kaldırılır. VARCHAR sondaki boşlukları korur. Katı SQL modu açıksa fazla uzun değer hata verir; kapalıysa değer kırpılır ve yalnız uyarı üretilir. Sondaki boşlukların karşılaştırmada dikkate alınıp alınmayacağını harmanlamanın doldurma özelliği belirler.
Aynı tip adı, üç veritabanında farklı kurallar
| SQL Server | PostgreSQL | MySQL | |
|---|---|---|---|
| Uzunluk birimi | Bayt | Karakter | Karakter |
| CHAR okunurken | Boşluklarla birlikte döner | Boşluklarla saklanır ve gösterilir | Sondaki boşluklar kaldırılır |
| Fazla uzun değer | Dönüşümde kırpılır | Hata; açık dönüşümde kırpılır | Katı modda hata, değilse kırpma |
| Çok uzun metin | VARCHAR(max) | TEXT ya da uzunluksuz VARCHAR | VARCHAR ya da TEXT türleri |
| Unicode metin | UTF-8 harmanlaması ya da NVARCHAR | Veritabanı karakter kümesiyle | Karakter kümesi ve harmanlamayla |
NVARCHAR ve Türkçe karakterler
NVARCHAR ve NCHAR, SQL Server'ın Unicode metin tipleridir ve Türkçe sitelerde en çok karıştırılan konu budur. SQL Server'da CHAR ve VARCHAR, sütunun harmanlamasına bağlı bir kod sayfasıyla saklanır. Microsoft belgesine göre harmanlama UTF-8 destekli değilse bu tipler yalnız o kod sayfasının desteklediği karakterleri saklayabilir; UTF-8 destekli bir harmanlama seçildiğinde ise tüm Unicode karakter aralığını saklayabilir.
Belge, birden çok dili destekleyen sistemler için iki yol önerir: UTF-8 harmanlamasını destekleyen sürümlerde UTF-8 harmanlaması kullanmayı düşünmek, daha eski sürümlerde ise karakter dönüşüm sorunlarını en aza indirmek için NCHAR ve NVARCHAR kullanmak.
Türkçe açısından pratik sonuç şudur: ç, ş, ğ, ı, ö, ü ve İ gibi harfler UTF-8'de birden fazla bayt kaplar. SQL Server'da UTF-8 harmanlamalı bir VARCHAR sütununda uzunluk bayt olduğu için, Türkçe harf yoğun bir ad beklenenden daha az karaktere sığar. PostgreSQL ve MySQL'de uzunluk karakter cinsinden olduğu için bu sorun sütun tanımında yaşanmaz; ama depolama alanı yine bayt üzerinden hesaplanır.
PostgreSQL ve MySQL'de ayrı bir NVARCHAR ihtiyacı genellikle yoktur; Unicode desteği veritabanı ya da sütun düzeyindeki karakter kümesi ve harmanlamayla sağlanır.
Hangi sütunda hangisi?
Kararı veren soru, değerlerin uzunluğunun gerçekten sabit olup olmadığıdır. "Genellikle aynı uzunlukta" yeterli değildir; tek bir istisna, CHAR sütununun anlamını bozar.
CHAR için uygun adaylar, tanımı gereği sabit uzunlukta olan kodlardır: standart ülke ve para birimi kodları, sabit biçimli iç referans kodları. Bunlar dışında ad, soyad, e-posta, adres, ürün adı ve açıklama gibi alanların neredeyse tamamı VARCHAR'a aittir.
PostgreSQL kullanıyorsanız karar daha da basittir: belgelerin önerisi doğrultusunda çoğu durumda TEXT ya da VARCHAR kullanılır, sabit uzunluk kuralı gerekiyorsa bu bir kontrol kısıtıyla ifade edilebilir. SQL Server'da Türkçe ya da çok dilli metin saklayacaksanız harmanlama ve NVARCHAR kararını uzunluk kararından önce verin.
Son olarak, VARCHAR(n) içindeki n bir iş kuralıdır, performans ayarı değildir. Uzunluğu gerçek veriye göre belirleyin; aşırı küçük seçmek veri kaybına, gereksiz büyük seçmek ise iş kuralının belirsizleşmesine yol açar.
Seçimi değerin uzunluğu ve karakter ihtiyacı belirler
- Her değer tanımı gereği aynı uzunluktaCHAR(n)Ülke ya da para birimi kodu gibi sabit biçimli kodlar.
- Uzunluk değerden değere değişiyorVARCHAR(n)Ad, e-posta, adres; n gerçek veriye göre seçilir.
- Metin çok uzun olabilirVARCHAR(max) ya da TEXTSQL Server'da VARCHAR(max), PostgreSQL'de TEXT.
- SQL Server, çok dilli ya da Türkçe metinUTF-8 harmanlaması ya da NVARCHARUzunluğun bayt olduğunu unutmayın.
İlgili Mindset programı
SQL ile Programlama Eğitimi
Sık sorulan sorular
CHAR sütununda karşılaştırma yaparken neden beklenmedik sonuçlar çıkar?
CHAR değerleri sondaki boşluklarla saklandığı için, aynı metnin VARCHAR ya da düz metin karşılığıyla karşılaştırılması veritabanına göre farklı sonuç verebilir. PostgreSQL CHAR değerlerinde sondaki boşlukları karşılaştırmada anlamsız sayar ama LIKE ve düzenli ifadelerde dikkate alır. MySQL'de bunu harmanlamanın doldurma özelliği belirler. Sorunsuz bir yol, değişken uzunluklu veriyi baştan VARCHAR olarak saklamaktır.
VARCHAR sütununu gereğinden büyük tanımlamanın zararı var mı?
Saklanan değer kadar alan kullanıldığı için doğrudan depolama kaybı genellikle yoktur. Ancak uzunluk sınırı aynı zamanda bir veri kalitesi kuralıdır; çok geniş tanımlanan sütun hatalı ya da anlamsız uzun girişleri engellemez. SQL Server'da VARCHAR(max) sütunların satır boyutu ve bazı işlemlerdeki ek yükü konusunda belgede ayrıca uyarı bulunur. Bu yüzden uzunluğu gerçek veriye göre seçmek en sağlıklı yoldur.
Var olan bir CHAR sütununu VARCHAR'a çevirmek güvenli mi?
Dönüşüm genellikle mümkündür ama iki noktaya dikkat edilmelidir. Birincisi, CHAR değerlerindeki dolgu boşluklarının dönüşümde ne olacağı veritabanına göre değişir; PostgreSQL CHAR değerini başka bir metin tipine çevirirken sondaki boşlukları kaldırır. İkincisi, sütunu kullanan sorgu, indeks ve uygulama kodunun sondaki boşluklara bağlı bir karşılaştırma yapıp yapmadığı önceden test edilmelidir. Değişikliği önce test ortamında, gerçek veriyle denemek gerekir.
TEXT ile VARCHAR arasında ne fark var?
PostgreSQL'de TEXT, uzunluk sınırı olmayan yerel metin tipidir ve belgeler TEXT, VARCHAR ve uzunluksuz VARCHAR arasında performans farkı olmadığını belirtir; VARCHAR(n) yalnız uzunluk kontrolü ekler. SQL Server'da ise eski TEXT tipi yerine VARCHAR(max) kullanılır. MySQL'de TEXT türleri ayrı bir tip ailesidir ve VARCHAR'dan farklı depolama kurallarına sahiptir. Seçim, kullandığınız veritabanının belgesine göre yapılmalıdır.
Sabit uzunluklu kodlarda CHAR kullanmak performans kazandırır mı?
Veritabanına göre değişir. PostgreSQL belgeleri bu konuda açıktır: CHAR'ın bazı başka veritabanlarında performans avantajı olabileceğini, PostgreSQL'de ise böyle bir avantaj bulunmadığını ve ek depolama nedeniyle genellikle en yavaş seçenek olduğunu belirtir. SQL Server ve MySQL'de sabit uzunluklu kodlar için CHAR yaygın bir tercihtir, ama kazanç genellikle küçüktür. Asıl belirleyici, verinin gerçekten sabit uzunlukta olmasıdır; performans iddiasını kendi veriniz ve sorgularınızla ölçmeden genellemeyin.
İlgili rehberler
İlgili eğitimler
Kategori: Veri Analitiği ve İş Zekası