---
title: 'Veri Ambarı'
source: 'https://academia.sh/tr/kurslar/veri-depolama-mimarileri/veri-ambari'
course: 'Veri Depolama Mimarileri'
language: tr
updated: '2026-08-17T18:08:51+00:00'
license: 'CC BY-SA 4.0'
---

# Veri Ambarı

Hattan çıkan 2200 satırın bir depolama düzenine indirilip bir sorgunun o düzene dokunmak için ödediğinin sayılması: bölümlemesiz ve satırlı tabanda dönem süzgeçli sorgu 15400 hücre ve 15520 maliyet, yalnız seçilen sütunlar okunduğunda 4400 hücre ve 4520 maliyet, dönem bölümlemesinde 400 hücre ve 520 maliyet. Aynı düzen bölüm anahtarı dışındaki süzgeçte 4520 yerine 5720 veriyor, yani düzen bir sorguya kazandırırken ötekine kaybettiriyor. Yazma anında şema dayatması altı bozulma sınıfının ikisini yakalayıp 400 satırı reddediyor, ama reddedilen 400 satırın 400'ünde ölçüm bozulmamış duruyor; şema satırı atıyor, sayıyı değil. Dosya sabiti 120 bir seçimdir: dönem sorgusundaki 4000 hücrelik kazanç sabitten bağımsız, öteki sorgudaki 1200'lük kayıp ise tamamen sabitin eseri ve on dosyaya eşit.

Veri Mühendisliğine Giriş kursu on derste bir hattı kurdu ve saydı. Kurgu ölçüm ağının 2400 sayaç
okuması beş aşamadan geçti, tüketim aşamasının çıkışında 2200 satır kaldı, özet 55 hücreye ve sunum
5 değere indi; ardından altı bozulma sınıfının her birinin kaç aşama sonra yakalandığı ölçüldü. Bu
ölçülerin tamamı hattın **taşıdığı** satır üzerineydi. Hiçbiri şunu sormadı: o 2200 satır **nerede
duruyor**, hangi düzende yazılıyor ve o düzen bir sorguya ne ödetiyor.

Soru boş değildir: aynı 2200 satır birbirinden çok farklı biçimlerde diske indirilebilir ve seçilen
biçim bir sorgunun bedelini kat kat değiştirir. Bu ders o bedeli ölçülebilir kılar. Bir **depolama
düzeni (storage layout)** kurar, bir sorgunun o düzene dokunmak için ödediğini sayar ve ilk düzen
kararını, yani **şemanın yazma anında dayatılmasını**, hem kattığı hem ödettiği yandan yazar. Kursun
kuralı buradan çıkar ve on iki ders sürer: **bir depolama düzeninin sayısı sakladığı satır değil,
bir sorgunun ona dokunmak için ödediğidir; hangi sorgu için seçildiği yazılmayan düzen ölçülmemiş
sayılır.**

- **DY1.** Kod bir **kurgudur**; gerçek bir ambar ürünü, dosya biçimi, katalog ya da sorgu motoru
  çağrılmaz ve hiçbir ürün, satıcı ya da biçim adı yazılmaz. Yaklaşımlar **sınıf adlarıyla** anılır;
  SQL bir dildir ve serbesttir. Kaynak ile hat Veri Mühendisliğine Giriş kursundan devralınır, tohum
  **20260218**'dir.
- **DY2.** Kaynak **200 abone x 12 dönem = 2400 okuma**; hattan çıkan satır **2200**, çünkü her
  abonenin ilk döneminin tüketim farkı tanım gereği yoktur.
- **DY3.** Bir **düzen**, satırların hangi dosyaya düştüğüdür. `yaz` satırları **bölümleme
  anahtarına** göre dağıtır; anahtar boşsa tek dosya oluşur.
- **DY4.** Bir sorgunun bedeli üç sayıdır: **dokunulan dosya**, **okunan hücre** ve **maliyet =
  dosya x 120 + hücre**. Süzgeç bölüm anahtarındaysa dosya budanır, değilse bütün dosyalara
  dokunulur.
- **DY5. Dosya sabiti 120 bir seçimdir**; ona duyarlı her sonuç sabitin değeriyle yazılır.
- **DY6.** Taban çizgisi **bölümlemesiz, satırlı, tarihçesiz** düzendir; bu üç eksenin yalnız
  birincisi bu derste oynatılır.
- **DY7.** Altı bozulma sınıfı Veri Mühendisliğine Giriş kursundan **girdi** alınır, yeniden
  türetilmez: `gec_gelen`, `yinelenen`, `sema_degisti`, `birim_degisti`, `eksik_bolum`, `kayan_tip`.
  Hiçbiri saldırı değildir; hepsi üretici tarafı kazasıdır.
- **DY8.** Bölümleme, dizin ve sorgu planı yordamı **tekrarlanmaz**; Veri Modelleme ve İlişkisel
  Kuram ile Sorgu Eniyileme kurslarında ölçüldü. Eklenen tek şey **dosya düzeyindeki maliyettir**.
- **DY9.** Çözünürlük: 2200 satırda satır oranının adımı **0,0005**, en çok 110 dosyada dosya
  oranının adımı **0,0091**. **Maliyet oran değildir**; değerin kendisi yazılır.

## Düzen, Dosya ve Maliyet

**Veri ambarı (data warehouse)**, şemaya uyumlu ve yapılandırılmış veriyi saklayan depolama
sınıfıdır. Onu iki karar tanımlar. Birincisi **şemanın yazma anında dayatılmasıdır**: bir satır
ambara girebilmek için alanlarını ve türlerini önceden bildirilmiş şemaya uydurmak zorundadır.
İkincisi **düzenin önceden seçilmiş olmasıdır**: satırların hangi dosyaya düşeceğine yazma sırasında
karar verilir, okuma sırasında değil. İkinci karar ölçülebilir, çünkü bir sorgunun bedeli doğrudan
ondan çıkar. Aşağıdaki kod hattı kurar, çıkışını bir düzene indirir ve iki sorguyu üç düzende ölçer.
İkisi de aynı iki sütunu seçer; sorgu A'nın süzgeci `donem`, sorgu B'ninki `tip` alanındadır.

```python
# KURGU depolama duzeni -- gercek bir ambar urunu, dosya bicimi ya da sorgu
# motoru cagrilmaz. Kaynak bir olcum aginin KURGU sayac okumalaridir, tohum 20260218.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
DONEM = [f"2026-{a:02d}" for a in range(1, 13)]
ABONE = {}
for i in range(200):
    r = uretec(TOHUM + 37 * i)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "baslangic": 10000 + int(r() * 60000)}


def kaynak_uret():
    kayit = []
    for i, (ab, a) in enumerate(ABONE.items()):
        e = a["baslangic"]
        for d in DONEM:
            r = uretec(TOHUM + 101 * i + 7 * DONEM.index(d))
            e += 4 + int(r() * 46)
            kayit.append({"abone": ab, "donem": d, "bolge": a["bolge"], "tip": a["tip"],
                          "endeks": e, "birim": "m3"})
    return kayit


def a1_ayikla(kayit):
    ZOR = ("abone", "donem", "bolge", "endeks", "birim")
    tut = [k for k in kayit if all(a in k for a in ZOR)]
    return tut, len(kayit) - len(tut)


def a2_tekille(kayit):
    gor, tut = set(), []
    for k in kayit:
        ad = (k["abone"], k["donem"])
        if ad in gor:
            continue
        gor.add(ad)
        tut.append(k)
    return tut, len(kayit) - len(tut)


def a3_tuketim(kayit):
    """Donem farkindan tuketim. Onceki donem yoksa satir hesaplanamaz."""
    tablo = {(k["abone"], k["donem"]): k for k in kayit}
    cikti, dusen = [], 0
    for k in kayit:
        i = DONEM.index(k["donem"])
        if i == 0:
            continue
        onceki = tablo.get((k["abone"], DONEM[i - 1]))
        if onceki is None:
            dusen += 1
            continue
        try:
            f = int(k["endeks"]) - int(onceki["endeks"])
        except (TypeError, ValueError):
            dusen += 1
            continue
        cikti.append(dict(k, m3=f))
    return cikti, dusen


# ---- DEPOLAMA DUZENI: yaz , sorgu , maliyet
SUTUN = ("abone", "donem", "bolge", "tip", "endeks", "birim", "m3")
DOSYA_SABIT = 120          # her dosyaya dokunmanin sabit bedeli , hucre cinsinden


def satirlar():
    v, _ = a1_ayikla(kaynak_uret())
    v, _ = a2_tekille(v)
    v, _ = a3_tuketim(v)
    return v


def yaz(kayitlar, bolumleme=()):
    """Kayitlari bolumleme anahtarina gore dosyalara dagitir."""
    duzen = {}
    for k in kayitlar:
        anahtar = tuple(k[a] for a in bolumleme)
        duzen.setdefault(anahtar, []).append(k)
    return duzen


def sorgu(duzen, bolumleme, secilen, suzgec=None, sutunlu=True):
    """Suzgec: {alan: deger}. Bolumleme anahtarindaki alanlar dosya budar ,
    obur alanlar dosyanin tamamini okutur."""
    suzgec = {} if suzgec is None else suzgec
    budayan = {a: v for a, v in suzgec.items() if a in bolumleme}
    kalan = {a: v for a, v in suzgec.items() if a not in bolumleme}
    dosya, hucre, satir = 0, 0, 0
    okunan_sutun = len(secilen) if sutunlu else len(SUTUN)
    for anahtar, kayit in duzen.items():
        if budayan:
            eslesme = dict(zip(bolumleme, anahtar))
            if any(eslesme[a] != v for a, v in budayan.items()):
                continue
        dosya += 1
        hucre += len(kayit) * okunan_sutun
        satir += sum(1 for k in kayit if all(k[a] == v for a, v in kalan.items()))
    return {"dosya": dosya, "hucre": hucre, "eslesen_satir": satir,
            "maliyet": dosya * DOSYA_SABIT + hucre}


kayitlar = satirlar()
taban = yaz(kayitlar, ())
duzenli = yaz(kayitlar, ("donem",))
SEC, OLCUM = ("bolge", "m3"), {}
print("hattan cikan satir", len(kayitlar), " secilen sutun", len(SEC), "/", len(SUTUN))
print("duzen                  dosya  ort.satir  A.dosya  A.hucre  A.maliyet  B.maliyet")
for ad, d, b, st in [("bolumlemesiz/satirli", taban, (), False),
                     ("bolumlemesiz", taban, (), True),
                     ("donem", duzenli, ("donem",), True)]:
    a = sorgu(d, b, SEC, {"donem": "2026-07"}, sutunlu=st)
    v = sorgu(d, b, SEC, {"tip": "isyeri"}, sutunlu=st)
    OLCUM[ad] = (a, v)
    print(f"{ad:<22}{len(d):>6}{len(kayitlar) / len(d):>11.1f}"
          f"{a['dosya']:>9}{a['hucre']:>9}{a['maliyet']:>11}{v['maliyet']:>11}")
```

```
hattan cikan satir 2200  secilen sutun 2 / 7
duzen                  dosya  ort.satir  A.dosya  A.hucre  A.maliyet  B.maliyet
bolumlemesiz/satirli       1     2200.0        1    15400      15520      15520
bolumlemesiz               1     2200.0        1     4400       4520       4520
donem                     11      200.0        1      400        520       5720
```

Tablo kursun **üçlüsünü** kuruyor ve bundan sonraki her derste aynı üç sayı yan yana duracak.
**Düzensiz taban** ilk satırdır: tek dosya, satırlı okuma, sorgu A için 15400 hücre ve **15520
maliyet**. **Düzenli kurulum** son satırdır: `donem` anahtarına göre on bir dosya, sorgu A için 400
hücre ve **520 maliyet**. **Bedel** bu derste iki kalemdir: sorgu B'nin maliyeti ile birazdan
ölçülecek reddedilen satır.

Orta satır iki ekseni ayırır. Yalnız seçilen iki sütunun okunması hücreyi 15400'den 4400'e
indiriyor; bu bir **okuma biçimi** kazancıdır ve kursun ilerleyen bir dersinde ayrıca ölçülecek.
Bölümleme ayrı bir eksendir: 4400'den 400'e inişin tamamı **bölüm ayıklamasıdan (partition pruning)**
gelir. Süzgeç `donem` alanında ve düzen de `donem` anahtarıyla kurulu olduğu için sorgu on bir
dosyanın onunu hiç açmıyor.

Son sütun kursun **ikinci iddiasının** ilk görünümüdür: **düzen de bozar.** Aynı `donem` düzeni,
süzgeci `tip` alanında olan sorgu B için **5720** veriyor; bölümlemesiz taban aynı sorguyu **4520**
ile bitiriyor. Bölümleme burada hiçbir dosya budayamıyor, çünkü `tip` anahtarda değil; okunan hücre
iki düzende de 4400, ama on bir dosyanın her birine ayrı dokunuluyor. Bir düzen bir sorguya
kazandırırken bir başkasına kaybettirir ve iki sonuç aynı tabloda durur. Kursun kuralı tam olarak
bunu söyler: **hangi sorgu için seçildiği yazılmayan düzen ölçülmemiş sayılır.**

## Şema Dayatmanın Reddettiği Satır

Şema yazma anında dayatıldığında ambar bir **kapı** kazanır: uymayan satır depoya hiç girmez. Bu
kapının ne kattığı ve ne ödettiği, altı bozulma sınıfı kapıya sürüldüğünde görünür.

```python
# ---- KURGU bozulma siniflari. Hicbiri saldiri degildir; hepsi uretici tarafi kazasidir.
BOZULMA = ["gec_gelen", "yinelenen", "sema_degisti", "birim_degisti", "eksik_bolum", "kayan_tip"]


def boz(kayit, sinif, donem="2026-07"):
    """Tek bir donemi bozar , kalan donemler saglam kalir."""
    yeni, sayac = [], 0
    for k in kayit:
        if k["donem"] != donem:
            yeni.append(k)
            continue
        if sinif == "gec_gelen":
            if k["abone"] <= "A040":                # bu donemde 40 abone hic gelmedi
                sayac += 1
                continue
            yeni.append(k)
        elif sinif == "yinelenen":
            yeni.append(k)
            if k["abone"] <= "A060":                # 60 kayit iki kez geldi
                yeni.append(dict(k))
                sayac += 1
        elif sinif == "sema_degisti":
            y = dict(k)
            y["endeks_degeri"] = y.pop("endeks")    # alan adi degisti
            sayac += 1
            yeni.append(y)
        elif sinif == "birim_degisti":
            y = dict(k)
            y["endeks"] = k["endeks"] * 1000        # m3 yerine litre
            y["birim"] = "m3"                       # ETIKET DEGISMEDI , sessiz bozulma
            sayac += 1
            yeni.append(y)
        elif sinif == "eksik_bolum":
            if k["bolge"] == "kuzey":               # bir bolgenin bolumu hic yazilmadi
                sayac += 1
                continue
            yeni.append(k)
        elif sinif == "kayan_tip":
            y = dict(k)
            y["endeks"] = str(k["endeks"])          # sayi metne dondu
            sayac += 1
            yeni.append(y)
    return yeni, sayac


# ---- SEMA YAZMA ANINDA DAYATILIR: uymayan satir hic yazilmaz
SEMA = {"abone": str, "donem": str, "bolge": str, "tip": str, "endeks": int, "birim": str}


def sema_ihlali(k):
    for a, t in SEMA.items():
        if a not in k:
            return "eksik_alan"
        if not isinstance(k[a], t):
            return "yanlis_tip"
    return None


def yaz_semali(kayitlar):
    kabul, red = [], {}
    for k in kayitlar:
        n = sema_ihlali(k)
        if n:
            red[n] = red.get(n, 0) + 1
            continue
        kabul.append(k)
    return kabul, red


def olcum_kurtarilabilir(k):
    """Reddedilen satirin olcumu duruyor mu: adi degismis ya da metne donmus olabilir."""
    d = k.get("endeks", k.get("endeks_degeri"))
    try:
        int(d)
        return True
    except (TypeError, ValueError):
        return False


kaynak = kaynak_uret()
print(f"{'sinif':<15}{'gelen':>7}{'bozulan':>9}{'reddedilen':>12}  {'neden':<12}{'yazilan':>8}")
top_red, top_kurt, yakalanan = 0, 0, 0
for s in ["temiz"] + BOZULMA:
    gelen, n = (kaynak, 0) if s == "temiz" else boz(kaynak, s)
    kabul, red = yaz_semali(gelen)
    r = sum(red.values())
    neden = "-" if not red else "/".join(sorted(red))
    top_red += r
    top_kurt += sum(1 for k in gelen if sema_ihlali(k) and olcum_kurtarilabilir(k))
    yakalanan += 1 if r else 0
    print(f"{s:<15}{len(gelen):>7}{n:>9}{r:>12}  {neden:<12}{len(kabul):>8}")
print(f"reddedilen toplam {top_red}  olcumu duran {top_kurt}  "
      f"yakalanan sinif {yakalanan}/{len(BOZULMA)}")
```

```
sinif            gelen  bozulan  reddedilen  neden        yazilan
temiz             2400        0           0  -               2400
gec_gelen         2360       40           0  -               2360
yinelenen         2460       60           0  -               2460
sema_degisti      2400      200         200  eksik_alan      2200
birim_degisti     2400      200           0  -               2400
eksik_bolum       2354       46           0  -               2354
kayan_tip         2400      200         200  yanlis_tip      2200
reddedilen toplam 400  olcumu duran 400  yakalanan sinif 2/6
```

Kapının **kattığı** ilk satırda okunur: temiz kaynakta hiçbir satır reddedilmiyor, yani şema
dayatması sağlam veriyi engellemiyor. Bozuk kaynaklarda iki sınıf kapıya takılıyor. `sema_degisti`
alanın adını değiştirdiği için 200 satır **eksik alan**, `kayan_tip` sayıyı metne çevirdiği için 200
satır **yanlış tür** gerekçesiyle geri çevriliyor. Depoya giren her satırın alanları ve türleri
bilindiği için önceki bölümdeki sorgu istediği iki sütunu adıyla seçebiliyor ve 400 hücreyle
bitiriyor: **şema dayatmasının kattığı, sorgunun okuduğu hücreyi küçültme hakkıdır.**

**Ödettiği** iki kalemdir. Birincisi kapsam: altı sınıfın **dördü** kapıdan etkilenmeden geçiyor.
`gec_gelen` ile `eksik_bolum` satır **eksiltiyor**, ortada uymayan bir satır yok; şema gelmeyeni
göremez. `yinelenen` şemaya uygun satırı ikinci kez yazıyor, çünkü şema alan ve tür sorar, tekillik
sormaz. `birim_degisti` en tehlikelisidir: değeri bin katına çıkarıp birim etiketini `m3` bırakıyor,
yani **şemaya kusursuz uyuyor**.

İkinci kalem kursun ikinci iddiasının buradaki karşılığıdır: **düzen de bozar.** Reddedilen 400
satırın **400'ünde ölçüm bozulmadan duruyor** — `sema_degisti` satırında `endeks_degeri` adıyla,
`kayan_tip` satırında metin olarak, ama ikisinde de tamsayıya çevrilebilir hâlde. Şema kapısı
**satırı** atıyor, **sayıyı** değil. Bir düzen kararı burada veri kalitesini yükseltmiyor,
kurtarılabilir veriyi **yok ediyor** ve bunu sessizce yapıyor, çünkü reddedilen satır sayısı ayrıca
yazılmadıkça hiçbir sorguda görünmez.

## Dosya Sabiti Bir Seçimdir

Maliyet formülündeki 120 sayısı ölçülmüş bir büyüklük değil, **modelin bir seçimidir**: her dosyaya
dokunmanın hücre cinsinden bedelini temsil eder. Seçim olduğu için ondan çıkan her sonucun sabite ne
kadar duyarlı olduğu ayrıca yazılmalıdır.

```python
def maliyet(r, sabit):
    return r["dosya"] * sabit + r["hucre"]


(A_t, B_t), (A_d, B_d) = OLCUM["bolumlemesiz"], OLCUM["donem"]
print(" sabit  A.taban  A.duzenli  A.kazanc  B.taban  B.duzenli  B.kazanc")
for s in (0, 120):
    print(f"{s:>6}{maliyet(A_t, s):>9}{maliyet(A_d, s):>11}{maliyet(A_t, s) - maliyet(A_d, s):>10}"
          f"{maliyet(B_t, s):>9}{maliyet(B_d, s):>11}{maliyet(B_t, s) - maliyet(B_d, s):>10}")
print("dokunulan dosya farki  A", A_d["dosya"] - A_t["dosya"], " B", B_d["dosya"] - B_t["dosya"])
```

```
 sabit  A.taban  A.duzenli  A.kazanc  B.taban  B.duzenli  B.kazanc
     0     4400        400      4000     4400       4400         0
   120     4520        520      4000     4520       5720     -1200
dokunulan dosya farki  A 0  B 10
```

İki satır sonucu kesin biçimde ayırıyor. Bölümlemenin sorgu A'ya **kazandırdığı 4000 hücre sabitten
bağımsızdır**: sabit sıfır da olsa yüz yirmi de olsa kazanç aynı kalır, çünkü iki düzen de tek
dosyaya dokunuyor ve fark tamamen okunan hücreden geliyor. Sorgu B'deki **1200 birimlik kayıp ise
tamamen sabitin eseridir**: sabit sıfırken kayıp yoktur, yüz yirmiyken kayıp on dosya çarpı yüz
yirmidir. Bu dersin "düzen de bozar" bulgusu sabitin **pozitif** olmasına bağlıdır ve büyüklüğü
sabitle doğru orantılıdır. Sabitin birden çok değerle süpürülmesi ve hangi sonuçların sıra
değiştirdiği kursun ilerleyen bir dersinde ölçülür.

Tablodaki hiçbir sayı koşuma bağlı değildir. Hat belirlenimcidir, `random` kullanılmaz ve her hücre
koşum yapılmadan türetilebilir: hattan çıkan satır 200 abone x 11 dönem = **2200**; `donem`
düzenindeki dosya sayısı tüketim hesaplanabilen dönem kadar, **11**; dosya başına ortalama 2200 / 11
= **200** satır; iki sütun seçili bölümlemesiz okuma 2200 x 2 = **4400** hücre; budayan sorguda
200 x 2 = **400** hücre. Türetilebilirlik ölçünün yeterliliği için gereklidir: sonraki derslerde iki
düzen arasında görülen her fark düzen kararından gelir, koşum oynaklığından değil.

## Özet

- Bir depolama düzeni satırların hangi dosyaya düştüğüdür; bedeli üç sayıdır: dokunulan dosya,
  okunan hücre ve maliyet = dosya x 120 + hücre. Dosya sabiti 120 bir seçimdir.
- Aynı sorgu bölümlemesiz ve satırlı tabanda 15400 hücre ile 15520 maliyet, yalnız seçilen sütunlar
  okunduğunda 4400 hücre ile 4520 maliyet, `donem` bölümlemesinde 400 hücre ile 520 maliyet veriyor.
- Aynı `donem` düzeni, süzgeci anahtarın dışında olan sorgu B için 4520 yerine 5720 veriyor: düzen
  bir sorguya kazandırırken bir başkasına kaybettirir ve bu kayıp tamamen dosya sabitinden gelir.
- Yazma anında şema dayatması altı bozulma sınıfının ikisini yakalayıp 400 satırı reddediyor;
  `gec_gelen`, `yinelenen`, `eksik_bolum` ve `birim_degisti` kapıdan etkilenmeden geçiyor.
- Reddedilen 400 satırın 400'ünde ölçüm bozulmadan duruyor: şema kapısı satırı atıyor, sayıyı değil.
- Kursun kuralı: bir düzenin sayısı sakladığı satır değil bir sorgunun ona dokunmak için ödediğidir;
  hangi sorgu için seçildiği yazılmayan düzen ölçülmemiş sayılır.

## Sonraki Adım

Bu dersin ambarı kapıyı sıkı tuttu ve karşılığında sorguya ucuz bir okuma verdi. Kapının bedeli de
ölçüldü: dört bozulma sınıfı zaten geçiyor, geri çevrilen 400 satırın ölçümü ise kurtarılabilir
olduğu hâlde depoya hiç girmiyor. Buradan doğal bir soru çıkar: kapı hiç kurulmasaydı ne olurdu.
Gelen her satır olduğu gibi, hiçbir şema dayatılmadan yazılsaydı yazma tarafı ne kazanır, okuma
tarafı ne öderdi. Sonraki ders bu yaklaşımı, yani **veri gölünü** ölçer; ölçüsü iki sayının
karşıtlığıdır: aynı sorgu ham düzende kaç hücre okutuyor, şemaya uyumlu düzende kaç. Tablonun ikinci
yarısı daha rahatsız edici olacak, çünkü kapı kaldırıldığında hangi bozulma sınıfının yazma anında
**hiç** yakalanamadığı da sayılacak.
