Ders 09 / 10
Kavramsal, Mantıksal ve Fiziksel Model
Aynı 26 olgu ilişkisel yapıya çevrildiğinde tablo 5'ten 7'ye çıkıyor, 13 alan modelde adı hiç geçmeden ortaya çıkıyor ve 5 kısıttan 2'si düşüyor; düşen ikisinin yapısal sebebi tam sayımla gösteriliyor.
İçindekiler
Önceki ders kavramsal modeli tek bir düzeyde tuttu ve o düzeyin söylemediklerini saydı: yirmi altı olgu yazılıyordu, ama katılım ve öznitelik zorunluluğu yazılmadığı için aynı gösterime bir milyondan fazla sistem düşüyordu. Bu ders düzeyi değiştirir.
Sorusu şudur: aynı yirmi altı olgu ilişkisel bir yapıya çevrildiğinde ne kadarı olduğu gibi taşınıyor, ne kadarı düşüyor, ve modelde hiç yazmayan ne kadar şey ortaya çıkıyor. Üç sayı yine yan yana duracak, ama bu kez bedelin iki ayrı bileşeni var: düşen kısıt ve uydurulan alan. İkisi ayrı ayrı sayılır, çünkü biri kayıp, öteki eklemedir.
Üç Düzey
Kavramsal model alanın olgularını taşır ve hiçbir saklama kararı içermez: varlık, öznitelik, ilişki, kısıt. Mantıksal model bu olguları belirli bir veri modelinin yapılarına çevirir; burada o yapı ilişkiseldir, yani tablo, alan, anahtar ve yabancı anahtar. Fiziksel model aynı yapıyı saklanabilir hâle getirir: tip, uzunluk, boş geçilebilirlik, dizin. Üç düzeyin hiçbiri bir ürün adı içermez; fiziksel düzey bile karar türlerini taşır, ürünü değil.
- VM8 — Üç düzey birbirinin üstüne oturur ve aşağı inildikçe karar sayısı artar. Bir düzeyin yazmadığı her şey aşağıdaki düzeyde ya türetilir ya da uydurulur.
- VM9 — Mantıksal geçiş kuralı sabittir: her varlık bir tabloya çevrilir, her N:M ilişkisi bir bağlantı bağıntısına açılır, her N:1 ve 1:N ilişkisi çok tarafına konan bir yabancı anahtar alanına döner, ve her tabloya bir birincil anahtar alanı eklenir.
- VM10 — Bir kısıt, ilişkisel yapının anahtar, benzersizlik ve yabancı anahtar araçlarından biriyle yazılabiliyorsa taşınır; yazılamıyorsa düşer.
Anahtar çeşitleri, yabancı anahtarın silme ve güncelleme eylemleri, bütünlük kısıtları ve normalleştirme bu derste öğretilmez; hepsi Veritabanları müfredatının İlişkisel Kuram kursunda kuruldu. Burada o araçlar yalnız birer taşıma aracı olarak kullanılıyor ve sorulan tek şey, hangi olgunun taşınıp hangisinin taşınamadığıdır.
"""M01/K06 ortak tanim (kesit): kavramsaldan mantiksala gecis ve gecisin bilancosu.""" KISITLAR = [ {"metin": "her is emrinin tek ustasi var", "arac": "yabanci anahtar"}, {"metin": "parca kodu benzersiz", "arac": "benzersizlik"}, {"metin": "belge yalnizca kendi is emrine ait", "arac": "yabanci anahtar"}, {"metin": "bir is emri en az bir parca ister", "arac": None}, {"metin": "bir usta ayni anda tek tezgahta", "arac": None}, ] KAVRAMSAL = { "varliklar": ["IsEmri", "Usta", "Parca", "Tezgah", "Belge"], "oznitelikler": {"IsEmri": ["no", "acilis", "durum"], "Usta": ["ad", "uzmanlik"], "Parca": ["kod", "ad", "birim"], "Tezgah": ["kod", "tur"], "Belge": ["tur", "tarih"]}, "iliskiler": [("IsEmri", "Usta", "N:1"), ("IsEmri", "Parca", "N:M"), ("Usta", "Tezgah", "N:M"), ("IsEmri", "Belge", "1:N")], "kisitlar": KISITLAR, } def mantiksal(kavramsal): """N:M iliskiler bağlantı bağıntısına acilir; kisitlar tasinabilirligine gore ayrilir.""" tablolar = {} for v in kavramsal["varliklar"]: tablolar[v] = ["anahtar"] + list(kavramsal["oznitelikler"][v]) ara = [] for a, b, c in kavramsal["iliskiler"]: if c == "N:M": ad = f"{a}_{b}" tablolar[ad] = ["anahtar", f"{a}_anahtar", f"{b}_anahtar"] ara.append(ad) elif c == "N:1": tablolar[a].append(f"{b}_anahtar") else: tablolar[b].append(f"{a}_anahtar") tasinan = [k for k in kavramsal["kisitlar"] if k["arac"]] dusen = [k for k in kavramsal["kisitlar"] if not k["arac"]] return {"tablolar": tablolar, "baglanti_bagintisi": ara, "tasinan": tasinan, "dusen": dusen} M = mantiksal(KAVRAMSAL) print("tablo alan alanlar") for ad, alanlar in M["tablolar"].items(): print(f"{ad:14s} {len(alanlar):4d} {', '.join(alanlar)}") print() alan = sum(len(v) for v in M["tablolar"].values()) oznitelik = sum(len(a) for a in KAVRAMSAL["oznitelikler"].values()) anahtar = sum(v.count("anahtar") for v in M["tablolar"].values()) yabanci = sum(1 for v in M["tablolar"].values() for a in v if a.endswith("_anahtar")) print("varlik", len(KAVRAMSAL["varliklar"]), "-> tablo", len(M["tablolar"]), "( bağlantı bağıntısı:", ", ".join(M["baglanti_bagintisi"]), ")") print("oznitelik", oznitelik, "-> alan", alan, "| kavramsal modelde adi hic gecmeyen alan:", alan - oznitelik) print(" ", anahtar, "birincil anahtar +", yabanci, "yabanci anahtar =", anahtar + yabanci) print("kisit", len(KISITLAR), "-> tasinan", len(M["tasinan"]), "| dusen", len(M["dusen"])) for k in M["dusen"]: print(" DUSEN:", k["metin"])
tablo alan alanlar IsEmri 5 anahtar, no, acilis, durum, Usta_anahtar Usta 3 anahtar, ad, uzmanlik Parca 4 anahtar, kod, ad, birim Tezgah 3 anahtar, kod, tur Belge 4 anahtar, tur, tarih, IsEmri_anahtar IsEmri_Parca 3 anahtar, IsEmri_anahtar, Parca_anahtar Usta_Tezgah 3 anahtar, Usta_anahtar, Tezgah_anahtar varlik 5 -> tablo 7 ( bağlantı bağıntısı: IsEmri_Parca, Usta_Tezgah ) oznitelik 12 -> alan 25 | kavramsal modelde adi hic gecmeyen alan: 13 7 birincil anahtar + 6 yabanci anahtar = 13 kisit 5 -> tasinan 3 | dusen 2 DUSEN: bir is emri en az bir parca ister DUSEN: bir usta ayni anda tek tezgahta
Sistem: 26 olgu. Gösterim: 7 tablo ve 25 alan. Bedel: 2 düşen kısıt ve 13 uydurulan alan. Üçüncü sayı en az bakılanıdır ama en açıklayıcı olanıdır: mantıksal model, kavramsal modelin adını hiç anmadığı on üç alan taşıyor. Yedisi tabloların birincil anahtarı, altısı ilişkileri kuran yabancı anahtar. Bunların hiçbiri alanın bir olgusu değildir — atölyede kimse iş emrinin “anahtarından” söz etmez. Bunlar ilişkisel yapının kendi kayıt tutma gereçleridir ve modelden değil, düzeyden gelirler.
Tablo sayısının 5’ten 7’ye çıkması da aynı yerden gelir. İlişkisel yapı bir N:M ilişkisini doğrudan tutamaz; iki tarafın anahtarlarını taşıyan bir bağlantı bağıntısı ister. İki N:M ilişkisi olduğu için iki bağlantı bağıntısı doğar ve alan sayısı altı artar. Bu, bir tasarım tercihi değildir; ilişkisel yapının ifade sınırının doğrudan sonucudur.
Düşen İki Kısıt Neden Düşüyor
Beş kısıttan üçü taşınıyor: “her iş emrinin tek ustası var” bir yabancı anahtarla, “parça kodu benzersiz” bir benzersizlik kısıtıyla, “belge yalnızca kendi iş emrine ait” yine bir yabancı anahtarla yazılabiliyor. Kalan ikisi düşüyor, ve düşme sebebi unutkanlık değil, yüklemin türüdür.
Anahtar, benzersizlik ve yabancı anahtar araçlarının üçü de aynı biçimdedir: bir tek satıra bakarlar ya da iki satırın belirli alanlarının eşitliğini karşılaştırırlar. Düşen iki kısıt bu iki biçimin dışındadır. “Bir iş emri en az bir parça ister” tek satıra bakarak yanıtlanamaz; bir iş emrine bağlı satırların sayısına bakar ve sayı için bir alt sınır ister. “Bir usta aynı anda tek tezgahta” ise iki satırın zaman aralıklarının kesişimini sorar, oysa benzersizlik yalnız eşitliği görür.
- VM11 — Fazla kabul sayımında iki iş emri, iki parça, iki usta ve iki tezgah alınır. Örnek uzayı, bağlantı bağıntısının alabileceği bütün satır alt kümeleridir; sayım tamdır.
- VM12 — Örnekler tek bir andaki durumu gösterir; tabloda zaman alanı yoktur.
"""Dusen iki kisit neden dusuyor: iliskisel arac hangi yuklemi yazamiyor.""" from itertools import combinations, product IS_EMRI, PARCA = ("o1", "o2"), ("p1", "p2") USTA, TEZGAH = ("u1", "u2"), ("t1", "t2") def tum_ornekler(sol, sag): """Ara tablonun alabilecegi butun degerler: satir kumesinin butun alt kumeleri.""" satir = list(product(sol, sag)) return [frozenset(k) for n in range(len(satir) + 1) for k in combinations(satir, n)] def araclar_kabul(ornek, sol, sag): """Bilesik birincil anahtar satir yinelemesini , yabanci anahtar bos basvuruyu keser. Ikisi de TEK SATIRA bakan yuklemlerdir.""" return all(a in sol and b in sag for a, b in ornek) def en_az_bir_parca(ornek, sol): """Grup BUYUKLUGUNE bakan yuklem: her is emrinin en az bir satiri olmali.""" return all(any(kaynak == x for kaynak, _ in ornek) for x in sol) def tek_tezgah(ornek): """Yine grup buyuklugu: bir usta en cok bir satirda gorunmeli.""" kullanan = [a for a, _ in ornek] return len(kullanan) == len(set(kullanan)) toplam_arac, toplam_dogru = 1, 1 for ad, sol, sag, gercek in (("IsEmri_Parca", IS_EMRI, PARCA, lambda o: en_az_bir_parca(o, IS_EMRI)), ("Usta_Tezgah", USTA, TEZGAH, tek_tezgah)): hepsi = tum_ornekler(sol, sag) arac = [o for o in hepsi if araclar_kabul(o, sol, sag)] dogru = [o for o in arac if gercek(o)] toplam_arac *= len(arac) toplam_dogru *= len(dogru) print(f"{ad:13s} olasi ornek {len(hepsi):3d} | arac kabul {len(arac):3d}" f" | sistemde dogru {len(dogru):3d} | fazla kabul {len(arac) - len(dogru):3d}") print(f"{'':13s} en kucuk fazla kabul: " f"{sorted(sorted(o) for o in arac if not gercek(o))[0]}") print() print("iki bağlantı bağıntısı birlikte: arac kabul", toplam_arac, "| sistemde dogru", toplam_dogru, "| fazla kabul", toplam_arac - toplam_dogru) print() def ortusuyor(x, y): return x[1] < y[2] and y[1] < x[2] SATIR = [("u1", 0, 4), ("u1", 2, 6)] print("zaman alani eklense bile:") print(" iki satirin degerleri farkli -> benzersizlik gecer:", len(set(SATIR)) == len(SATIR)) print(" araliklar ortusuyor -> kisit ihlal:", ortusuyor(SATIR[0], SATIR[1]))
IsEmri_Parca olasi ornek 16 | arac kabul 16 | sistemde dogru 9 | fazla kabul 7
en kucuk fazla kabul: []
Usta_Tezgah olasi ornek 16 | arac kabul 16 | sistemde dogru 9 | fazla kabul 7
en kucuk fazla kabul: [('u1', 't1'), ('u1', 't2')]
iki bağlantı bağıntısı birlikte: arac kabul 256 | sistemde dogru 81 | fazla kabul 175
zaman alani eklense bile:
iki satirin degerleri farkli -> benzersizlik gecer: True
araliklar ortusuyor -> kisit ihlal: True
Her iki bağlantı bağıntısı için de araçlar 16 örneğin 16’sını kabul ediyor, oysa sistemde doğru olan yalnız 9’u. Yedişer örnek, şemanın kabul ettiği ama alanda hiç var olmaması gereken durumlardır — kursun terimiyle fazla kabul. İki tablo birlikte ele alındığında şema 256 durumu kabul ediyor, sistemde doğru olan 81, aradaki fark 175.
En küçük karşı örnekler kısıtların türünü çıplak biçimde gösteriyor. “En az bir parça”
kısıtının en küçük ihlali boş tablodur: hiçbir satır yoksa hiçbir anahtar ve hiçbir
yabancı anahtar ihlal edilmez, ama her iş emri parçasız kalmıştır. Bir alt sınır kısıtını
satır düzeyinde çalışan bir araçla yazmak yapısal olarak mümkün değildir, çünkü ihlal
var olan bir satırda değil, olmayan bir satırdadır. İkinci kısıtın en küçük ihlali iki
satırdır: ('u1','t1') ve ('u1','t2'). Bileşik anahtar bu iki satırı ayrı sayar, çünkü
gerçekten farklıdırlar; sorulan soru eşitlik değil, aynı ustanın kaç kez göründüğüdür.
Son iki satır ise kısıtı zaman alanı ekleyerek kurtarma girişiminin neden yetmediğini
gösteriyor. ('u1', 0, 4) ile ('u1', 2, 6) farklı değerlerdir, bu yüzden her benzersizlik
kısıtından geçerler; ama aralıkları örtüşür ve kısıt ihlal edilmiştir. Eşitlik ile
kesişim ayrı yüklemlerdir ve biri ötekini ifade edemez.
İkinci Yapılandırma
Bir ölçüm, yalnız değiştirilerek sınandığında anlaşılır. İki değişiklik denenir: kardinaliteleri değiştirmek ve modele yeni bir alan eklemek.
- VM13 — Zaman alanı iki dilimlidir (0 ve 1);
zamanalanı kavramsal modelde bulunmayan, mantıksal düzeyde eklenen bir alandır.
"""Ikinci yapilandirma: dusen kisiti tasimanin iki yolu ve ikisinin de bedeli.""" from itertools import combinations, product USTA, TEZGAH, ZAMAN = ("u1", "u2"), ("t1", "t2"), (0, 1) def alt_kumeler(satir): return [frozenset(k) for n in range(len(satir) + 1) for k in combinations(satir, n)] def sema(iliskiler, varlik=5, oznitelik=12): tablo = varlik + sum(1 for _, c in iliskiler if c == "N:M") alan = tablo + oznitelik + sum(2 if c == "N:M" else 1 for _, c in iliskiler) return tablo, alan print("IsEmri-Parca Usta-Tezgah tablo alan uydurulan alan") for c1, c2 in product(("N:M", "N:1"), repeat=2): t, a = sema([("IsEmri-Usta", "N:1"), ("IsEmri-Parca", c1), ("Usta-Tezgah", c2), ("IsEmri-Belge", "1:N")]) print(f"{c1:^12s} {c2:^11s} {t:5d} {a:4d} {a - 12:14d}") print() satir_zamansiz = list(product(USTA, TEZGAH)) satir_zamanli = list(product(USTA, TEZGAH, ZAMAN)) def dogru_zamansiz(o): k = [u for u, _ in o] return len(k) == len(set(k)) def dogru_zamanli(o): k = [(u, z) for u, _, z in o] return len(k) == len(set(k)) for ad, satir, dogru, benzersiz in ( ("zaman alani yok ", satir_zamansiz, dogru_zamansiz, None), ("zaman alani var ", satir_zamanli, dogru_zamanli, None), ("zaman + benzersiz", satir_zamanli, dogru_zamanli, dogru_zamanli)): hepsi = alt_kumeler(satir) arac = [o for o in hepsi if benzersiz is None or benzersiz(o)] dog = [o for o in arac if dogru(o)] print(f"{ad}: arac kabul {len(arac):4d} | sistemde dogru {len(dog):3d}" f" | fazla kabul {len(arac) - len(dog):4d}")
IsEmri-Parca Usta-Tezgah tablo alan uydurulan alan
N:M N:M 7 25 13
N:M N:1 6 23 11
N:1 N:M 6 23 11
N:1 N:1 5 21 9
zaman alani yok : arac kabul 16 | sistemde dogru 9 | fazla kabul 7
zaman alani var : arac kabul 256 | sistemde dogru 81 | fazla kabul 175
zaman + benzersiz: arac kabul 81 | sistemde dogru 81 | fazla kabul 0
Birinci tablo, bağlantı bağıntısının bir tercih olmadığını gösteriyor: her N:M ilişkisi tam olarak bir tablo ve iki alan ekliyor, ve dördüncü satırda hiç N:M kalmayınca tablo sayısı varlık sayısına, yani 5’e iniyor. Uydurulan alan da 13’ten 9’a düşüyor — çünkü tablo başına bir anahtar ve ilişki başına en az bir yabancı anahtar her durumda gerekiyor.
İkinci tablo daha ilginçtir. Zaman alanı eklenince tablonun taşıyabildiği doğru örnek
sayısı 9’dan 81’e çıkıyor: aynı ustanın farklı zaman dilimlerinde farklı tezgâhlarda
çalıştığı yetmiş iki durum, zamansız biçimde hiç yazılamıyordu. Üstelik (usta, zaman)
üzerine konan bir benzersizlik kısıtı, düşen kısıtı tam olarak taşıyor: fazla kabul
175’ten 0’a iniyor.
Bu sonuç düşen kısıtları geri getirmenin yolunu gösteriyor, ama bedelini de gösteriyor. Kısıt ancak kavramsal modelde hiç bulunmayan bir alan eklendikten sonra yazılabildi. Yani düşen kısıtı kurtarmanın yolu, modelin söylemediği bir şeyi şemaya koymaktan geçiyor — ve o alanın oradaki varlığını açıklayan hiçbir olgu kavramsal modelde yazmıyor. Bu, sonraki dersin konusunun ilk örneğidir: mantıksal ve fiziksel düzey yalnız kaybetmez, aynı zamanda uydurur.
Özet
- Kavramsal düzey alanın olgularını, mantıksal düzey bunların ilişkisel yapıdaki karşılığını, fiziksel düzey saklama kararlarını taşır; aşağı inildikçe karar sayısı artar.
- 26 olgu mantıksal düzeyde 7 tabloya ve 25 alana dönüşüyor. İki N:M ilişkisi iki ara tablo doğuruyor ve tablo sayısını 5’ten 7’ye çıkarıyor.
- 25 alanın 13’ünün adı kavramsal modelde hiç geçmiyor: 7 birincil anahtar ve 6 yabancı anahtar. Bunlar alanın olgusu değil, ilişkisel yapının kayıt tutma gereçleridir.
- 5 kısıttan 3’ü taşınıyor, 2’si düşüyor. Düşme sebebi yüklemin türüdür: biri satır sayısına alt sınır koyar, öteki zaman aralıklarının kesişimini sorar; anahtar ve benzersizlik ise tek satıra bakar ya da eşitliği karşılaştırır.
- Düşen kısıtların bedeli sayıldı: iki bağlantı bağıntısında şema 256 örneği kabul ederken sistemde doğru olan 81, yani 175 fazla kabul. En küçük ihlaller boş tablo ve aynı ustanın iki satırıdır.
- Kısıt, kavramsal modelde bulunmayan bir
zamanalanı eklenerek tam olarak taşınabiliyor (fazla kabul 175’ten 0’a) ve taşınabilen doğru örnek sayısı 9’dan 81’e çıkıyor; bedeli, modelin söylemediği bir alanı şemaya koymaktır.
Sonraki Adım
Bu ders bir alanın modelde adı geçmeden ortaya çıkabildiğini gösterdi ve on üç tanesini saydı. Sıradaki ders bu sayımı fiziksel düzeye taşır ve orada durum köklü biçimde değişir: yedi tablo ile yirmi beş alan, yüz alan kararı ve on dört tablo kararı ister. Toplam yüz on dört karar, kavramsal modelin söylediği yirmi altı olgunun kaç katıdır, bu kararları kim verir, ve verilen kararın yanlış olduğu nereden anlaşılır.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.