---
title: 'Depo Türleri'
source: 'https://academia.sh/tr/kurslar/veri-olcekleme/depo-turleri'
course: 'Veri Katmanı Ölçekleme'
language: tr
updated: '2026-08-17T18:11:02+00:00'
license: 'CC BY-SA 4.0'
---

# Depo Türleri

Anahtar–değer, belge, geniş sütun ve çizge deposunun aynı erişim örüntüleriyle ölçülmesi: her türün bir örüntü için gerektirdiği sorgu sayısı ile dokunduğu kayıt sayısı, bir örüntüyü ucuzlatan yapının hangi örüntüyü pahalılaştırdığı ve seçimin giriş kursundaki depo istek hızı ile yazma/okuma oranına ödettiği bedel.

Buraya kadarki bütün kararlar satırları ve sütunları olan tek bir depo biçimi üzerinde verildi.
Oysa ölçülen örüntülerin istediği şeyler birbirinden çok farklıdır: takip sorgusu tek anahtarla
tek kayıt ister, durum olayı sürekli ekleme yapar, dönem taraması geniş bir aralıkta toplam alır.
Bir depo türü bu işlerden birini yapısına yazdığında ötekileri uygulamaya bırakır ve bu ders o
alışverişi sayar.

Ailelerin tanımı — anahtar–değer, belge, geniş sütun ve çizge deposunun neyi bırakıp neyi verdiği
— Veri Modelleme ve İlişkisel Kuram kursunda kuruldu; ilişkisel ile ilişkisel olmayan seçimi ve
kayıt sisteminin tek kalması kuralı bu konunun ilk dersinde ölçüldü. İkisi de tekrarlanmaz.
Buradaki soru dardır: **her tür, her örüntü için kaç sorgu ister ve kaç kayda dokunur.**

## Türleri Ayıran Şey

Bir depo türünü, yerel olarak yanıtlayabildiği erişim biçimi tanımlar. Yanıtlayamadığı her biçim
uygulamaya düşer ve uygulamaya düşen her adım ayrı bir depo isteğidir.

**Anahtar–değer deposu** yalnız birincil anahtarı bilir. Değerin içi kendisi için anlamsızdır,
bu yüzden ikincil erişim uygulamanın tuttuğu bir anahtar listesiyle yapılır ve listedeki her
kayıt ayrı bir istek olur.

**Belge deposu** değerin alanlarını görür ve bir alan üzerinde ikincil dizin kurabilir. İkincil
bir süzme tek istekte biter.

**Geniş sütun deposu** satırları bölüm anahtarına göre gruplar ve grup içinde sıralı bir aralığı
tek istekte okur. Farklı bir anahtarla süzme, aynı verinin ikinci bir bölüm anahtarıyla ikinci
kez yazılmasını gerektirir.

**Çizge deposu** düğüm ve kenarları birinci sınıf nesne yapar; bir dolaşma depo içinde yürür ve
istemciye tek istek olarak görünür.

Ölçüm için üç örüntünün yanına dördüncüsü konur, çünkü ilk üçünün hiçbiri çizge deposunun
kazandığı yerde durmaz. **P4 — rota dolaşması:** bir aktarma merkezi durduğunda o merkezden geçen
gönderilerin bulunması, sonraki duraklarının çıkarılması ve o duraklardan geçen gönderilere kadar
üç adım ilerlenmesi. Teslimat operasyonunun sorduğu bir sorudur ve bir kaydın kendisiyle değil
kayıtlar arasındaki bağla ilgilidir.

```js
// tur/erisim.mjs — ayni erisim oruntulerinin dort depo turunde gerektirdigi sorgu ve
// dokundugu kayit. MODEL: depolar birer nesnedir, sayaclar aciktir; bir urun degil,
// erisim yeteneklerinin modelidir. Sonuclar belirlenimlidir.
const GONDERI = 60_000, SATICI = 20, MERKEZ = 8;   // 01. dersin olcegi: satici basina 3000
const gonderi = Array.from({ length: GONDERI }, (_, i) => ({
  no: `TR-${i}`, satici: i % SATICI,
  rota: [0, 1, 2].map((j) => (i * 3 + j) % MERKEZ),
}));
const saticiDizin = new Map(), merkezDizin = new Map(), rotaSonraki = new Map();
for (const g of gonderi) {
  if (!saticiDizin.has(g.satici)) saticiDizin.set(g.satici, []);
  saticiDizin.get(g.satici).push(g);
  for (let j = 0; j < g.rota.length; j += 1) {
    const m = g.rota[j];
    if (!merkezDizin.has(m)) merkezDizin.set(m, []);
    merkezDizin.get(m).push(g);
    if (j + 1 < g.rota.length) {
      if (!rotaSonraki.has(m)) rotaSonraki.set(m, new Set());
      rotaSonraki.get(m).add(g.rota[j + 1]);
    }
  }
}

class Depo {                       // her cagri bir depo istegidir; dokunulan kayit sayilir
  constructor() { this.sorgu = 0; this.kayit = 0; }
  iste(n) { this.sorgu += 1; this.kayit += n; return n; }
}

// P1: takip numarasina gore tekil okuma (durum + son uc rota adimi)
// P2: tasiyicidan gelen bir durum olayinin yazilmasi
// P3: bir saticinin donem taramasi
// P4: bir merkezden baslayip H adim ilerleyen rota dolasmasi
const H = 3;   // dolasma derinligi
const ORUNTU = {
  "anahtar-deger": {                        // yalniz birincil anahtar; ikincil dizin uygulamada
    P1: (d) => d.iste(1),                                   // deger butun halinde gelir
    P2: (d) => { d.iste(1); d.iste(1); },                   // oku, sonra butun degeri yaz
    P3: (d) => { const n = saticiDizin.get(3).length; d.iste(1);   // once dizin anahtari
      for (let i = 0; i < n; i += 1) d.iste(1); },                     // sonra kayit basina bir istek
    P4: (d, derinlik) => { let m = new Set([0]);
      for (let h = 0; h < derinlik; h += 1) { const s = new Set();
        for (const x of m) { for (const g of merkezDizin.get(x)) d.iste(1);
          for (const y of rotaSonraki.get(x) ?? []) s.add(y); d.iste(1); }
        m = s; } },
  },
  "belge": {                                // belge alanlari uzerinde ikincil dizin
    P1: (d) => d.iste(1),
    P2: (d) => d.iste(1),                                   // belgenin olay dizisine ekleme
    P3: (d) => d.iste(saticiDizin.get(3).length),
    P4: (d, derinlik) => { let m = new Set([0]);
      for (let h = 0; h < derinlik; h += 1) { const s = new Set(); let k = 0;
        for (const x of m) { k += merkezDizin.get(x).length;
          for (const y of rotaSonraki.get(x) ?? []) s.add(y); }
        d.iste(k); m = s; } },
  },
  "genis sutun": {                          // bolum anahtari + bolum icinde sirali aralik
    P1: (d) => d.iste(3),                                   // son uc olay satiri
    P2: (d) => { d.iste(1); d.iste(1); },                   // olay tablosu + satici tablosu
    P3: (d) => d.iste(saticiDizin.get(3).length),
    P4: (d, derinlik) => { let m = new Set([0]);
      for (let h = 0; h < derinlik; h += 1) { const s = new Set(); let k = 0;
        for (const x of m) { k += merkezDizin.get(x).length;
          for (const y of rotaSonraki.get(x) ?? []) s.add(y); }
        d.iste(k); m = s; } },
  },
  "cizge": {                                // dugum ve kenarlar; dolasma depo icinde yurur
    P1: (d) => d.iste(1 + 3),                               // gonderi dugumu + son uc kenar
    P2: (d) => d.iste(2),                                   // olay dugumu + kenar
    P3: (d) => d.iste(1 + 2 * saticiDizin.get(3).length),   // satici dugumu, kenar, gonderi
    P4: (d, derinlik) => { let m = new Set([0]), k = 0;
      for (let h = 0; h < derinlik; h += 1) { const s = new Set();
        for (const x of m) { k += 1 + merkezDizin.get(x).length;
          for (const y of rotaSonraki.get(x) ?? []) s.add(y); }
        m = s; }
      d.iste(k); },
  },
};

console.log(`model: ${GONDERI} gonderi, ${SATICI} satici, ${MERKEZ} merkez, ` +
  `rota 3 adim, dolasma ${H} adim; sayilar sorgu/kayit`);
const ad = ["P1 tekil okuma", "P2 olay yazma", "P3 donem taramasi", "P4 rota dolasmasi"];
console.log(`\n${"depo turu".padEnd(16)}${ad.map((a) => a.padStart(19)).join("")}`);
for (const [tur, o] of Object.entries(ORUNTU)) {
  const hucre = ["P1", "P2", "P3", "P4"].map((p) => {
    const d = new Depo(); o[p](d, H);
    return `${d.sorgu}/${d.kayit}`;
  });
  console.log(tur.padEnd(16) + hucre.map((h) => h.padStart(19)).join(""));
}

console.log(`\nP4 dolasma derinligi ile sorgu sayisi`);
console.log(`${"depo turu".padEnd(16)}${[1, 2, 3].map((h) => `${h} adim`.padStart(10)).join("")}`);
for (const [tur, o] of Object.entries(ORUNTU))
  console.log(tur.padEnd(16) + [1, 2, 3].map((h) => {
    const d = new Depo(); o.P4(d, h); return String(d.sorgu).padStart(10);
  }).join(""));
```

```
model: 60000 gonderi, 20 satici, 8 merkez, rota 3 adim, dolasma 3 adim; sayilar sorgu/kayit

depo turu            P1 tekil okuma      P2 olay yazma  P3 donem taramasi  P4 rota dolasmasi
anahtar-deger                   1/1                2/2          3001/3001        67503/67503
belge                           1/1                1/1             1/3000            3/67500
genis sutun                     1/3                2/2             1/3000            3/67500
cizge                           1/4                1/2             1/6001            1/67503

P4 dolasma derinligi ile sorgu sayisi
depo turu           1 adim    2 adim    3 adim
anahtar-deger        22501     45002     67503
belge                    1         2         3
genis sutun              1         2         3
cizge                    1         1         1
```

Sayılar **hesap** sınıfındadır: modelin sayaçlarından çıkarlar, belirlenimlidirler ve makineden
bağımsızdırlar. Model bir ürün değil, erişim yeteneklerinin bir soyutlamasıdır.

## Hiçbir Sütun Baştan Sona Kazanmıyor

**P1 hiçbir türü ayırmıyor.** Dört türün de sorgu sayısı 1. Dokunulan kayıt 1, 1, 3 ve 4 olarak
farklılaşıyor, ama tek anahtarla tek kayıt getirmek her türün yaptığı iştir. Bir tasarımı yalnız
takip sorgusuna bakarak seçmek, dört seçeneği ayırt edemez.

**P2 iki türü ayırıyor.** Belge ve çizge deposu bir olayı tek istekte ekliyor. Anahtar–değer
deposu iki istek istiyor, çünkü değerin içine dokunamıyor: bütün değeri okuyup bütün değeri geri
yazıyor. Geniş sütun deposu da iki istek istiyor, ama başka bir nedenle — P3'ü karşılamak için
aynı veri ikinci bir bölüm anahtarıyla ikinci bir tabloya da yazılıyor. **İki tür aynı sayıyı iki
ayrı gerekçeyle üretiyor ve gerekçe, sayının nasıl büyüyeceğini belirliyor**: anahtar–değerin
ikinci isteği kaydın boyutuyla, geniş sütunun ikinci isteği desteklenen sorgu sayısıyla büyür.

**P3 anahtar–değer deposunu eliyor.** Belge ve geniş sütun tek istekte 3000 kayıt okuyor; çizge
tek istekte 6001 kayda dokunuyor, çünkü satıcı düğümünden her gönderiye önce bir kenar, sonra bir
düğüm üzerinden geçiliyor. Anahtar–değer 3001 istek istiyor: ikincil dizin uygulamada tutulduğu
için listede ne varsa tek tek çekiliyor. Dokunulan kayıt sayısı aynı büyüklükte, **istek sayısı üç
bin kat farklı.**

**P4 tabloyu tersine çeviriyor.** Dokunulan kayıt dört türde de aynı mertebede: 67.500 ile 67.503
arası. Ayrım sorgu sütununda. Belge ve geniş sütun adım başına bir istek harcıyor; çizge deposu
derinlik ne olursa olsun tek istekte bitiriyor; anahtar–değer 67.503 istekte. Alt tablo bunu
netleştiriyor: derinlik birden üçe çıktığında belge ve geniş sütunun istek sayısı 1, 2, 3 diye
ilerliyor, çizgeninki 1'de kalıyor. **Çizge deposunun kazandığı şey dokunulan kayıt değil, istek
sayısının dolaşma derinliğinden bağımsız olmasıdır.** Derinliği önceden bilinmeyen bir dolaşma,
başka türlerde kaç istek edeceği bilinmeyen bir işe dönüşür.

## Hesaba Geri Dönüş

Sorgu sayıları K01'in satırlarına doğrudan çevrilir: her örüntünün istek hızı, o örüntünün gerektirdiği
sorgu sayısıyla çarpılır.

```js
// tur/hesap.mjs — olculen sorgu ve kayit sayilarinin K01 hesabindaki satirlara etkisi.
// Hepsi aritmetiktir; girdi tur/erisim.mjs kosumunun ciktisidir.
const OKUMA = 41.67, YAZMA = 97.22, DEPO = 138.89, ORAN = 2.33;   // K01 hesaplari
const TARAMA = 833.33, SATICI = 4000, PENCERE = 4 * 3600;         // K01 hesaplari ve V10
const OLCUM = {                                    // tur/erisim.mjs: [sorgu, kayit]
  "anahtar-deger": { P1: [1, 1], P2: [2, 2], P3: [3001, 3001] },
  "belge": { P1: [1, 1], P2: [1, 1], P3: [1, 3000] },
  "genis sutun": { P1: [1, 3], P2: [2, 2], P3: [1, 3000] },
  "cizge": { P1: [1, 4], P2: [1, 2], P3: [1, 6001] },
};

console.log(`${"depo turu".padEnd(16)}${"depoya ulasan/s".padStart(16)}${"kat".padStart(7)}` +
  `${"yazma/okuma".padStart(13)}${"toplu istek/s".padStart(15)}${"toplu kayit/s".padStart(15)}` +
  `${"kat".padStart(7)}`);
for (const [tur, o] of Object.entries(OLCUM)) {
  const okuma = OKUMA * o.P1[0], yazma = YAZMA * o.P2[0];
  const istek = (o.P3[0] * SATICI) / PENCERE, kayit = (o.P3[1] * SATICI) / PENCERE;
  console.log(tur.padEnd(16) + (okuma + yazma).toFixed(2).padStart(16) +
    ((okuma + yazma) / DEPO).toFixed(2).padStart(7) + (yazma / okuma).toFixed(2).padStart(13) +
    istek.toFixed(2).padStart(15) + kayit.toFixed(2).padStart(15) +
    (kayit / TARAMA).toFixed(2).padStart(7));
}
console.log(`K01 tabani: depoya ulasan ${DEPO} istek/s, yazma/okuma ${ORAN}, ` +
  `toplu tarama ${TARAMA} kayit/s (toplu istek/s tek depoda ${(SATICI / PENCERE).toFixed(2)})`);
```

```
depo turu        depoya ulasan/s    kat  yazma/okuma  toplu istek/s  toplu kayit/s    kat
anahtar-deger             236.11   1.70         4.67         833.61         833.61   1.00
belge                     138.89   1.00         2.33           0.28         833.33   1.00
genis sutun               236.11   1.70         4.67           0.28         833.33   1.00
cizge                     138.89   1.00         2.33           0.28        1666.94   2.00
K01 tabani: depoya ulasan 138.89 istek/s, yazma/okuma 2.33, toplu tarama 833.33 kayit/s (toplu istek/s tek depoda 0.28)
```

İki tür `depoya ulasan istek/s` satırını 138,89'dan 236,11'e, 1,70 kat büyütüyor ve
`depoda yazma/okuma orani`nı 2,33'ten 4,67'ye çıkarıyor. İkisinde de neden aynı: P2 iki istek
istiyor. Aynı aritmetiği bu konunun ilk dersi de üretmişti — okuma yolunu ayırmak için yazma
yolunu iki hedefe uzatmak aynı 236,11'i veriyordu. **Depo türü değişse de sayı aynı yerden
geliyor: yazma yolunun kaç hedefe dokunduğundan.**

Toplu iş sütunu asıl uyarıyı taşıyor. Belge ve geniş sütun deposunda gün sonu işi dört saatlik
pencerede saniyede 0,28 istek üretiyor ve K01'in hesapladığı 833,33 kayıt/s taramayı birebir
tekrarlıyor. Anahtar–değer deposunda aynı iş saniyede **833,61 istek** üretiyor: dört saatlik bir
pencerede depo, bütün günün adım adım kurulan 138,89 istek/s'sinin altı katını görüyor. Bu, tek
bir mimari kararın K01'in en büyük kalemini hangi sütuna taşıdığını gösteriyor — kayıt sayısı
değişmedi, istek sayısı değişti.

Çizge sütunu bunun aynadaki görüntüsüdür. İstek sayısı en iyi türlerle aynı, ama toplu iş kayıt
hızı 833,33'ten 1666,94'e, iki katına çıkıyor: her gönderiye bir kenar üzerinden ulaşılıyor.
Dolaşmayı ucuzlatan yapı, toplamayı pahalılaştırıyor.

Dört sütun birlikte okunduğunda sonuç tek bir cümledir: **hiçbir tür dört örüntüyü birden
ucuzlatmaz.** Seçim en pahalı örüntüye göre yapılır ve ilk dersin kuralı sürer — kayıt sistemi tek
kalır, öteki türler ondan türetilen ikincil depolardır.

## Özet

- Bir depo türünü yerel olarak yanıtlayabildiği erişim biçimi tanımlar; yanıtlayamadığı her biçim
  uygulamaya düşer ve uygulamaya düşen her adım ayrı bir depo isteğidir.
- Tekil okuma dört türü ayırt etmiyor: hepsi tek istek, 1 ile 4 arası kayıt.
- Anahtar–değer deposu dönem taramasında 3001 istek istiyor, belge ile geniş sütun 1; dokunulan
  kayıt aynı mertebede, istek sayısı üç bin kat farklı.
- Çizge deposunun kazancı dokunulan kayıtta değil istek sayısındadır: üç adımlık dolaşmada belge
  ve geniş sütun 3 istek harcarken çizge 1 istekte kalıyor ve derinlik arttıkça bu sayı değişmiyor.
- K01'e dönüş: anahtar–değer ve geniş sütun `depoya ulasan istek/s`'yi 138,89'dan 236,11'e (1,70
  kat) ve `depoda yazma/okuma orani`nı 2,33'ten 4,67'ye çıkarıyor.
- Gün sonu işi anahtar–değer deposunda saniyede 833,61 istek üretiyor, çizge deposunda tarama
  hızını 833,33'ten 1666,94 kayıt/s'ye çıkarıyor; hiçbir tür dört örüntüyü birden ucuzlatmıyor.

## Sonraki Adım

Sekiz ders verinin **nerede** ve **hangi biçimde** durduğunu tasarladı: tür erişim örüntüsüne
göre seçildi, veri çoğaltıldı, federe edildi ve parçalandı; parçalar üç ayrı kuralla
yerleştirildi; okuma yolu denormalizasyonla kısaldı ve tekrarlanan toplam önceden hesaplandı.
Kazanç gerçek: dönem taraması 833,33 kayıt/s'den 8,33'e, bir okumanın çektiği ikincil kayıt
9000'den 40'a indi. Kazanmayan tek sayı `depoya ulasan istek/s`'nin okuma tarafıdır. Bu dersin
en iyi sütununda bile takip sorgusu saniyede 41,67 istekle deponun kapısını çalıyor, çünkü sekiz
dersin hiçbiri okumanın **depoya gitmesini** engellemedi; hepsi vardığında ne bulacağını
düzenledi. Sonraki konu okumanın deponun **önünde** karşılanmasını ele alır ve ilk sorusu kopyanın
hangi katmanda duracağıdır.
