Quiz 2

18 - Decomposition (Lossless & Dependency-Preserving)

1788 words
9 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# 18 - Decomposition (Lossless & Dependency-Preserving) ## 🎯 Learning Objectives After reading this topic, you will be able to: - Explain lossless vs. lossy decomposition - Test whether a decomposition is lossless - Test whether a decomposition preserves dependencies - Apply the 3NF synthesis algorithm ## 📋 Prereq...

18 - Decomposition (Lossless & Dependency-Preserving)

🎯 Learning Objectives

After reading this topic, you will be able to:
  • Explain lossless vs. lossy decomposition
  • Test whether a decomposition is lossless
  • Test whether a decomposition preserves dependencies
  • Apply the 3NF synthesis algorithm

📋 Prerequisites

📖 Core Content

18.1 Intuition: Splitting Relations Correctly

When you decompose a relation (split it into smaller tables), two things can go wrong:
  1. Lossy join: When you join the decomposed tables back, you get MORE rows than the original (spurious tuples)
  2. FD loss: The decomposed tables don't allow checking all original FDs, so updates could violate constraints A GOOD decomposition must be:
  • Lossless: The natural join of the projections must equal the original relation
  • Dependency-preserving: All original FDs can be checked on the decomposed relations
Why This Matters: A bad decomposition is WORSE than no decomposition — it can silently produce wrong results.

18.2 Lossless Join Decomposition

Definition: Decomposition of R into R₁, R₂, ..., Rₙ is lossless if:
R=R1R2...RnR = R₁ \bowtie R₂ \bowtie ... \bowtie Rₙ
For binary decomposition (RR1,R2R \rightarrow R₁, R₂): The decomposition is lossless iff:
R1R2R1 or R1R2R2R₁ \cap R₂ \rightarrow R₁ \text{ or } R₁ \cap R₂ \rightarrow R₂
(Where \rightarrow means functional dependency.) Chase test (general case): A systematic method to check lossless join.

18.3 Testing Lossless Join (Binary)

Algorithm:
  1. Check if R1R2=RR₁ \cup R₂ = R (all attributes preserved)
  2. Check if R1R2R₁ \cap R₂ \neq \emptyset (there's some common attribute)
  3. Check if R1R2R1R₁ \cap R₂ \rightarrow R₁ or R1R2R2R₁ \cap R₂ \rightarrow R₂ If all three conditions hold, the decomposition is lossless.

Worked Example

R(A,B,C,D,E)R(A, B, C, D, E) with F={ABC,CD,BE}F = \{AB \rightarrow C, C \rightarrow D, B \rightarrow E\} Decomposition 1: R1(A,B,C)R₁(A, B, C), R2(D,E)R₂(D, E)
  • R1R2={A,B,C,D,E}=RR₁ \cup R₂ = \{A, B, C, D, E\} = R
  • R1R2=R₁ \cap R₂ = \emptyset
  • Lossy! Decomposition 2: R1(A,B,C,D)R₁(A, B, C, D), R2(B,E)R₂(B, E)
  • R1R2={A,B,C,D,E}=RR₁ \cup R₂ = \{A, B, C, D, E\} = R
  • R1R2={B}R₁ \cap R₂ = \{B\} \neq \emptyset
  • {B}+\{B\}^+ using F: {B} → BEB \rightarrow E → {B, E}. Not all of R₁ or R₂.
  • But check: Does BR2B \rightarrow R₂? R₂ = {B, E}. {B}+\{B\}^+ = {B, E} = R₂! Yes!
  • Lossless!

18.4 Dependency Preservation

Definition: A decomposition preserves dependencies if the union of all FDs that can be verified on the decomposed relations is equivalent to the original FD set. Testing: For each FD XYX \rightarrow Y in FF:
  1. Compute X+X^+ using only FDs that can be checked on the decomposed relations
  2. If YX+Y \subseteq X^+, the FD is preserved
  3. All FDs must be preserved for the decomposition to be dependency-preserving Simpler approach: For each relation RiR_i, project the FDs onto RiR_i (keep only FDs where both sides are in RiR_i). If the union of these projected FDs is equivalent to FF, the decomposition preserves dependencies.

Worked Example

R(A,B,C)R(A, B, C) with F={AB,BC}F = \{A \rightarrow B, B \rightarrow C\} Decomposition: R1(A,B)R₁(A, B), R2(A,C)R₂(A, C) FDs on R1R₁: ABA \rightarrow B FDs on R2R₂: None (A and C have no direct FD, only transitive) Can we derive BCB \rightarrow C from {AB}\{A \rightarrow B\}? No! So this decomposition is NOT dependency-preserving. Better decomposition: R1(A,B)R₁(A, B), R2(B,C)R₂(B, C)
  • FDs on R1R₁: ABA \rightarrow B
  • FDs on R2R₂: BCB \rightarrow C
  • All original FDs are preserved. ✓

18.5 Lossless vs. Dependency-Preserving

Key insight: These two properties are INDEPENDENT:
  • A lossless decomposition may NOT preserve dependencies
  • A dependency-preserving decomposition may be lossy Goal: Get BOTH properties. | BCNF | Guarantees lossless | Does NOT guarantee dependency preservation | | 3NF | Guarantees lossless | Guarantees dependency preservation |

18.6 3NF Synthesis Algorithm

This algorithm produces a lossless, dependency-preserving 3NF decomposition:
sql
Input: R (relation), F (FD set)
Output: 3NF decomposition
1. Compute canonical cover F_c of F
2. For each FD X → Y in F_c, create relation R_i = X ∪ Y
3. If no relation contains a candidate key of R, add a relation with a candidate key
4. Optimize: Merge any two relations where one is a subset of the other
5. The resulting decomposition is lossless and dependency-preserving

Worked Example

R(A,B,C,D)R(A, B, C, D) with F={AB,AC,BD}F = \{A \rightarrow B, A \rightarrow C, B \rightarrow D\} Step 1: Canonical cover. Fc={AB,BD}F_c = \{A \rightarrow B, B \rightarrow D\} (A→C is redundant). Step 2: Create relations for each FD:
  • ABA \rightarrow BR1(A,B)R₁(A, B)
  • BDB \rightarrow DR2(B,D)R₂(B, D) Step 3: Check if any relation contains a candidate key. CK = {A, C}. No relation has {A, C}. Add R3(A,C)R₃(A, C). Step 4: No merges needed. Final 3NF: R1(A,B)R₁(A, B), R2(B,D)R₂(B, D), R3(A,C)R₃(A, C)

18.7 Lossless Join Test (Chase) for Multiple Relations

For more than two relations, use the chase test:
  1. Create a table with one row per relation and columns for all attributes
  2. Fill each cell: If the attribute is in the relation, put a ; otherwise put
  3. Apply FDs: If two rows match on LHS, force equality on RHS
  4. If any row becomes all , the decomposition is lossless

📐 Key Formulas / Concepts

PropertyBinary TestGeneral Test
LosslessR1R2R1R₁ \cap R₂ \rightarrow R₁ or R1R2R2R₁ \cap R₂ \rightarrow R₂Chase test
Dependency-preservingAll FDs checkable on individual relationsProject FDs, check equivalence

⚠️ Common Pitfalls

Pitfall 1: Assuming Lossless Means "No Data Loss"

The Mistake: Thinking lossless means no information is lost. Why It's Wrong: Lossless means the join returns exactly the original relation — no more rows. But you've "lost" the FD constraints that can't be checked on individual relations. Correct: Lossless ≠ dependency-preserving. You need both.

Pitfall 2: Not Checking R1R2=RR₁ \cup R₂ = R

The Mistake: Only checking the FD condition for losslessness. Fix: First verify all attributes are covered: R1R2=RR₁ \cup R₂ = R.

Pitfall 3: Thinking Decomposition Always Improves Design

The Mistake: Decomposing every relation to BCNF regardless of query patterns. Why It's Wrong: Decomposition increases the number of JOINs needed in queries. Sometimes keeping a 3NF relation (with some redundancy) is better for performance than splitting it.

📝 Practice Questions

Q1. What makes a decomposition lossless? State the binary decomposition condition.

Answer
A binary decomposition of R into R₁ and R₂ is lossless iff:
  1. R1R2=RR₁ \cup R₂ = R (all attributes covered)
  2. R1R2R₁ \cap R₂ \neq \emptyset (common attributes exist)
  3. R1R2R1R₁ \cap R₂ \rightarrow R₁ OR R1R2R2R₁ \cap R₂ \rightarrow R₂ (common attributes determine one relation)
If satisfied, joining R₁ and R₂ will return exactly the original R without spurious tuples.

Q2. Check if decomposition of R(A,B,C,D)R(A,B,C,D) with F={AB,BC}F=\{A→B, B→C\} into R1(A,B)R₁(A,B) and R2(C,D)R₂(C,D) is lossless.

Answer
  • R1R2={A,B,C,D}=RR₁ \cup R₂ = \{A,B,C,D\} = R
  • R1R2=R₁ \cap R₂ = \emptyset
Condition 2 fails. The decomposition is lossy.
Even without checking the FD condition, having no common attributes between the two relations means the Cartesian product will produce spurious tuples.

Q3. What does dependency preservation mean? Why is it important?

Answer
Dependency preservation means all original FDs can be checked on the individual decomposed relations — no joins are needed to verify constraints.
Importance: If a decomposition doesn't preserve dependencies, the DBMS must do JOINs to check FDs, which is expensive. Updates on the decomposed relations might violate FDs that can't be checked locally.
Example: If F={AB,BC}F = \{A→B, B→C\} and decomposition is R1(A,B)R₁(A,B), R2(A,C)R₂(A,C), the FD BCB→C can't be checked on either relation alone.

Q4. Apply the 3NF synthesis algorithm to R(A,B,C,D)R(A,B,C,D) with F={AB,CD}F=\{A→B, C→D\}.

Answer
Step 1: Canonical cover. F is already minimal: Fc={AB,CD}F_c = \{A→B, C→D\}.
Step 2: Create relations:
  • ABA→BR1(A,B)R₁(A, B)
  • CDC→DR2(C,D)R₂(C, D)
Step 3: Check for candidate key. CK = {A, C}. Add R3(A,C)R₃(A, C).
Step 4: No merges.
Final 3NF: R1(A,B)R₁(A,B), R2(C,D)R₂(C,D), R3(A,C)R₃(A,C) — lossless and dependency-preserving.

Q5. Is it possible to have a lossless decomposition that doesn't preserve dependencies?

Answer
Yes! These properties are independent. Example:
R(A,B,C)R(A,B,C) with F={AB,BC}F=\{A→B, B→C\}. Decompose into R1(A,B)R₁(A,B) and R2(A,C)R₂(A,C).
  • Lossless? R1R2={A}R₁∩R₂=\{A\}, {A}+={A,B,C}=R1\{A\}^+ = \{A,B,C\} = R₁? Wait, R1R₁ is just {A,B}\{A,B\}. {A}+\{A\}^+ in F = {A,B,C}\{A,B,C\}, so {A}+\{A\}^+ contains R1R₁. ✓ Lossless.
  • Dependency-preserving? BCB→C can't be checked on either R1R₁ or R2R₂ (B not in R2R₂, C not in R1R₁). ✗
This is lossless but NOT dependency-preserving.

Q6. What is the chase test used for?

Answer
The chase test is a general method to check lossless join for decompositions involving more than two relations. It creates a symbolic table tracking which relations can supply which attributes, and uses FDs to deduce equality constraints. If any row becomes entirely marked, the decomposition is lossless.

Q7. Find a lossless, dependency-preserving 3NF decomposition of R(A,B,C,D)R(A,B,C,D) with F={ABC,BD}F=\{A→BC, B→D\}.

Answer
Canonical cover: Decompose ABCA→BCAB,ACA→B, A→C. Fc={AB,AC,BD}F_c = \{A→B, A→C, B→D\}.
Synthesis:
  • ABA→BR1(A,B)R₁(A,B)
  • ACA→C → Already covered? R1R₁ has A,B but not C. Make R2(A,C)R₂(A,C) Actually merge: ABA→B and ACA→C can be combined: R1(A,B,C)R₁(A,B,C)
  • BDB→DR2(B,D)R₂(B,D)
Check candidate key: CK = ? Compute: A⁺ = {A,B,C,D} = R → {A} is a CK. Already covered by R1R₁ (which has A). No need to add extra relation.
Final: R1(A,B,C)R₁(A,B,C), R2(B,D)R₂(B,D) — both in 3NF, lossless, dependency-preserving.

Q8. Why is the 3NF synthesis algorithm preferred over BCNF decomposition?

Answer
The 3NF synthesis algorithm guarantees BOTH lossless join AND dependency preservation. BCNF decomposition guarantees lossless join but may lose FDs.
In practice, if you need to preserve all FDs (which you usually do), 3NF synthesis is the safer choice. If BCNF is achievable while preserving all FDs, it's preferred for its stronger guarantees.

🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.