İçeriğe geç
academia.sh

Ders 06 / 14

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ı.

İçindekiler

Ö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:

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:

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:

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:

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:

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.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat