Beş Storage Class, O Kadar Çok Tip Yok
SQLite, her değeri beş storage class'tan birinde saklar:
NULL— değerin yokluğu.INTEGER— işaretli tam sayı; boyutuna göre 1 ila 8 bayt arasında yer kaplar.REAL— 8 baytlık IEEE kayan noktalı sayı.TEXT— veritabanının kodlamasıyla (genellikle UTF-8) saklanan metin.BLOB— ham bayt; ne verdiyseniz aynen öyle tutulur.
Hepsi bu. Ayrı bir BOOLEAN yok, DATETIME yok, VARCHAR yok, DECIMAL de yok. Diğer veritabanlarında onlarca tip bulunurken SQLite'da sadece beş tane var; geri kalan her şey bu beşinin üzerine kurulu.
typeof() size her değerin gerçek storage class'ını söyler. Karşınıza integer, real, text, blob çıkacak. SQLite'ın bildiği her şey bu dört tip — bir de null.
SQLite Dinamik Tipleme Nasıl Çalışır?
İşte Postgres veya MySQL'den gelenleri şaşırtan kısım: SQLite'ta (STRICT kullanmıyorsanız) bir kolona verdiğiniz tip aslında bir sözleşme değil, daha çok tavsiye niteliğinde. Asıl tip, her bir değerin kendisinde tutulur:
Her iki satır da sorunsuz kabul edildi. id kolonu bir satırda tam sayı, diğerinde metin tutuyor; body ise hem metin hem tam sayı barındırıyor. SQLite, herhangi bir storage class'a ait değeri herhangi bir kolonda gönül rahatlığıyla saklıyor.
İşte buna dinamik tipleme deniyor ve bu, bilinçli bir tasarım tercihi. SQLite'ı prototipleme ve hızlı script'ler için son derece esnek kılan da bu özellik. Ama madalyonun diğer yüzü şu: uygulama kodunuzdaki ufak bir yazım hatası, yıllar boyunca yanlış biçimde veri kaydedilmesine sessizce sebep olabilir. Bu denge sizi rahatsız ediyorsa — ki çoğu üretim şemasında rahatsız etmeli — çözüm STRICT tablolar. Onlara birazdan geleceğiz.
Tek Paragrafta Tip Yakınlığı (Type Affinity)
Bir kolonda belirttiğiniz tip yok sayılmıyor; o kolona bir affinity (yakınlık) kazandırıyor. Bir değer eklediğinizde SQLite, temiz bir dönüşüm mümkünse değeri kolonun yakınlık tipine çevirmeye çalışır. TEXT yakınlığına sahip bir kolona 42 sayısı eklerseniz, değer metin olarak '42' şeklinde tutulur; INTEGER yakınlığına sahip bir kolona '42' metnini verirseniz, tam sayı 42 olarak kaydedilir. Dönüşüm bilgi kaybına yol açacaksa, orijinal tip korunur.
Birinci satır: 42 tamsayısı '42' metnine, '100' metni de 100 tamsayısına dönüştürüldü. İkinci satır: '3.5' değeri INTEGER'a kayıpsız çevrilemediği için metin olarak kaldı. Affinity konusuna birazdan ayrı bir bölümde gireceğiz — şimdilik şunu bilin yeter: kolonun tipi zorlayıcı olmasa da depolamayı yine de etkiliyor.
Boolean değerleri
SQLite'ta BOOLEAN diye bir storage class yok. Boolean değerler tamsayı olarak saklanır — false için 0, true için 1:
TRUE ve FALSE anahtar kelimeleri (SQLite 3.23 ile birlikte) tanınıyor ve sırasıyla 1 ile 0 değerlerine karşılık geliyor. BOOLEAN olarak tanımlanan bir kolon sayısal affinity'ye sahip oluyor ama değerleri 0 veya 1 ile sınırlamıyor — yani STRICT kullanmadığınız sürece kolona pekâlâ 'maybe' yazabilirsiniz, SQLite gıkını çıkarmaz.
Tarih ve Saat Saklama
DATETIME diye bir tip de yok. Üç farklı kodlama biçiminden birini seçiyorsunuz ve SQLite'ın tarih fonksiyonları üçüyle de çalışıyor:
- ISO-8601 formatında
TEXT:'2026-04-23 14:30:00'. - Jülyen gün numarası olarak
REAL. - Unix epoch saniyesi olarak
INTEGER.
ISO-8601 metni en yaygın tercihtir — string olarak doğru sıralanır, insan tarafından okunabilir ve dahili fonksiyonların hepsi (date(), time(), datetime(), strftime(), julianday()) bu formatı tüketir. Her kolon için tek bir kodlama seçin ve ondan şaşmayın; aynı kolon içinde farklı formatları karıştırmak, altı ay sonra başınıza iş açacak türden bir hatadır.
VARCHAR, CHAR ve Tanıdık Diğer Tip Adları
SQLite, başka veritabanlarından alışkın olduğunuz tip adlarını da kabul eder — VARCHAR(255), CHAR(10), NVARCHAR, DECIMAL(10,2), DOUBLE, FLOAT, INT, BIGINT, MEDIUMINT. Hepsi sorunsuz parse edilir. Sadece arka planda affinity kurallarına göre beş storage class'tan birine eşlenirler.
VARCHAR(255) ifadesi 255 karakterlik bir sınır dayatmaz — SQLite uzunluk bilgisini görmezden gelir. DECIMAL(10, 2) de sabit hassasiyetli bir ondalık sayı saklamaz; numeric affinity alır ve içeride INTEGER ya da REAL olarak tutulur. Bu isimler yalnızca başka veritabanlarından kopyalanan şemaların hatasız çalışabilmesi için var; o isimlerin diğer sistemlerde getirdiği kısıtlamaları SQLite'a taşımıyorlar.
Para gibi kesin ondalık aritmetik gerektiren değerlerde, kuruşları INTEGER olarak saklayın. Kayan noktalı REAL tipi, er ya da geç üçüncü basamakta yuvarlama hatası üretir.
NULL Bir Storage Class'tır
NULL sadece "değer yok" demek değildir — kendi storage class'ına sahip bir değerdir ve typeof() ile sorgulandığında bunu görürsünüz:
b artık null olarak görünüyor. Bunun önemi şurada: NULL hiçbir şeye eşit değildir — başka bir NULL'a bile. Yani b = NULL ifadesi asla true dönmez; bunun yerine b IS NULL yazmak zorundasın. Bu konunun ayrıntıları ileride operatörler ve NULL sayfasında işlenecek ama temeli buradan, storage class'tan başlıyor.
BLOB ile Ham Bayt Saklama
BLOB, ham baytları olduğu gibi saklar — küçük görseller, hash değerleri, kodlanmış veriler, kısacası metin ya da sayı olmayan her şey için biçilmiş kaftandır:
x'...' literali sayesinde blob'ları SQL içinde hex olarak yazabilirsiniz; uygulama tarafında ise genellikle bir byte dizisini parametre üzerinden geçirirsiniz. Bir blob üzerinde length() çağırdığında karakter değil, byte sayısını alırsınız.
Pratik bir uyarı: SQLite büyük blob'ları sorunsuz saklar ama her sorguda 50 MB'lık bir blob'u satırla birlikte çekmek işleri yavaşlatır. Büyük dosyalar için dosyayı diskte tut, veritabanında yalnızca yolunu sakla.
Özetle Aklında Kalsın
- Beş storage class —
NULL,INTEGER,REAL,TEXT,BLOB— her ihtiyacı karşılar. - Boolean değerler aslında integer'dır; tarihler ise senin tercihine göre text, real ya da integer olarak tutulur.
- Tanımlanmış kolon tipleri birer sözleşme değil, sadece ipucudur (tabii
STRICTkullanmıyorsanız). VARCHAR(255)ve benzerleri sözdizimsel olarak kabul edilir ama başka veritabanlarındaki gibi uzunluk veya hassasiyet kısıtı uygulamaz.- Bir değerin gerçekte ne olarak saklandığından emin değilsen,
typeof(value)en iyi dostundur.
Sırada: Type Affinity
Yukarıda "ipucu" diye geçiştirdiğimiz davranışın aslında net bir kural seti var — beş affinity sınıfı, kolonun tanımlanmış tip adından türetilir ve her ekleme işleminde devreye girer. Bir sonraki sayfanın konusu bu; SQLite'ın verdiğiniz değerlerle gerçekte ne yapacağını tahmin etmenin anahtarı da burada.
Sıkça Sorulan Sorular
SQLite hangi veri tiplerini destekliyor?
SQLite'ın beş depolama sınıfı (storage class) vardır: NULL, INTEGER, REAL, TEXT ve BLOB. Veritabanındaki her değer bunlardan biri olarak saklanır. VARCHAR(255), DATETIME veya BOOLEAN gibi alıştığımız isimler CREATE TABLE içinde uyumluluk için kabul edilir, ama saklama anında bu beş sınıftan birine indirgenir.
SQLite'ta boolean veya datetime tipi var mı?
Ayrı bir storage class olarak yok. Boolean değerler INTEGER olarak saklanır (0 ve 1); buna ek olarak SQLite TRUE ve FALSE anahtar kelimelerini de tanır. Tarih ve saat ise TEXT (ISO-8601 string), REAL (Julian gün numarası) veya INTEGER (Unix epoch saniyesi) olarak tutulabilir — kodlamayı sen seçersin, tarih fonksiyonları üçünde de çalışır.
SQLite'ın tiplemesine neden 'dinamik' deniyor?
Çoğu veritabanında INTEGER olarak tanımlı bir kolon string kabul etmez. SQLite'ta ise (varsayılan davranışta) tanımlı tip yalnızca bir ipucu gibi çalışır — gerçek tip değerin kendisiyle birlikte taşınır. Yani TEXT bir kolona integer da yazabilirsin. Bu esneklik bazen işe yarar, bazen de ayağına dolanır. Kapatmak istersen STRICT tabloları devreye sokabilirsin.