---
title: 'Alma Türleri'
source: 'https://academia.sh/tr/kurslar/veri-hatlari/alma-turleri'
course: 'Veri Hatları ve Orkestrasyon'
language: tr
updated: '2026-08-17T18:08:49+00:00'
license: 'CC BY-SA 4.0'
---

# Alma Türleri

Üç alma yönteminin taşıdığı satır ile kaçırdığı değişikliğin yan yana sayılması: dönem başına dört görevden kurulu çizge 48 düğüm ve 47 kenar taşıyor, tam yükleme on iki koşumda 15.560 satır taşıyıp hiçbir değişikliği kaçırmıyor, artımlı yükleme 2.360 satır taşıyıp 148 değişikliği kaçırıyor, değişiklik yakalama 2.508 satır taşıyıp hiçbirini kaçırmıyor. Artımlı yüklemenin kaçırdığı 40 geç gelen satır ile 108 düzeltilmemiş satır sunumu her bölgede aşağı çekiyor, ama satır sayısı denetimi 0,0167 oranıyla sessiz kalıyor ve bozulmayı ancak dağılım denetimi 0,3469 ile aşama 4'te yakalıyor.

Önceki kurs on iki derste verinin **nerede** ve **hangi düzende** durduğunu ölçtü: bölümleme,
dosya düzeni, sıkıştırma ve okunan hücre yan yana sayıldı. O düzeni **kimin, ne zaman ve hangi
sırayla doldurduğu** hiç sorulmadı. Bir hat kendiliğinden dolmaz; her dönem birileri onu
tetikler, adımlar bir sırayla koşar ve o sıradan biri düştüğünde geri kalanın ne yapacağı
önceden yazılmış olmalıdır.

Bu kurs hattı **koşum** üzerinden ölçer ve kuralı şudur: bir hattın sayısı bir kez doğru koşması
değil, **yeniden koşturulduğunda aynı sonucu vermesidir**; yeniden koşturulamayan hat
**ölçülmemiş** sayılır. Her derste üç sayı yan yana durur: orkestrasyonsuz taban, orkestrasyonlu
kurulum ve bedel. Bu ders üçlüyü ve hattın görev çizgesini kurar, sonra ilk soruyu sorar:
kaynaktan veri **hangi yöntemle** alınıyor ve o yöntem neyi **kaçırıyor**.

- **VA1.** Kod **kurgudur**; gerçek bir depo, motor, mesaj sistemi ya da orkestratör çağrılmaz.
  Kaynak bir ölçüm ağının kurgu sayaç okumalarıdır: 200 abone, 12 dönem, 2400 satır, tohum
  20260218.
- **VA2.** Hat belirlenimcidir; rastgelelik kitaplığı kullanılmaz ve bütün sayılar koşumdan
  bağımsızdır.
- **VA3.** Taban çizgisi **orkestrasyonsuz koşumdur**: tek elle tetikleme, yeniden deneme yok,
  atomik yazım yok, geri doldurma yok.
- **VA4.** Görev çizgesi dönem başına dört **görev** (task) taşır: `al`, `ayikla`, `tuketim`,
  `ozet`. `tuketim` bir önceki dönemin `ayikla` görevine de bağlıdır.
- **VA5.** Geç gelen satır K01'in `gec_gelen` bozulmasıdır: 2026-07 döneminin 40 satırı o dönemin
  koşumunda yoktur, bir sonraki koşumdan önce gelir. Saldırı değil, üretici tarafı kazasıdır.
- **VA6.** Ana veri düzeltmesi 12 abonenin bölgesini onuncu koşumdan önce düzeltir ve düzeltme o
  abonelerin **bütün dönemlerine** uygulanır.
- **VA7.** Hedef anahtarlıdır: `(abone, donem)` çifti bir satırı tekler, aynı anahtar yeniden
  yazıldığında üzerine yazılır. Yazım bu yüzden **yinelemeye dayanıklıdır** (idempotent).
- **VA8.** Taşınan satır, `al` görevinin on iki koşum boyunca hatta geçirdiği satır sayısının
  toplamıdır. Satır oranının adımı 1/2400, yani 0,0004; sunum üzerinde oran basılmaz.

## Hattın Görev Çizgesi

Bir hat, birbirine bağlı görevlerden kurulu bir **yönlü çevrimsiz çizgedir** (directed acyclic
graph). Çizge kavramı ve topolojik sıralama Veri Yapıları kursundaki Çizgeler konusunda
ölçüldü; burada algoritma tekrarlanmaz, çizge **kurulur ve kullanılır**. Dönem başına
dört görev vardır ve tek gerçek incelik şudur: tüketim bir **fark** hesabıdır, bu yüzden
`tuketim` görevi kendi döneminin `ayikla` görevine olduğu kadar **bir önceki dönemin** `ayikla`
görevine de bağlıdır. Zincirin dönemler arasına uzanması, ilerideki derslerde bir görev
düştüğünde neden bütün bir kuyruğun beklediğini açıklar.

```python
# KURGUDUR. Gercek bir depo, motor ya da orkestrator cagrilmaz; olcum aginin
# sayac okumalari kurgudur, 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():                                  # her donem her abone icin bir okuma
    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


# ---- HAT: bes asama, her asama kendi dusurdugu satiri sayar.
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):
    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


def a4_ozet(kayit):
    top = {}
    for k in kayit:
        ad = (k["bolge"], k["donem"])
        top[ad] = top.get(ad, 0) + k["m3"]
    return top, 0


def a5_sun(ozet):                                   # bolge basina donem ortalamasi
    bolge = {}
    for (b, d), v in ozet.items():
        bolge.setdefault(b, []).append(v)
    return {b: round(sum(v) / len(v), 2) for b, v in bolge.items()}, 0


def okuma_sonucu(kayitlar):
    v, _ = a1_ayikla(kayitlar)
    v, _ = a2_tekille(v)
    v, _ = a3_tuketim(v)
    oz, _ = a4_ozet(v)
    sun, _ = a5_sun(oz)
    return sun, len(v), oz


# ---- KURGU gorev cizgesi: donem basina dort gorev.
GOREV = ("al", "ayikla", "tuketim", "ozet")
BAGIMLILIK = {"al": (), "ayikla": ("al",), "tuketim": ("ayikla",), "ozet": ("tuketim",)}


def cizge():
    """`tuketim` bir onceki donemin `ayikla`sina da baglidir."""
    dugum, kenar = [], []
    for d in DONEM:
        for g in GOREV:
            dugum.append((g, d))
            for o in BAGIMLILIK[g]:
                kenar.append(((o, d), (g, d)))
        i = DONEM.index(d)
        if i > 0:
            kenar.append((("ayikla", DONEM[i - 1]), ("tuketim", d)))
    return dugum, kenar


def sirala(dugum, kenar):
    gelen = {u: 0 for u in dugum}
    ardil = {u: [] for u in dugum}
    for a, b in kenar:
        gelen[b] += 1
        ardil[a].append(b)
    hazir = [u for u in dugum if gelen[u] == 0]
    sira = []
    while hazir:
        u = hazir.pop(0)
        sira.append(u)
        for v in ardil[u]:
            gelen[v] -= 1
            if gelen[v] == 0:
                hazir.append(v)
    return sira


dugum, kenar = cizge()
sira = sirala(dugum, kenar)
ham = kaynak_uret()
sun, n, _ = okuma_sonucu(ham)
print("cizge", len(dugum), "dugum", len(kenar), "kenar , sira", len(sira), "gorev")
print("ilk uc gorev", sira[:3])
print("kaynak", len(ham), "satir , tuketim", n, "satir")
print("saglam sunum", sun)
```

```
cizge 48 dugum 47 kenar , sira 48 gorev
ilk uc gorev [('al', '2026-01'), ('al', '2026-02'), ('al', '2026-03')]
kaynak 2400 satir , tuketim 2200 satir
saglam sunum {'merkez': 1321.45, 'kuzey': 1212.55, 'dogu': 881.36, 'bati': 833.09, 'guney': 1065.55}
```

Kırk sekiz düğüm, kırk yedi kenar ve tam sıralanabilen bir çizge. Kenar sayısının düğümden bir
eksik olması çizgenin **tek parça bir orman** olduğunu söyler: on iki dönemin `al` görevleri
dışında her düğümün tam bir öncülü vardır. Bu derste ölçülen şey çizgenin şekli değil, en baştaki
düğümün ne yaptığıdır — **`al` görevi kaynaktan neyi istiyor**.

## Üç Alma Yöntemi

**Tam yükleme** (full load) her koşumda kaynağın o anki tamamını okur ve hedefi baştan yazar.
**Artımlı yükleme** (incremental load) yalnız son alınan dönemden sonraki dönemleri ister; sınır
bir dönem numarasıdır ve her koşumda ilerler. **Değişiklik yakalama** (change data capture)
kaynağın kendi değişiklik akışını okur: ekleme ve güncelleme olaylarını taşır, dokunulmayan
satırı hiç taşımaz.

Aşağıdaki blok kaynağın zaman içindeki hâlini modelliyor ve üç yöntemi aynı on iki koşumda
çalıştırıyor. Kaynağa iki üretici tarafı olayı düşüyor: 2026-07'nin kırk satırı geç geliyor, ve on
ikinci abonenin bölgesi onuncu koşumdan önce düzeltiliyor.

```python
# ---- KURGU kaynak sistemin zaman icindeki hali. Iki uretici tarafi olayi:
#  1) K01'in `gec_gelen` bozulmasi: 2026-07'nin 40 satiri o donemin kosumunda
#     yok, bir sonraki kosumdan once geliyor.
#  2) Ana veri duzeltmesi: 12 abonenin bolgesi yanlis girilmis, 10. kosumdan
#     once butun donemleri icin duzeltiliyor.
GEC = [f"A{i:03d}" for i in range(1, 41)]
YANLIS = [f"A{i:03d}" for i in range(101, 113)]


def kaynak_anlik(kosum):
    """Kaynagin `kosum` numarali kosum aninda gorunen hali."""
    kayit = []
    for k in kaynak_uret():
        i = DONEM.index(k["donem"]) + 1
        if i > kosum or (i == 7 == kosum and k["abone"] in GEC):
            continue
        y = dict(k)
        if k["abone"] in YANLIS and kosum < 10:
            y["bolge"] = BOLGE[(BOLGE.index(k["bolge"]) + 1) % 5]
        kayit.append(y)
    return kayit


def tam_yukleme():
    """Her kosumda kaynagin tamami yeniden okunur , hedef silinip yazilir."""
    hedef, tasinan = {}, 0
    for kosum in range(1, 13):
        anlik = kaynak_anlik(kosum)
        tasinan += len(anlik)
        hedef = {(k["abone"], k["donem"]): k for k in anlik}
    return list(hedef.values()), tasinan


def artimli_yukleme():
    """Yalniz son alinan donemden sonraki donemler okunur."""
    hedef, tasinan, sinir = {}, 0, 0
    for kosum in range(1, 13):
        yeni = [k for k in kaynak_anlik(kosum) if DONEM.index(k["donem"]) + 1 > sinir]
        tasinan += len(yeni)
        for k in yeni:
            hedef[(k["abone"], k["donem"])] = k
        sinir = kosum
    return list(hedef.values()), tasinan


def degisiklik_yakalama():
    """Kaynagin degisiklik akisi okunur , ekleme ve guncelleme olaylari tasinir."""
    hedef, tasinan, onceki = {}, 0, {}
    for kosum in range(1, 13):
        anlik = {(k["abone"], k["donem"]): k for k in kaynak_anlik(kosum)}
        olay = [k for ad, k in anlik.items() if onceki.get(ad) != k]
        tasinan += len(olay)
        for k in olay:
            hedef[(k["abone"], k["donem"])] = k
        onceki = anlik
    return list(hedef.values()), tasinan


gercek = {(k["abone"], k["donem"]): k for k in ham}
dogru_sun, _, dogru_oz = okuma_sonucu(ham)
print("yontem      tasinan  hedef  eksik  yanlis  tuketim  satir orani  dagilim eni")
for ad, f in (("tam", tam_yukleme), ("artimli", artimli_yukleme),
              ("degisiklik", degisiklik_yakalama)):
    hed, tasinan = f()
    hd = {(k["abone"], k["donem"]): k for k in hed}
    eksik = len(set(gercek) - set(hd))
    yanlis = sum(1 for a in hd if gercek[a] != hd[a])
    s, t, oz = okuma_sonucu(hed)
    en = max(abs(v - dogru_oz[a]) / max(abs(dogru_oz[a]), 1) for a, v in oz.items())
    print(f"{ad:<11} {tasinan:>7} {len(hd):>6} {eksik:>6} {yanlis:>7} {t:>8} "
          f"{abs(len(hd) - 2400) / 2400:>12.4f} {en:>12.4f}")
print()
for ad, f in (("tam", tam_yukleme), ("artimli", artimli_yukleme),
              ("degisiklik", degisiklik_yakalama)):
    s, _, _ = okuma_sonucu(f()[0])
    print(f"{ad:<11}", {b: round(s.get(b, 0) - dogru_sun[b], 2) for b in dogru_sun})
```

```
yontem      tasinan  hedef  eksik  yanlis  tuketim  satir orani  dagilim eni
tam           15560   2400      0       0     2200       0.0000       0.0000
artimli        2360   2360     40     108     2120       0.0167       0.3469
degisiklik     2508   2400      0       0     2200       0.0000       0.0000

tam         {'merkez': 0.0, 'kuzey': 0.0, 'dogu': 0.0, 'bati': 0.0, 'guney': 0.0}
artimli     {'merkez': -11.18, 'kuzey': -28.1, 'dogu': -39.09, 'bati': -36.91, 'guney': -70.0}
degisiklik  {'merkez': 0.0, 'kuzey': 0.0, 'dogu': 0.0, 'bati': 0.0, 'guney': 0.0}
```

## Taşınan Satır ile Kaçırılan Değişiklik

Tablonun ilk sütunu tam yüklemenin bedelini yazıyor: on iki koşumda **15.560 satır** taşınmış,
oysa sonuçta hedefte duran satır **2400**. Aynı veriyi altı buçuk kez taşımanın karşılığı, hiçbir
değişikliği kaçırmamasıdır. Geç gelen kırk satır sekizinci koşumda kendiliğinden yerine oturur,
bölge düzeltmesi onuncu koşumda bütün dönemlere yayılır, çünkü her koşum kaynağı yeniden okur.
Tam yüklemenin bir kusuru yoktur; yalnız pahalıdır ve **kaynak büyüdükçe pahalılığı doğrusal
büyür**.

Artımlı yükleme en az satırı taşıyor: **2360**. Bedeli aynı satırda duruyor. Yedinci koşum
dönemin yalnız 160 satırını görüyor; kırk satır sonra geliyor ama sınır artık yedidedir ve o
satırlar bir daha hiç istenmez. Bölge düzeltmesi de aynı nedenle yalnız onuncu koşumdan sonraki
dönemlere iniyor: hedefte on iki abonenin dokuz dönemi, yani **108 satır**, eski bölgesiyle
kalıyor. Toplam **148 kaçırılan değişiklik**, ve bunların 40'ı eksik satır, 108'i yanlış satırdır.
Artımlı yükleme neyi kaçırdığını **bilmez** — sınırın gerisinde bir şeyin değiştiğini görecek bir
düzeneği yoktur.

Değişiklik yakalama iki olayı da görüyor ve bunun için taşıdığı satır **2508**. Artımlı
yüklemeden yalnız **148 satır** fazla, tam yüklemeden **13.052 satır** az. Fark tam olarak
kaçırılan değişiklik sayısı kadardır ve bu tesadüf değildir: değişiklik yakalamanın taşıdığı şey
**değişikliğin kendisidir**. Bedeli satırda değil kaynaktadır; kaynağın değişiklik akışını
yayımlıyor olması gerekir, ve bu yayımı yapmayan bir kaynakta yöntem hiç kurulamaz.

## Kaçırılan Değişikliği Hangi Denetim Görüyor

Artımlı yüklemenin hedefi sunumu her bölgede aşağı çekiyor: en küçük sapma merkezde **−11,18**, en
büyüğü güneyde **−70,00**. Bu sapmayı görecek biri var mıdır? Veri Mühendisliğine Giriş kursunda
kurulan denetim kümesi bu soruya iki farklı cevap veriyor. Satır sayısı denetiminin oranı
**0,0167**; öntanımlı tolerans
0,05 olduğu için denetim **yeşil kalıyor**. Şema, tür ve tekillik denetimleri de yeşildir, çünkü
eksik satırların şeması bozuk değil, sadece yokturlar. Bölge kümesi de tamdır: on iki abonenin
bölgesi yanlış ama yanlış olan bölge de listede vardır.

Yakalayan tek denetim **dağılım denetimidir** ve özet katmanında en büyük hücre sapması **0,3469**
ile 0,25 eşiğini aşar. Bu denetim aşama 4'te koşar; yani bozulma alma, ayıklama, tekilleştirme ve
tüketim hesabından geçtikten sonra görünür. Yakalama gecikmesi **4 aşamadır** ve o ana kadar 2120
satırlık ara tablo çoktan yazılmıştır. Yöntem seçimi burada bir ölçü seçimine dönüşür: artımlı
yükleme taşınan satırı 6,6 kat düşürür, karşılığında 148 değişikliği kaçırır ve bu kaçağı yalnız
en pahalı denetim, en geç aşamada bildirir.

## Özet

- Hat, dönem başına dört görevden kurulu bir yönlü çevrimsiz çizgedir: 48 düğüm, 47 kenar ve tam
  sıralanabilen bir koşum sırası. `tuketim` bir önceki dönemin `ayikla` görevine bağlıdır, bu
  yüzden zincir dönemler arasına uzanır.
- Tam yükleme hiçbir değişikliği kaçırmaz ve bedelini taşınan satırla öder: 2400 satırlık bir
  hedef için on iki koşumda 15.560 satır taşınır.
- Artımlı yükleme en az satırı taşır (2360) ama sınırın gerisinde olan biteni göremez: 40 geç
  gelen satır ile 108 düzeltilmemiş satır, toplam 148 değişiklik kaçar.
- Değişiklik yakalama iki olayı da görür ve artımlı yüklemeden yalnız kaçırılan değişiklik sayısı
  kadar, 148 satır fazla taşır; koşulu, kaynağın değişiklik akışını yayımlıyor olmasıdır.
- Kaçırılan değişikliği satır sayısı denetimi 0,0167 oranıyla görmez; yalnız dağılım denetimi
  0,3469 ile ve aşama 4 gecikmeyle bildirir.

## Sonraki Adım

Bu derste `al` görevi kaynağı **tek bir hamlede** okudu: `kaynak_anlik` çağrıldı ve satırlar
elde oldu. Kaynak sistemler böyle okunmaz. Bir uçnokta veriyi sayfa sayfa verir, pencere başına
kaç çağrı yapılabileceğini sınırlar ve çağrılardan bir kısmı geçici olarak düşer. Sonraki ders
aynı `al` görevini bu kısıtların altına sokar ve iki şeyi sayar: **kısıt altında tamamlanan çağrı
ve alınan satır**. Ölçülecek takas şudur: sayfa boyunu büyütmek çağrı sayısını düşürür, ama düşen
tek bir çağrının kaçırdığı satır aynı oranda büyür.
