Ders 04 / 12
Veri Pazarı
Tek bir birime adanmış bir alt küme ayrı yazıldığında sorgu maliyetinin ne olduğunun ve aynı satırın kaç yerde durduğunun sayılması: üç soruluk bir kümede bölümlemesiz ambar 13.560, en iyi merkezî düzen 3.256, iki pazar 2.580 ödüyor ve pazarın kazancı bölge sorusunda sıfır, tip sorusunda 676. Bedel çoğalmadır: altı pazar 3.322 satır daha saklıyor, satır başına 2,51 kopya, 1.122 satır üç ayrı yerde duruyor. Geç gelen kayıt ambara işlendiğinde yenilenmemiş altı pazar 126 (satır, yer) çiftinde ayrışıyor ve yarı yenilenmiş bir kümede beş bölge pazarının toplamı 4.707, ambarınki 5.340 çıkıyor.
İçindekiler
Önceki üç ders depolamanın ne sakladığını ayırdı: şemaya uyan satırı, ham satırı ve ikisini aynı yerde tutan düzeni. Üçünde de sorulan soru “bu satır nasıl saklanır” idi ve yanıt bir yazma kararıydı. Bir soru hiç sorulmadı: bu satır kimin için saklanır. Bölge sorumlusunun sorduğu soru ile tarife sorumlusunun sorduğu soru aynı satırlara dokunur, fakat aynı düzeni istemez.
Bu dersin ölçtüğü şey o ayrışmanın bedelidir. Tek bir birimin sorularına adanmış alt küme ambardan çıkarılıp ayrı yazıldığında sorgu maliyeti düşer; karşılığında aynı satır birden çok yerde durur ve o yerler ayrı ayrı tazelenir. İki sayı yan yana konur: alt kümenin kazandırdığı maliyet ve aynı satırın kaç kopyası olduğu.
- DY41. Kaynak, hat ve depolama düzeni kurgudur ve ders içinde tanımlanır. Hiçbir ambar, göl, dosya biçimi, katalog ürünü ya da sorgu motoru çağrılmaz. Tohum 20260218.
- DY42. Veri pazarı (data mart), ambardaki satırların tek bir alan değeri üzerinden çıkarılmış ve ayrı yazılmış alt kümesidir. Türetme kuralı tek alan üzerinde eşitliktir; özetleme yoktur, satırlar ambardaki satırların aynısıdır.
- DY43. Maliyet ölçüsü kurs boyunca aynıdır:
dosya x 120 + okunan hücre. Dosya sabiti 120 bir seçimdir; bu derste sabit tutulur, süpürülmesi sonraki derse bırakılır. - DY44. Bir pazar yazıldığı anın satırlarını taşır. Tazeleme ayrı bir iştir ve ambarın tazelenmesiyle aynı anda olmak zorunda değildir.
- DY45. Bölümleme, parçalama ve çoğaltma yordamı Veritabanları müfredatındaki İlişkisel Veritabanı Yönetimi kursunda ve Sistem Tasarımı ve Dağıtık Sistemler müfredatındaki Veri Katmanı Ölçekleme kursunda ölçüldü; burada tekrarlanmaz. Bu ders yalnız alt küme çıkarma kararının sorguya ödettiğini sayar.
- DY46. Satır oranı basılacaksa çözünürlük yazılır: küme 2.200 satırdır, oran adımı 0,0005. Maliyet bir orandır değil tam sayıdır ve değerin kendisi yazılır.
Alt Kümenin Kattığı
Ölçüm üç soruyla yapılır. İkisi bir bölgenin sorusudur: o bölgenin bir dönemi ve o bölgenin bütün dönemleri. Üçüncüsü bir tarife sorusudur: bir dönemdeki işyeri aboneleri. Üç soru da aynı 2.200 satırın üstündedir ve üçü de aynı yanıtı vermek zorundadır; ayrıldıkları tek yer, o yanıta ulaşmak için dokunulan dosya ve okunan hücredir.
# KURGUDUR. Olcum aginin sayac okumalari, hat ve depolama duzeni ders icinde # tanimlanir; hicbir ambar, gol, dosya bicimi ya da sorgu motoru cagrilmaz. 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): 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 cikti.append(dict(k, m3=int(k["endeks"]) - int(onceki["endeks"]))) return cikti, dusen SUTUN = ("abone", "donem", "bolge", "tip", "endeks", "birim", "m3") DOSYA_SABIT = 120 # bir dosyaya dokunmanin sabit bedeli , hucre cinsinden def hattan(kaynak): v, _ = a1_ayikla(kaynak) 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: duzen.setdefault(tuple(k[a] for a in bolumleme), []).append(k) return duzen def sorgu(duzen, bolumleme, secilen, suzgec=None, sutunlu=True): """Bolumleme anahtarindaki alan dosya budar , obur alan 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: es = dict(zip(bolumleme, anahtar)) if any(es[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} def pazar(kayitlar, alan, deger): """Birim odakli alt kume: ambardan tek bir degere ait satirlar ayri yazilir.""" return [k for k in kayitlar if k[alan] == deger] TUM = hattan(kaynak_uret()) SEC = ("abone", "m3") SORU = [("dogu/07", {"bolge": "dogu", "donem": "2026-07"}), ("dogu/tum", {"bolge": "dogu"}), ("isyeri/07", {"tip": "isyeri", "donem": "2026-07"})] DUZEN = [("bolumlemesiz", ()), ("donem", ("donem",)), ("donem+bolge", ("donem", "bolge")), ("donem+bolge+tip", ("donem", "bolge", "tip"))] print(f"hattan cikan satir {len(TUM)} , dosya sabiti {DOSYA_SABIT} hucre") print("\nmerkezi ambar dosya " + " ".join(f"{a:>10}" for a, _ in SORU) + " toplam") for ad, bl in DUZEN: d = yaz(TUM, bl) m = [sorgu(d, bl, SEC, f)["maliyet"] for _, f in SORU] print(f"{ad:<17} {len(d):>5} " + " ".join(f"{x:>10}" for x in m) + f" {sum(m):>6}") p_bolge = yaz(pazar(TUM, "bolge", "dogu"), ("donem",)) p_tip = yaz(pazar(TUM, "tip", "isyeri"), ("donem",)) m = [sorgu(p_bolge, ("donem",), SEC, {"donem": "2026-07"})["maliyet"], sorgu(p_bolge, ("donem",), SEC, {})["maliyet"], sorgu(p_tip, ("donem",), SEC, {"donem": "2026-07"})["maliyet"]] print(f"{'iki pazar':<17} {len(p_bolge) + len(p_tip):>5} " + " ".join(f"{x:>10}" for x in m) + f" {sum(m):>6}")
hattan cikan satir 2200 , dosya sabiti 120 hucre merkezi ambar dosya dogu/07 dogu/tum isyeri/07 toplam bolumlemesiz 1 4520 4520 4520 13560 donem 11 520 5720 520 6760 donem+bolge 55 188 2068 1000 3256 donem+bolge+tip 110 308 3388 804 4500 iki pazar 22 188 2068 324 2580
Tablonun ilk satırı taban çizgisidir: bölümlemesiz, satırlı, tarihçesiz düzende üç soru da aynı tek
dosyayı baştan sona okur ve toplam 13.560 öder. Pazar kurulumu 2.580 ile en ucuzudur ve bunu
yirmi iki dosyayla yapar; en iyi merkezî düzen olan donem+bolge elli beş dosyayla 3.256
öder. Ancak asıl okunması gereken yer toplam değil, sütunlardır.
Bölge sorularında pazarın kazancı sıfırdır. dogu/07 hem donem+bolge düzeninde hem doğu
pazarında 188, dogu/tum ikisinde de 2.068. Bunun nedeni açıktır: bir bölge pazarı, bölge alanını
bölüm anahtarına eklemekle aynı budamayı yapar. Aynı sonucu veren iki yoldan biri satırları
kopyalar, öbürü yalnızca dizilişi değiştirir. Bir alt küme çıkarma kararının bölümleme kararından
farklı bir şey kazandırdığı iddia ediliyorsa, o farkın sayısı gösterilmelidir.
Fark üçüncü sütunda görünür. isyeri/07 sorusunda donem+bolge düzeni 1.000, işyeri pazarı 324
öder; kazanç 676. Merkezî düzen bu soruyu ucuzlatamaz, çünkü bölüm anahtarı tek bir
sıralamadır ve o sıralama bölgeye ayrılmıştır. Üçüncü alanı da anahtara eklemek işi düzeltmez,
kötüleştirir: donem+bolge+tip düzeni yüz on dosyaya çıkar ve toplamı 3.256’dan 4.500’e taşır,
üstelik ilk iki soruda da pahalılaşır. Okunan hücre azalırken dosya sabitinin yüz on kez ödenmesi
kazancı yutar. Pazarın gerçek kazandırdığı şey budur: her alt kümenin kendi bölüm anahtarını
seçebilmesi. Tek bir düzende bu mümkün değildir.
Aynı Satır Kaç Yerde Duruyor
Kazanç bir yazma kararıyla alındı ve her yazma kararı bir kopya üretti. Şimdi sayılacak olan kopyanın kendisidir. Kurulum genişletilir: beş bölge pazarı ve bir tarife pazarı, ambarın yanında. Ardından üretici tarafında bir kaza olur — bir dönemde kırk abonenin okuması geç gelir — ve kayıt sonradan ambara işlenir. Pazarların tazelenmesi ayrı bir iştir; tazelenmedikleri sürece ne söyledikleri sayılır.
# Onceki blogun tanimlari surer: hattan, kaynak_uret, pazar, TUM, BOLGE. def gec_gelen(kayit, donem="2026-07", ust="A040"): """KURGU uretici kazasi: bu donemde 40 abonenin okumasi hic gelmedi.""" return [k for k in kayit if not (k["donem"] == donem and k["abone"] <= ust)] def anahtar(kayitlar): return {(k["abone"], k["donem"]) for k in kayitlar} def toplam(kayitlar, donem="2026-07"): return sum(k["m3"] for k in kayitlar if k["donem"] == donem) PAZAR = [(b, "bolge", b) for b in BOLGE] + [("isyeri", "tip", "isyeri")] ESKI = hattan(gec_gelen(kaynak_uret())) # gec gelen kayitla yazilmis pazarlar kopya = {} for k in TUM: n = 1 + sum(1 for _, a, d in PAZAR if k[a] == d) kopya[n] = kopya.get(n, 0) + 1 saklanan = len(TUM) + sum(len(pazar(TUM, a, d)) for _, a, d in PAZAR) print(f"ambar {len(TUM)} satir , alti pazar {saklanan - len(TUM)} satir , " f"saklanan toplam {saklanan}") print(f"iki yerde duran satir {kopya[2]} , uc yerde duran {kopya[3]} , " f"satir basina ortalama {saklanan / len(TUM):.2f} kopya") print("\npazar satir yenilenmemis eksik satir 07 ambar 07 pazar fark") eksik_toplam = 0 for ad, a, d in PAZAR: yeni, esk = pazar(TUM, a, d), pazar(ESKI, a, d) eksik = len(anahtar(yeni) - anahtar(esk)) eksik_toplam += eksik print(f"{ad:<9} {len(yeni):>5} {len(esk):>12} {eksik:>10} {toplam(yeni):>8}" f" {toplam(esk):>8} {toplam(yeni) - toplam(esk):>5}") print(f"tutarsiz (satir , yer) cifti: {eksik_toplam}") # Kismi yenileme: ambar ve iki bolge pazari yenilendi , uc pazar yenilenmedi. YENI = {"dogu", "bati"} pazar_toplami = sum(toplam(pazar(TUM if b in YENI else ESKI, "bolge", b)) for b in BOLGE) print(f"\nambarin 2026-07 toplami {toplam(TUM)} , bes bolge pazarinin toplami " f"{pazar_toplami} , fark {toplam(TUM) - pazar_toplami}")
ambar 2200 satir , alti pazar 3322 satir , saklanan toplam 5522 iki yerde duran satir 1078 , uc yerde duran 1122 , satir basina ortalama 2.51 kopya pazar satir yenilenmemis eksik satir 07 ambar 07 pazar fark dogu 374 356 18 958 665 293 bati 341 333 8 812 674 138 kuzey 506 492 14 1251 1041 210 guney 440 418 22 1039 780 259 merkez 539 521 18 1280 1116 164 isyeri 1122 1076 46 2738 2113 625 tutarsiz (satir , yer) cifti: 126 ambarin 2026-07 toplami 5340 , bes bolge pazarinin toplami 4707 , fark 633
Birinci sayı saklama tarafındadır: 2.200 satırlık bir veri kümesi altı pazarla birlikte 5.522 satır olarak duruyor, satır başına 2,51 kopya. Beş bölge pazarı satırları ayrıştırdığı için her satırı tam bir kez çoğaltıyor; tarife pazarı bunun üstüne biniyor ve 1.122 satırı üçüncü bir yere yazıyor. Kopya sayısı düzenlerin sayısıyla değil, düzenlerin kesişmesiyle artar; kesişmeyen beş pazar ikinci kopyayı, kesişen bir pazar üçüncüyü getirdi.
İkinci sayı tutarlılık tarafındadır ve saklama sayısından daha ağırdır. Geç gelen kayıt ambara işlendiğinde ambar 2.200 satıra çıkıyor, tazelenmemiş pazarlar yazıldıkları andaki satırlarda kalıyor. Ayrışma 126 (satır, yer) çiftindedir: seksen satır beş bölge pazarında, kırk altısı ayrıca tarife pazarında eksik. Ayrışmanın sunulan sayıya yansıması sütunlardadır — doğu pazarı o dönem için 665 diyor, ambar 958 diyor. Aynı soruya iki adres iki yanıt veriyor ve hiçbir yerde hata görünmüyor; her iki taraf da kendi içinde tutarlı, eksiksiz ve tür bakımından kusursuz.
Üçüncü sayı çoğalmanın en sinsi biçimidir. Tazeleme hepsi için aynı anda yapılmaz; ambar ve iki bölge pazarı yenilenmiş, üçü yenilenmemiş bir anda beş bölge pazarının toplamı 4.707, ambarın aynı dönem toplamı 5.340 çıkıyor. Fark 633 m3 ve iki sayı da bir kaynağın kendi içinde doğru okumasıdır. Ambar bölge pazarlarının birleşimi olduğu hâlde birleşimin toplamı ambarınkini vermiyor; veren şey tazelemenin sırası. Bir alt küme çıkarıldığında ölçülmesi gereken üçüncü sayı, iki adresin ne kadar süre farklı yanıt verdiğidir.
Özet
- Veri pazarı, ambardaki satırların tek bir alan değeri üzerinden çıkarılmış ve ayrı yazılmış alt kümesidir; özet değil, aynı satırların ikinci bir kopyasıdır.
- Üç soruluk kümede bölümlemesiz taban 13.560, en iyi merkezî düzen 3.256, iki pazar 2.580 öder; ama pazarın bölge sorularındaki kazancı sıfırdır, çünkü orada bölüm anahtarına bir alan eklemekle aynı budama elde edilir.
- Pazarın gerçek kazancı her alt kümenin kendi bölüm anahtarını seçebilmesidir: tarife sorusunda merkezî düzen 1.000, tarife pazarı 324 öder; üçüncü alanı merkezî anahtara eklemek toplamı 3.256’dan 4.500’e çıkarır.
- Bedel çoğalmadır: altı pazar 3.322 satır daha saklar, satır başına 2,51 kopya, 1.122 satır üç ayrı yerde durur. Kopya sayısını düzenlerin sayısı değil kesişmesi belirler.
- Tazeleme ayrıştığında 126 (satır, yer) çifti ayrışır ve aynı soru iki adreste iki yanıt verir (665 ve 958) — hiçbir hata görünmeden.
- Yarı yenilenmiş bir kümede beş bölge pazarının toplamı 4.707, ambarın aynı dönem toplamı 5.340 olur; iki sayı da kendi kaynağında doğrudur.
Sonraki Adım
Bu derste alt kümeyi kimin çıkardığı hiç sorulmadı. Altı pazarın bölüm anahtarını, tazeleme sırasını ve türetme kuralını tek bir taraf belirledi; bölge sorumlusu yalnızca kendisi için yazılmış alt kümeyi okudu. Karar o tarafta kalmasaydı ne olurdu — düzen kararını bölgenin kendisi verseydi, tazeleme takvimini kendisi seçseydi. İki sayı bu soruyla değişir: düzen kararı alan taraf sayısı ve uçtan uca bir sorgunun dokunduğu düzen sayısı. Sonraki ders sahipliğin dağıtıldığı iki modeli bu iki sayıyla ölçer ve aynı yerde bu kursun her maliyetinin dayandığı dosya sabitini süpürerek hangi sonuçların o sabite bağlı olduğunu gösterir.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.