SEN2104 · 11. hafta · Relational Database Design

Ayrıştırma: kayıpsız birleştirme, bağımlılık koruma, BCNF ve 3NF algoritmaları

Bir şemayı parçalara bölerken veri kaybetmemeyi (lossless join) ve FD'leri korumayı test etmeyi, BCNF ayrıştırma ve 3NF sentez algoritmalarını adım adım uygulamayı öğrenirsin.

decompositionlossless-join decompositionlossy decompositionspurious tuplechase (tableau) testdependency preservationprojection of FBCNF decomposition algorithm3NF synthesis algorithm

Geçen hafta bir şemanın hangi normal formda olduğunu bulmayı öğrendin. Normal form düşükse çözüm şemayı parçalara ayırmak (decomposition). Ama her bölme iyi değil. Bir ayrıştırmadan iki şey istersin:

  1. Kayıpsız birleştirme (lossless join): Parçaları NATURAL JOIN ile geri birleştirince tam olarak orijinal tablo çıkmalı.
  2. Bağımlılık koruma (dependency preservation): Her FD, join yapmadan tek tek parçalarda denetlenebilmeli.

Sınavda tipik sorular: “Is this decomposition lossless?”, “Is it dependency preserving?”, “Decompose R into BCNF”, “Apply the 3NF synthesis algorithm”.

Kayıplı ayrıştırma: veride görelim

Örnek veritabanından öğrencinin bölümünü ve aldığı dersi tutan bir tablo türet (bölümü NULL olan S7 dışarıda): enr(stu_id, dept_name, course_id), 13 satır. Tek FD: stu_id→dept_name\text{stu\_id} \to \text{dept\_name}.

Şimdi bunu yanlış yerden bölelim:

CREATE TABLE r1 AS SELECT DISTINCT stu_id, dept_name FROM enr;    -- 5 satır
CREATE TABLE r2 AS SELECT DISTINCT dept_name, course_id FROM enr; -- 10 satır
SELECT COUNT(*) FROM r1 NATURAL JOIN r2;
18

13 satırlık tablo 18 satır olarak geri geldi. Fazlalığı EXCEPT ile görebilirsin:

SELECT stu_id, dept_name, course_id FROM r1 NATURAL JOIN r2
EXCEPT SELECT * FROM enr;
stu_iddept_namecourse_id
S2CSCS305
S2CSMA101
S5CSCS201
S5CSCS305
S5CSMA101

Bu satırlara sahte satır (spurious tuple) denir. Neden sadece CS? Join dept_name üzerinden yapılıyor ve CS’de üç öğrenci var (S1, S2, S5). r2, “bir CS öğrencisi bu dersi aldı” bilgisini tutuyor ama hangi öğrenci olduğunu kaybetmiş. EE’de ve MATH’te tek öğrenci olduğu için orada karışıklık çıkmıyor.

TUZAK · “kayıplı” satır kaybetmek demek değil. Kayıplı ayrıştırmada join daha fazla satır üretir. Kaybedilen şey bilgi: hangi satırın gerçek olduğunu artık bilemezsin.

Doğru bölme: r1(stu_id, dept_name) ve r3(stu_id, course_id). Kesişim stu_id, ve stu_id→dept_name\text{stu\_id} \to \text{dept\_name} olduğu için stu_id r1’in anahtarı. r1 NATURAL JOIN r3 tam 13 satır verir, EXCEPT sonucu boş.

İkili test (binary decomposition)

RR‘yi R1R_1 ve R2R_2‘ye bölüyorsan, ayrıştırma ancak ve ancak şu FD’lerden biri F+F^+‘da ise kayıpsızdır:

R1∩R2→R1ya daR1∩R2→R2R_1 \cap R_2 \to R_1 \qquad \text{ya da} \qquad R_1 \cap R_2 \to R_2

Yani kesişim, parçalardan birinin süper anahtarı olmalı. Hesap: kesişimin closure’ını al.

R(A,B,C,D)R(A,B,C,D), F={A→B, C→D}F = \{A \to B,\ C \to D\}:

AyrıştırmaKesişimClosureSonuç
(A,B), (A,C,D)A{A}+=AB⊇R1\{A\}^+ = AB \supseteq R_1kayıpsız
(A,B,C), (C,D)C{C}+=CD⊇R2\{C\}^+ = CD \supseteq R_2kayıpsız
(A,B), (C,D)boşboşkayıplı
(A,B,D), (B,C)B{B}+=B\{B\}^+ = Bkayıplı

Üç ve daha fazla parça: chase testi

İkili test sadece iki parça için. Daha fazlası için tablo (tableau) yöntemi:

  1. Sütunlar R’nin öznitelikleri, her parça bir satır.
  2. Satırda parçanın içerdiği sütunlara a, diğerlerine b (satıra özel) yaz.
  3. Her X→YX \to Y için: X sütunlarında aynı olan iki satırın Y değerlerini eşitle (biri a ise ikisi de a olur).
  4. Değişiklik bitene kadar tekrarla. Tamamen a’dan oluşan bir satır çıkarsa kayıpsız.

Çözümlü örnek. R(A,B,C,D,E)R(A,B,C,D,E), F={A→B, C→D, BD→E}F = \{A \to B,\ C \to D,\ BD \to E\}, parçalar (A,B), (C,D), (A,C,E).

         A    B    C    D    E
R1(AB)   a    a    b    b    b
R2(CD)   b    b    a    a    b
R3(ACE)  a    b    a    b    a

A -> B : R1 ve R3 A'da eşit  → R3.B = a
C -> D : R2 ve R3 C'de eşit  → R3.D = a
R3     : a    a    a    a    a      → KAYIPSIZ

Aynı F ile (A,B), (C,D), (B,D,E) denersen hiçbir FD uygulanamaz (A’da ya da C’de eşit iki satır yok, BD’de eşit iki satır yok) ve tamamen a satırı oluşmaz: kayıplı. Bir sezgi (kural değil): ilk örnekte kazanan satır, aday anahtar AC’yi içeren R3 oldu. İkinci örnekte A ile C’yi birlikte tutan parça yok.

Bağımlılık koruma (dependency preservation)

FiF_i, F+F^+‘nın RiR_i‘ye izdüşümü (projection) olsun: F+F^+‘daki, tüm öznitelikleri RiR_i içinde olan FD’ler. Ayrıştırma koruyucudur eğer (F1∪F2∪… )+=F+(F_1 \cup F_2 \cup \dots)^+ = F^+. Pratik test: F’deki her X→YX \to Y için XX‘in closure’ını sadece izdüşüm FD’leriyle al; Y çıkıyorsa korunuyor.

Örnek 1. R(A,B,C,D)R(A,B,C,D), F={A→B, B→C, C→D}F = \{A \to B,\ B \to C,\ C \to D\}, parçalar (A,B), (A,C), (C,D).

İzdüşümler: A→BA \to B, A→CA \to C, C→DC \to D. Bu kümeyle {B}+={B}\{B\}^+ = \{B\}: B→CB \to C kaybolur. Ayrıştırma kayıpsız ama koruyucu değil. Parçaları (A,B), (B,C), (C,D) seçseydin üç FD de bir parçada olurdu.

Örnek 2. R(A,B,C)R(A,B,C), F={A→B, B→C, C→A}F = \{A \to B,\ B \to C,\ C \to A\}, parçalar (A,B), (B,C). C→AC \to A‘yı içeren parça yok. Ama {B}+=ABC\{B\}^+ = ABC olduğu için AB’ye izdüşümde B→AB \to A, BC’ye izdüşümde C→BC \to B var. C→B→AC \to B \to A: C→AC \to A korunuyor.

TUZAK · izdüşüm sadece F’den alınmaz. Bir parçaya düşen FD’leri bulurken F’deki listeye bakıp “bu FD’nin öznitelikleri parçada mı?” demek yetmez. F+F^+‘dan gelen FD’leri de düşünmen gerekir; bunun yolu parçadaki her alt kümenin closure’ını almak.

BCNF ayrıştırma algoritması

sonuç := {R}
sonuçta BCNF olmayan bir Ri oldukça:
    Ri'de geçerli, X süper anahtar olmayan bir X -> Y bul
    Ri yerine  (X+ ∩ Ri)  ve  Ri − (X+ − X)  koy

Her bölmede kesişim X ve X ilk parçanın anahtarı, o yüzden sonuç her zaman kayıpsız. Koruma ise garanti değil.

Çözümlü örnek. R(A,B,C,D,E)R(A,B,C,D,E), F={A→B, BC→D, D→E}F = \{A \to B,\ BC \to D,\ D \to E\}. A ve C sağda yok, {A,C}+\{A,C\}^+ = ABCDE: tek anahtar AC. Her adımda en kısa ihlal eden sol tarafı seçiyoruz.

ABCDE : A -> B ihlal.  A+ ∩ Ri = AB         →  AB  ve  ACDE
AB    : BCNF
ACDE  : D -> E ihlal.  D+ ∩ Ri = DE         →  DE  ve  ACD
DE    : BCNF
ACD   : izdüşüm AC -> D, AC anahtar         →  BCNF
Sonuç : AB, DE, ACD

Koruma kontrolü: BC→DBC \to D. B ve C aynı parçada değil, izdüşümlerle {B,C}+={B,C}\{B,C\}^+ = \{B,C\}. Kayboldu. İlk adımda D→ED \to E ile başlasaydın farklı bir sonuç bulabilirdin; ayrıştırma tek değildir, sınavda seçtiğin sırayı yaz.

Üniversite örneği: wide(S, N, C, T, G) = (stu_id, stu_name, course_id, title, grade), F={S→N, C→T, SC→G}F = \{S \to N,\ C \to T,\ SC \to G\}. Algoritma CT, NS ve CGS’yi verir: course(course_id, title), student(stu_id, stu_name), takes(stu_id, course_id, grade). Bu sefer üç FD de korunuyor; ders boyunca kullandığımız tabloların neden böyle ayrıldığının cevabı bu.

3NF sentez algoritması (synthesis)

1. F'nin kanonik örtüsünü Fc bul
2. Fc'deki her X -> Y için şema (X ∪ Y) oluştur
3. Hiçbir şema R'nin bir aday anahtarını içermiyorsa, bir aday anahtarı ayrı şema olarak ekle
4. Başka bir şemanın alt kümesi olan şemaları sil

Sonuç hem kayıpsız hem bağımlılık koruyan bir 3NF ayrıştırmasıdır.

Aynı örnek: Fc={A→B, BC→D, D→E}F_c = \{A \to B,\ BC \to D,\ D \to E\} (gereksiz bir şey yok). Şemalar AB, BCD, DE. Hiçbiri AC’yi içermiyor, AC ekle. Sonuç AB, BCD, DE, AC. Chase testi kayıpsız diyor, üç FD de birer parçanın içinde. Bu örnekte parçaların hepsi BCNF bile çıktı; her zaman böyle olmaz.

BCNF mi 3NF mi?

BCNF ayrıştırma3NF sentez
Kayıpsızher zamanher zaman
Bağımlılık korumagaranti değilher zaman
Tekrar (redundancy)FD kaynaklı tekrar yokbiraz kalabilir

Klasik ikilem: tutoring(stu_id, subject, tutor_id), tutor_id→subject\text{tutor\_id} \to \text{subject}, {stu_id, subject}→tutor_id\{\text{stu\_id, subject}\} \to \text{tutor\_id}. BCNF ayrıştırma (tutor_id, subject) ve (stu_id, tutor_id) verir. Kayıpsız ama “bir öğrenci bir konuda tek öğretici” kuralı artık tek tabloda denetlenemiyor. Tasarımcı çoğu zaman 3NF’de kalıp bu kuralı korumayı seçer.

Sık yapılan hatalar

Yanlış düşünceDoğrusu
Kayıplı join satır kaybederFazla (sahte) satır üretir, bilgi kaybolur
Kesişim boş değilse kayıpsızKesişim bir parçanın süper anahtarı olmalı
3+ parçaya ikili testi uygulamakChase tablosunu kullan
FD’yi içeren parça yoksa korunmazİzdüşüm F+F^+‘dan alınır; zincirle türetilebilir
BCNF ayrıştırma bağımlılıkları korurKayıpsızdır ama korumayabilir
3NF sentezde anahtar adımını atlamakHiçbir parça anahtar içermiyorsa kayıplı olabilir
BCNF ayrıştırmanın tek cevabı vardırİhlal seçim sırası farklı sonuç verebilir

Kendini test et

Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.

Soru 1kolay

Let R(A,B,C,D)R(A,B,C,D) with F={A→B, C→D}F = \{A \to B,\ C \to D\}. Is the decomposition R1(A,B)R_1(A,B), R2(A,C,D)R_2(A,C,D) lossless?

Cevabı göster
Yes

İkili test: R1∩R2={A}R_1 \cap R_2 = \{A\}. {A}+={A,B}\{A\}^+ = \{A,B\}, yani A→AB=R1A \to AB = R_1. Kesişim parçalardan birinin süper anahtarı: kayıpsız.

Soru 2kolay

Same RR and FF. Is the decomposition R1(A,B)R_1(A,B), R2(C,D)R_2(C,D) lossless?

Cevabı göster
No (lossy)

Kesişim boş küme. Boş küme hiçbir şeyi belirlemez, birleştirme Kartezyen çarpıma döner ve orijinalde olmayan satırlar üretir. Kayıplı.

Soru 3orta

Same RR and FF. Is R1(A,B,D)R_1(A,B,D), R2(B,C)R_2(B,C) lossless?

Cevabı göster
No (lossy)

Kesişim {B}. {B}+={B}\{B\}^+ = \{B\}: B ne R1R_1'i ne R2R_2'yi belirliyor. İkili test başarısız, kayıplı.

Soru 4orta

Table enr(stu_id, dept_name, course_id) is split into r1(stu_id, dept_name) and r2(dept_name, course_id). S5 is a CS student who took only CS101. The CS students in enr took CS101, CS201, CS305 and MA101. After r1 NATURAL JOIN r2, which spurious courses appear for S5?

Cevabı göster
CS201, CS305, MA101

Birleştirme dept_name üzerinden yapılıyor. S5 → CS, CS → {CS101, CS201, CS305, MA101}. Yani join S5 için dört ders üretir; S5 sadece CS101 almış, diğer üçü sahte satır (spurious tuple). Kesişim dept_name hiçbir parçanın anahtarı değil, o yüzden kayıplı. Bütün tabloda 13 gerçek satır 18'e çıkıyor, 5 sahte.

Soru 5orta

Let R(A,B,C,D,E)R(A,B,C,D,E) with F={A→B, C→D, BD→E}F = \{A \to B,\ C \to D,\ BD \to E\}. Use the chase (tableau) test to decide whether R1(A,B)R_1(A,B), R2(C,D)R_2(C,D), R3(A,C,E)R_3(A,C,E) is lossless.

Cevabı göster
Lossless

Tablo: her parça bir satır, parçadaki sütunlara a, diğerlerine b yaz.
R1: a a b b b, R2: b b a a b, R3: a b a b a.A→BA \to B: R1 ve R3 A'da eşit, R3'ün B'si a olur. C→DC \to D: R2 ve R3 C'de eşit, R3'ün D'si a olur. R3 = a a a a a. Tamamen a olan satır çıktı: kayıpsız.

Soru 6zor

Same RR and FF. Is R1(A,B)R_1(A,B), R2(C,D)R_2(C,D), R3(B,D,E)R_3(B,D,E) lossless?

Cevabı göster
No (lossy)

Tablo: R1: a a b b b, R2: b b a a b, R3: b a b a a.A→BA \to B: A'da eşit iki satır yok. C→DC \to D: C'de eşit iki satır yok. BD→EBD \to E: R1 ve R3 B'de eşit ama D'de farklı. Hiçbir FD uygulanamıyor ve hiçbir satır tamamen a değil. Kayıplı. (Ayrıca A ve C'yi birlikte içeren parça yok; anahtar AC hiçbir parçada değil.)

Soru 7orta

Let R(A,B,C,D)R(A,B,C,D) with F={A→B, B→C, C→D}F = \{A \to B,\ B \to C,\ C \to D\} and the decomposition (A,B)(A,B), (A,C)(A,C), (C,D)(C,D). Is it dependency preserving? If not, which FD is lost?

Cevabı göster
No; B -> C is lost

İzdüşümler: AB'de A→BA \to B; AC'de A→CA \to C; CD'de C→DC \to D. Bu kümeyle {B}+={B}\{B\}^+ = \{B\}, C yok. B→CB \to C hiçbir parçada kontrol edilemiyor ve türetilemiyor: korunmuyor. (Ayrıştırma yine de kayıpsız.)

Soru 8zor

Let R(A,B,C)R(A,B,C) with F={A→B, B→C, C→A}F = \{A \to B,\ B \to C,\ C \to A\}, decomposed into (A,B)(A,B) and (B,C)(B,C). No piece contains both CC and AA. Is C→AC \to A preserved?

Cevabı göster
Yes

İzdüşüm sadece F'deki FD'ler değil, F+F^+'dan gelenler. AB'ye izdüşüm: A→BA \to B ve B→AB \to A (çünkü {B}+=ABC\{B\}^+ = ABC). BC'ye izdüşüm: B→CB \to C, C→BC \to B. Bu kümeyle {C}+\{C\}^+: C→BC \to B, B→AB \to A, A içinde. C→AC \to A korunuyor. Ders: "FD'yi içeren parça yok" demek "korunmuyor" demek değil.

Soru 9zor

Let R(A,B,C,D,E)R(A,B,C,D,E) with F={A→B, BC→D, D→E}F = \{A \to B,\ BC \to D,\ D \to E\}. Decompose RR into BCNF (at each step use the shortest violating left side). Is the result dependency preserving?

Cevabı göster
AB, DE, ACD; not preserving (BC -> D lost)

Anahtar AC. 1) A→BA \to B ihlal, {A}+=AB\{A\}^+ = AB: R → AB ve ACDE.
2) ACDE içinde D→ED \to E ihlal ({D}+=DE\{D\}^+ = DE): DE ve ACD.
3) ACD: tek FD AC→DAC \to D, AC anahtar, BCNF.
Sonuç AB, DE, ACD. BC→DBC \to D: B ve C aynı parçada değil, izdüşümlerle {B,C}+={B,C}\{B,C\}^+ = \{B,C\}. Korunmuyor.

Soru 10zor

Same RR and FF. Apply the 3NF synthesis algorithm.

Cevabı göster
AB, BCD, DE, AC

Kanonik örtü zaten {A→B, BC→D, D→E}\{A \to B,\ BC \to D,\ D \to E\}. Her FD için bir şema: AB, BCD, DE. Hiçbiri aday anahtar AC'yi içermiyor, AC'yi ekle. Biri diğerinin alt kümesi değil, silme yok. Sonuç kayıpsız ve bağımlılıkları koruyor (bu örnekte parçaların hepsi BCNF bile).

Soru 11orta

tutoring(stu_id, subject, tutor_id) has FDs tutor_id -> subject and stu_id, subject -> tutor_id. Give its BCNF decomposition and the FD that is no longer enforceable in a single table.

Cevabı göster
(tutor_id, subject), (stu_id, tutor_id); stu_id, subject -> tutor_id is lost

tutor_id→subject\text{tutor\_id} \to \text{subject} BCNF'yi bozuyor. {tutor_id}+\{\text{tutor\_id}\}^+ = {tutor_id, subject}: bir parça (tutor_id, subject), diğeri (stu_id, tutor_id). Kesişim tutor_id ilk parçanın anahtarı: kayıpsız. Ama stu_id ve subject artık aynı tabloda değil; "bir öğrenci bir konu için tek öğretici" kuralı bir join olmadan denetlenemez. Bu yüzden şema 3NF'de bırakılabilir.

Soru 12zor

Let R(A,B,C,D)R(A,B,C,D) with F={AB→C, C→D, D→A}F = \{AB \to C,\ C \to D,\ D \to A\}. Decompose into BCNF (shortest violating left side first) and name a lost dependency.

Cevabı göster
AD, CD, BC; AB -> C is lost

Anahtarlar AB, BC, BD (3NF ama BCNF değil). 1) C→AC \to A türetilmiş FD ihlal ({C}+=ACD\{C\}^+ = ACD, C tek harfle alfabetik ilk): ACD ve BC.
2) ACD içinde D→AD \to A ihlal (D süper anahtar değil): AD ve CD.
3) AD, CD, BC iki öznitelikli, BCNF.AB→CAB \to C: A ve B aynı parçada değil, izdüşümlerle {A,B}+={A,B}\{A,B\}^+ = \{A,B\}. Korunmuyor. Kayıpsızlık chase ile doğrulanır.

Doğrulama: Kayıplı/kayıpsız birleştirme örneği node:sqlite ile örnek veritabanında NATURAL JOIN ve EXCEPT çalıştırılarak sayıldı; ikili test, chase testi, bağımlılık koruma (FD izdüşümü ile), BCNF ayrıştırma izi ve 3NF sentezi verify/SEN2104/lib.mjs ile hesaplandı (verify/SEN2104/11.mjs, 52 kontrol, 0 hata). BCNF ayrıştırmada her adımda en kısa (eşitse alfabetik ilk) ihlal eden sol taraf seçildi.

Deftere not kartı

İyi ayrıştırma: 1) kayıpsız (lossless join) 2) bağımlılık koruyan (dependency preserving) Kayıplı = join FAZLA satır üretir (sahte/spurious), eksik değil İkili test: R1 ∩ R2 → R1 veya R1 ∩ R2 → R2 (kesişim bir parçanın süper anahtarı) 3+ parça: chase tablosu; her FD ile eşitle; tamamen a satırı çıkarsa kayıpsız Koruma: her FD, parçalara İZDÜŞÜMLERİN birleşiminden türetilebilmeli (F+ izdüşümü!) BCNF algoritması: ihlal eden X -> Y bul; Ri'yi (X+ ∩ Ri) ve Ri − (X+ − X) diye böl; tekrarla BCNF ayrıştırma: hep kayıpsız, koruma GARANTİ DEĞİL 3NF sentez: kanonik örtü; her X -> Y için XY şeması; anahtar yoksa ekle; alt kümeleri sil 3NF sentez: kayıpsız + koruyan, ama biraz tekrar kalabilir Ayrıştırma tek değildir: hangi ihlali önce seçtiğin sonucu değiştirir