Blocks of different shapes and sizes arranged in a row, representing SQL Server data types

SQL Server Veri Tipleri: Doğru Tip Nasıl Seçilir, Örtük Dönüşümden Nasıl Kaçınılır?

SQL Server’da tam sayı, para, metin ve tarih için doğru veri tipini seçmek; para için float’un neden yanlış olduğu, varchar ve nvarchar, datetime2 ve örtük dönüşümlerin index’i nasıl devre dışı bıraktığı.

Nisan 18, 2018

Veri tipi seçimi, tablo tasarımında en kolay atlanan ama sonradan değiştirilmesi en zor kararlardan biridir. Gerekenden geniş bir tip her satırda birkaç bayt fazla yer kaplar; bu fark milyonlarca satırda gigabaytlara, daha fazla okunan sayfaya, daha büyük index’lere ve daha uzun yedeklere dönüşür. Yanlış tip ise daha sinsi sorunlar yaratır: kuruşların kaybolduğu hesaplamalar, index’i kullanamayan sorgular, Türkçe karakterlerin bozulması.

Bu rehberde SQL Server’daki temel veri tiplerini, hangi durumda hangisinin seçileceğini ve en sık yapılan hataları anlatıyoruz.

SQL Server Danışmanlığı

Veri modelinizi gözden geçirmek mi istiyorsunuz?

Aryasoft, tablo ve veri tipi tasarımınızı performans, depolama ve veri doğruluğu açısından inceler.

Destek Alın

Tam Sayılar

Tip Boyut Aralık
tinyint 1 bayt 0 ile 255
smallint 2 bayt -32.768 ile 32.767
int 4 bayt yaklaşık ±2,1 milyar
bigint 8 bayt yaklaşık ±9,2 × 10^18

Değer aralığına uyan en küçük tipi seçin; ama büyümeyi de hesaba katın. Yoğun yazılan bir tablonun int IDENTITY kolonu 2,1 milyara ulaştığında insert’ler durur ve bigint’e geçiş büyük tablolarda saatler süren bir işlemdir. Hızla büyüyen log ve hareket tablolarında baştan bigint kullanmak daha güvenlidir.

Ondalık Sayılar ve Para

  • decimal(p, s) / numeric: Kesin değer saklar. Para, miktar, oran gibi tüm finansal veriler için doğru seçimdir.
  • float / real: Yaklaşık değer saklar. Bilimsel ölçümler için uygundur; para için kesinlikle uygun değildir.
  • money / smallmoney: Sabit 4 ondalık basamakla saklar; çarpma ve bölmede yuvarlama sorunları yaşatabilir. decimal genellikle daha öngörülebilirdir.

Uyarı

Para tutarlarını float olarak saklamak, toplamlarda kuruş farklarına ve “0,1 + 0,2 = 0,30000000000000004” türünden sonuçlara yol açar. Muhasebe ve faturalama verilerinde her zaman decimal kullanın ve hassasiyeti (örneğin decimal(19, 4)) iş kurallarına göre belirleyin.

Metin: char, varchar, nchar, nvarchar

Tip Uzunluk Karakter başına Ne zaman
char(n) Sabit 1 bayt (tek baytlık kod sayfaları) Hep aynı uzunlukta kodlar
varchar(n) Değişken 1 bayt; UTF-8 collation’da 1-4 bayt Yalnızca collation’ın kod sayfasındaki karakterler
nchar(n) Sabit 2 bayt (UTF-16) Sabit uzunlukta Unicode
nvarchar(n) Değişken 2 bayt, bazı karakterlerde 4 Çok dilli ya da belirsiz içerik

varchar, Turkish_CI_AS gibi bir collation ile Türkçe karakterleri saklayabilir; ancak kod sayfasında olmayan karakterler (başka alfabeler, emojiler) “?” olarak kaydedilir. Çok dilli veri ya da dışarıdan gelen serbest metin için nvarchar kullanın. SQL Server 2019 ve sonrasında _UTF8 ile biten collation’lar, varchar kolonlarında Unicode’u UTF-8 olarak saklamayı mümkün kılar. Collation seçimi için collation rehberimize bakın.

varchar(max) ve nvarchar(max) yalnızca 8.000 baytı (nvarchar’da 4.000 karakteri) aşabilecek veriler için kullanılmalıdır. Her kolonu max tanımlamak, index anahtarı olarak kullanılamamalarına ve bellek tahminlerinin şişmesine yol açar.

Tarih ve Saat

Tip Boyut Hassasiyet Not
date 3 bayt Gün Yalnızca tarih gerekiyorsa
time(n) 3-5 bayt 100 nanosaniye Yalnızca saat
datetime2(n) 6-8 bayt 100 nanosaniyeye kadar Yeni tasarımlar için önerilen
datetimeoffset(n) 8-10 bayt 100 nanosaniye Saat dilimi farkıyla birlikte
datetime 8 bayt ~3,33 milisaniye Eski; yeni tasarımda datetime2 tercih edin
smalldatetime 4 bayt Dakika Eski

Yalnızca tarih gerekiyorsa date kullanın. Saat de gerekiyorsa datetime2, hem daha geniş aralığa hem de ayarlanabilir hassasiyete sahiptir. Farklı saat dilimlerinden veri geliyorsa datetimeoffset ya da UTC’de saklamak tutarlılık sağlar.

Diğer Önemli Tipler

  • bit: Evet/hayır değerleri için; bir tablodaki en fazla 8 bit kolonu tek bir baytta saklanır.
  • uniqueidentifier: 16 baytlık GUID. Rastgele GUID’leri clustered index anahtarı yapmak, sürekli sayfa bölünmesine ve parçalanmaya yol açar; gerekiyorsa NEWSEQUENTIALID() ya da ayrı bir tam sayı anahtar kullanın.
  • varbinary(max): İkili veri. Büyük dosyaları veritabanında saklamak yedekleri ve restore süresini büyütür; çoğu zaman dosyayı dışarıda tutup yolunu saklamak daha iyidir.
  • xml ve json: Yarı yapılandırılmış veri. SQL Server 2025 yerel json veri tipini getirir; daha eski sürümlerde JSON nvarchar içinde saklanır.
  • vector: SQL Server 2025 ile gelen, gömme (embedding) vektörlerini saklamak ve benzerlik araması yapmak için tasarlanmış tip.
  • text, ntext, image: Kullanımdan kaldırılmıştır; yerine varchar(max), nvarchar(max) ve varbinary(max) kullanın.

Örtük Dönüşüm: Görünmeyen Performans Sorunu

Karşılaştırılan iki değerin tipi farklıysa, SQL Server birini diğerine dönüştürür. Dönüştürülen taraf index’li bir kolonsa, index seek yapılamaz ve tablo taranır. En klasik örnek, varchar bir kolonun nvarchar bir parametreyle karşılaştırılmasıdır:

-- MusteriKodu varchar(20) ve index'li
DECLARE @kod nvarchar(20) = N'M-1001';

-- Kolon nvarchar'a dönüştürülür; collation'a bağlı olarak index scan'e düşebilir
SELECT * FROM dbo.Musteri WHERE MusteriKodu = @kod;

-- Parametre kolonla aynı tipte: index seek
DECLARE @kod2 varchar(20) = 'M-1001';
SELECT * FROM dbo.Musteri WHERE MusteriKodu = @kod2;

Execution plan’da CONVERT_IMPLICIT uyarısı bu sorunun işaretidir. Uygulama tarafında parametre tiplerini kolon tipleriyle eşleştirmek (özellikle ORM’lerde string parametrelerin varsayılan olarak nvarchar gönderildiğini bilmek) bu tür sorunları kökten çözer. Aynı mantık join kolonları için de geçerlidir: birbirine join edilen kolonların tipleri aynı olmalıdır.

İpucu

Mevcut bir veritabanında tip uyumsuzluklarını bulmak için, aynı adı taşıyan kolonların farklı tablolarda farklı tiplerde tanımlanıp tanımlanmadığına bakın. Örneğin bir tabloda int, diğerinde varchar olan MusteriNo kolonları, join’lerde örtük dönüşümün ve yavaş sorguların sık rastlanan nedenidir.

SELECT c.name AS column_name,
       COUNT(DISTINCT TYPE_NAME(c.user_type_id) + '(' + CAST(c.max_length AS varchar(10)) + ')') AS type_variants,
       STRING_AGG(CONVERT(nvarchar(max), OBJECT_NAME(c.object_id) + ':' + TYPE_NAME(c.user_type_id)), ', ') AS usages
FROM sys.columns AS c
JOIN sys.tables AS t ON t.object_id = c.object_id
GROUP BY c.name
HAVING COUNT(DISTINCT TYPE_NAME(c.user_type_id) + '(' + CAST(c.max_length AS varchar(10)) + ')') > 1
ORDER BY type_variants DESC;

Kontrol Listesi

  • Tam sayılarda değer aralığına ve büyümeye uygun tip seçildi.
  • Para ve miktar verileri decimal; float yalnızca yaklaşık değerler için.
  • Çok dilli metin nvarchar; max tipler yalnızca gerektiğinde.
  • Yeni tasarımlarda datetime yerine date ya da datetime2.
  • Rastgele GUID’ler clustered index anahtarı değil.
  • text, ntext ve image kullanılmıyor.
  • Join edilen kolonlar ve uygulama parametreleri kolon tipleriyle uyumlu.
decimal (numeric). Kesin değer saklar; float yaklaşık değer sakladığı için toplamlarda kuruş farklarına yol açar.
Veri yalnızca collation’ın kod sayfasındaki karakterleri içeriyorsa varchar yeterlidir. Çok dilli ya da serbest metin için nvarchar kullanın. SQL Server 2019 ve sonrasında UTF-8 collation’lar varchar’da Unicode saklamaya da imkân verir.
Yeni tasarımlarda datetime2. Daha geniş aralık, ayarlanabilir hassasiyet ve çoğu durumda daha küçük boyut sunar. Yalnızca tarih gerekiyorsa date kullanın.
Index’li bir kolon başka bir tipe dönüştürülmek zorunda kalırsa SQL Server index seek yapamaz ve tabloyu tarar. Parametre ve join kolonlarının tiplerini eşleştirmek sorunu çözer.

SQL Server Danışmanlığı

Veri modelinizi sağlam temellere oturtun

Aryasoft’un kıdemli DBA ekibi tablo ve veri tipi tasarımınızı performans, depolama ve veri doğruluğu açısından inceler; örtük dönüşümleri ve tip uyumsuzluklarını bulup kesintisiz geçiş planlarıyla düzeltir.

4.7/5