---
title: 'Veri Tipleri'
source: 'https://academia.sh/tr/kurslar/iliskisel-kuram/veri-tipleri'
course: 'Veri Modelleme ve İlişkisel Kuram'
language: tr
updated: '2026-08-17T18:09:00+00:00'
license: 'CC BY-SA 4.0'
---

# Veri Tipleri

Tam sayı, ondalık ve kayan noktalı sayı seçimi; metin uzunluğu ve harmanlama; tarih ile saat diliminin saklanması; ikili veri, doğruluk değeri ve numaralandırma kalıpları.

Önceki beş ders şemayı kurdu: bağıntılar, anahtarlar, kısıtlar ve boş değerin mantığı.
Sütunların **ne tuttuğu** ise gerekçelendirilmeden geçildi — tarihler metin, tutarlar tam
sayı olarak yazıldı. Bu dersin sorusu şudur: bir sütunun tipi hangi ölçütlere göre
seçilir, ve yanlış seçimin bedeli nerede ortaya çıkar?

Tip seçimi üç şeyi aynı anda belirler: hangi değerlerin saklanabileceği, karşılaştırma ve
sıralamanın nasıl yapılacağı, ve satır başına kaç bayt harcanacağı. İlk ikisi doğruluğu,
üçüncüsü maliyeti etkiler; yanlış seçim genellikle ilk ikisinden fark edilir.

## Sayılar ve Para

Bilgisayarlar Nasıl Çalışır kursu, kayan noktalı sayının ikilik kesirlerle çalıştığını ve
ondalık kesirlerin çoğunu tam gösteremediğini kurmuştu. O gerçek veritabanında da geçerlidir
ve ekranda görünmez:

```sh
sqlite3 :memory: <<'SQL'
.headers on
.mode box
SELECT 0.1 + 0.2       AS toplam,
       0.1 + 0.2 = 0.3 AS uce_onda_esit_mi,
       10 + 20 = 30    AS kurus_esit_mi;
SQL
```

```
┌────────┬──────────────────┬───────────────┐
│ toplam │ uce_onda_esit_mi │ kurus_esit_mi │
├────────┼──────────────────┼───────────────┤
│ 0.3    │ 0                │ 1             │
└────────┴──────────────────┴───────────────┘
```

Toplam ekranda `0.3` yazar ama `0.3` değildir. Gösterim yuvarlar, karşılaştırma yuvarlamaz.
Bir gecikme cezası bu tiple tutulursa, ödenen tutarla borç tutarının eşitliğini sınayan
sorgu bazen yanlış yanıt verir ve bu yanlışlık kuruşun altındadır — yani kütüğe bakan
kimse göremez.

Üç seçenek vardır. **Tam sayı** tipleri kesindir; para için en küçük birim seçilerek
kullanılır — tutar kuruş cinsinden tam sayı olarak saklanır, gösterimde yüze bölünür.
**Ondalık** tipleri (`NUMERIC`, `DECIMAL`) belirli bir basamak sayısıyla kesin ondalık
aritmetik sunar; parasal alan için standart karşılıktır. **Kayan noktalı** tipler ise
ölçüm, oran ve bilimsel büyüklük gibi zaten yaklaşık olan değerler içindir.

Kural şudur: sayılan şey için tam sayı ya da ondalık, ölçülen şey için kayan noktalı tip
kullanılır. Para sayılır.

Tam sayıda ikinci ölçüt genişliktir. Dar tip yer kazandırır ama taşma sınırını yaklaştırır;
üye numarası için iki baytlık bir tip seçmek, altmış beş binden fazla üye kaydedilemeyeceği
anlamına gelir. Taşmanın nasıl davrandığı — sarma mı hata mı — motora göre değişir; sınırı
en baştan geniş seçmek, sonradan tip değiştirmekten ucuzdur.

## Tipin Uygulanması

Tipin bildirilmiş olması, ona uyulacağı anlamına gelmeyebilir:

```sh
sqlite3 :memory: <<'SQL'
.headers on
.mode box
CREATE TABLE kitap (isbn TEXT PRIMARY KEY, yayin_yili INTEGER NOT NULL);
INSERT INTO kitap VALUES ('978-975-0000-01-1', 'iki bin on dokuz');
SELECT yayin_yili, typeof(yayin_yili) AS saklanan_tip FROM kitap;
SQL
```

```
┌──────────────────┬──────────────┐
│    yayin_yili    │ saklanan_tip │
├──────────────────┼──────────────┤
│ iki bin on dokuz │ text         │
└──────────────────┴──────────────┘
```

Sütun tam sayı olarak bildirilmiştir, saklanan değer metindir. **Tip bildiriminin ne kadar
bağlayıcı olduğu motora göre değişir**: kimi motor dönüşümü dener ve başarısız olursa
reddeder, kimi motor değeri olduğu gibi kabul eder. Taşınabilir savunma yine kısıttır —
alan tanımı, tipten bağımsız olarak değeri sınırlar:

```sh
sqlite3 :memory: <<'SQL'
CREATE TABLE kitap (
  isbn       TEXT PRIMARY KEY NOT NULL,
  yayin_yili INTEGER NOT NULL CHECK (yayin_yili BETWEEN 1450 AND 2100)
);
INSERT INTO kitap VALUES ('978-975-0000-01-1', 'iki bin on dokuz');
SQL
```

```
Runtime error near line 5: CHECK constraint failed: yayin_yili BETWEEN 1450 AND 2100 (19)
```

## Metin ve Harmanlama

Metin tipleri iki eksende ayrılır. **Uzunluk**: sabit uzunluklu tip her satırda aynı yeri
kullanır ve kısa değerleri boşlukla doldurur; değişken uzunluklu tip yalnız yazılanı
saklar. Sabit uzunluk yalnız gerçekten sabit veriler için — iki harfli ülke kodu, üç
karakterli şube kodu — yerindedir. **Sınır**: uzunluk sınırı bir alan kısıtıdır; şube
kodunun üç karakter olması kuralı, sınırsız bir metin sütunuyla ifade edilmez.

Asıl incelik karşılaştırmadadır. İki metnin eşit sayılıp sayılmayacağı ve hangisinin önce
geleceği, **harmanlamaya** (collation) bağlıdır:

```sh
sqlite3 :memory: <<'SQL'
.headers on
.mode box
SELECT 'ayse' = 'AYSE'                 AS ikili_karsilastirma,
       'ayse' = 'AYSE' COLLATE NOCASE  AS harmanli_karsilastirma,
       'ayşe' = 'AYŞE' COLLATE NOCASE  AS turkce_harfli;
SQL
```

```
┌─────────────────────┬────────────────────────┬───────────────┐
│ ikili_karsilastirma │ harmanli_karsilastirma │ turkce_harfli │
├─────────────────────┼────────────────────────┼───────────────┤
│ 0                   │ 1                      │ 0             │
└─────────────────────┴────────────────────────┴───────────────┘
```

Öntanımlı karşılaştırma bayt bayttır: `ayse` ile `AYSE` farklıdır. Büyük–küçük harf
duyarsız harmanlama seçildiğinde bu ikisi eşitlenir, ama `ayşe` ile `AYŞE` yine
eşitlenmez — bu harmanlama yalnız temel Latin harflerini kapsar. **Harmanlama adları ve
kapsamları motora göre değişir**; Türkçe metinle çalışan bir şemada dil duyarlı bir
harmanlamanın açıkça seçilmesi gerekir. Karakter Kodlamaları dersindeki normalleştirme
sorunu burada yeniden karşımıza çıkar: görünüşte aynı iki dizgi, kod noktası dizisi farklı
olduğunda eşit sayılmaz.

## Tarih ve Zaman

Tarih ve zaman için üç ayrı kavram vardır: yalnız tarih, yalnız saat, ve ikisini birleştiren
zaman damgası. Zaman damgasında ek bir ayrım daha bulunur — değer bir saat dilimine bağlı
mıdır, yoksa yerel duvar saati midir? Kütüphane açılış saati "09:00" yerel bir kuraldır;
ödünç işleminin gerçekleştiği an ise evrensel bir noktadır ve saat dilimiyle birlikte
saklanmalıdır.

Ayrı bir tarih tipi bulunmayan ortamlarda ISO 8601 biçiminde metin kullanılır. Bu biçimin
değerli yanı, sözlük sırasının kronolojik sıraya eşit olmasıdır:

```sh
sqlite3 :memory: <<'SQL'
.headers on
.mode box
.nullvalue (bos)
CREATE TABLE odunc (odunc_no INTEGER PRIMARY KEY, alis_tarihi TEXT NOT NULL,
                    iade_tarihi TEXT);
INSERT INTO odunc VALUES (1001, '2025-03-02', '2025-03-16'),
                         (1002, '2025-03-04', '2025-04-01'),
                         (1003, '2025-12-30', NULL);
SELECT odunc_no, alis_tarihi,
       julianday(iade_tarihi) - julianday(alis_tarihi) AS gun,
       alis_tarihi > '2025-03-03' AS mart_ucunden_sonra
FROM odunc ORDER BY alis_tarihi;
SQL
```

```
┌──────────┬─────────────┬───────┬────────────────────┐
│ odunc_no │ alis_tarihi │  gun  │ mart_ucunden_sonra │
├──────────┼─────────────┼───────┼────────────────────┤
│ 1001     │ 2025-03-02  │ 14.0  │ 0                  │
│ 1002     │ 2025-03-04  │ 28.0  │ 1                  │
│ 1003     │ 2025-12-30  │ (bos) │ 1                  │
└──────────┴─────────────┴───────┴────────────────────┘
```

Sıralama ve aralık karşılaştırması metin üzerinde doğru çalışır. Aritmetik ise tarih
işlevleri gerektirir ve **bu işlevlerin adları motora göre değişir**; burada gün farkı
almak için bir gün sayısına çeviren işlev kullanılmıştır. Metin gösteriminin bedeli budur:
tip denetimi yoktur, `'2025-13-45'` yazılabilir, ve her işlem ayrıştırma gerektirir. Ayrı
bir tarih tipi bulunan motorlarda o tip seçilir.

Sıfırlanmış bir tarih ya da `'0000-00-00'` gibi bir yer tutucu kullanmak, önceki dersteki
boş değer tartışmasını atlatmak için yapılan bir kaçamaktır ve her sorguda o yer tutucunun
elenmesini gerektirir. Bilinmeyen tarih için boş değer kullanılır.

## Doğruluk Değeri, İkili Veri ve Numaralandırma

Üç yaygın durum daha vardır.

- **Doğruluk değeri.** Ayrı bir tip bulunmayan motorlarda tek basamaklı bir tam sayı
  sütunu, yanına `CHECK (sutun IN (0, 1))` kısıtı yazılarak kullanılır. Kısıt olmadan
  sütun üçüncü bir değer alabilir ve o değeri hangi kodun yazdığı bulunamaz.
- **İkili veri.** Kapak görseli, taranmış belge gibi veriler ikili tiplerde saklanabilir.
  Ölçüt boyuttur: küçük ve satırla birlikte anlamlı olan ikili veri sütunda durabilir;
  büyük nesneler için dosya sisteminde ya da nesne deposunda tutup veritabanında yalnız
  adresini saklamak, yedek boyutunu ve satır okuma maliyetini düşürür. Bunun bedeli,
  iki saklama yeri arasındaki tutarlılığın artık uygulamanın sorumluluğunda olmasıdır.
- **Numaralandırma.** Ödünç işleminin durumu — açık, gecikmiş, kapanmış — sınırlı bir
  değer kümesidir. İki karşılık vardır: metin sütunu üzerinde `CHECK ... IN (...)` kısıtı,
  ya da değerleri satır olarak tutan ayrı bir bağıntıya yabancı anahtar. İkincisi yeni
  değer eklemeyi şema değişikliği olmaktan çıkarır ve değere ek bilgi — görünen ad, sıra
  numarası — iliştirmeye izin verir.

## Özet

- Sayılan büyüklükler tam sayı ya da ondalık tiple, ölçülen büyüklükler kayan noktalı
  tiple saklanır; para sayılır.
- Kayan noktalı toplamın ekrandaki gösterimi doğru görünse de eşitlik karşılaştırması
  yanlış sonuç verebilir.
- Tip bildiriminin ne kadar bağlayıcı olduğu motora göre değişir; alanın gerçek sınırı
  kısıtla yazıldığında her motorda geçerli olur.
- Metin eşitliği ve sıralaması harmanlamaya bağlıdır; büyük–küçük harf duyarsızlığı
  Türkçe harflerde kendiliğinden gelmez.
- Tarih için ayrı tip yoksa ISO 8601 metni kullanılır; sıralama doğru çalışır, aritmetik
  motora özgü işlev gerektirir.

## Sonraki Adım

İlişkisel Model konusu burada tamamlanıyor: bağıntı tanımlandı, anahtarlar seçildi,
kısıtlar yazıldı, boş değerin mantığı kuruldu ve sütunlara tip verildi. Geriye tek soru
kalıyor — sütunlar hangi bağıntıya konmalı? Kursun ilk dersindeki `odunc.csv` dosyasında
üye adı üç satırda tekrar ediyordu ve e-posta değişikliğinin üç yerde yapılması
gerekiyordu. Sıradaki konu, bu tekrarın nereden geldiğini gösteren kavramla başlar:
işlevsel bağımlılık.
