Dependency Preservation

A decomposition may result in the inability to test whether a functional dependency holds without computing a join.

Example: Consider relation scheme R = (A, B, C, D), a decomposition tex2html_wrap_inline28 of R, where tex2html_wrap_inline30 = (A, B, C) and tex2html_wrap_inline32 = (A, D). In the decomposition, the functional dependency AB tex2html_wrap_inline34 D cannot be tested for relations tex2html_wrap_inline36 and tex2html_wrap_inline38 without computing tex2html_wrap_inline40 tex2html_wrap_inline42tex2html_wrap_inline44 tex2html_wrap_inline46 .

As computing joins is expensive, we want to avoid computing a join each time a tuple is inserted into tex2html_wrap_inline40 or tex2html_wrap_inline46 (or a tuple in either relation is updated). This is possible if each functional dependency refers to attributes of only one relation.

Given a decomposition tex2html_wrap_inline52 of relation scheme R and a set of functional dependencies F on R, the restriction of F to tex2html_wrap_inline58 is the set tex2html_wrap_inline60 of all functional dependencies tex2html_wrap_inline62 in F such that tex2html_wrap_inline66 and tex2html_wrap_inline68 .

In the previous example, the functional dependency AB tex2html_wrap_inline34 D is not in any tex2html_wrap_inline60 .

Define F' = tex2html_wrap_inline76 . (Note that tex2html_wrap_inline78 in general.) The decomposition tex2html_wrap_inline52 is dependency preserving if tex2html_wrap_inline82 .

In the previous example, F = {AB tex2html_wrap_inline34 D} and F' = {}. The decomposition tex2html_wrap_inline28 is not dependency preserving because AB tex2html_wrap_inline34 D tex2html_wrap_inline94 , but AB tex2html_wrap_inline34 D tex2html_wrap_inline98 .

Naive algorithm for checking dependency preservation:

Inputs: A decomposition D = tex2html_wrap_inline52 and a set of functional dependencies F
Output: true or false

  1. Compute tex2html_wrap_inline106
  2. Compute F'. This is done by finding the restriction of F to each tex2html_wrap_inline58 in D and unioning the results.
  3. Compute tex2html_wrap_inline116
  4. return ( tex2html_wrap_inline118 )

The running time of this algorithm is exponential in the size of F, because computing tex2html_wrap_inline106 takes time exponential in the size of F.

A more efficient algorithm (although one that rejects some decompositions that are actually dependency preserving) is as follows (given the same inputs and computing the same outputs):

  1. Find tex2html_wrap_inline126 , a canonical cover of F.
  2. Find tex2html_wrap_inline130
  3. return ( tex2html_wrap_inline132 )

If this algorithm reports that the decomposition is dependency preserving, then it in fact is dependency preserving because:

  1. tex2html_wrap_inline134 = tex2html_wrap_inline106
  2. For any set of functional dependencies Q, if Q is a proper subset of a canonical cover tex2html_wrap_inline126 (i.e. tex2html_wrap_inline144 and tex2html_wrap_inline146 ), then tex2html_wrap_inline148 by definition of canonical cover. Hence, if tex2html_wrap_inline130 (a subset of tex2html_wrap_inline126 ) does not equal tex2html_wrap_inline126 , then tex2html_wrap_inline156 does not equal tex2html_wrap_inline134 .

Unfortunately, this algorithm does reject some decompositions that are dependency preserving because of the choice of canonical cover (remember that canonical covers are not unique).

Example: Given R = (A, B, C, D, E, G) and F = {CE tex2html_wrap_inline34 A, C tex2html_wrap_inline34 A, C tex2html_wrap_inline34 B, AB tex2html_wrap_inline34 C, A tex2html_wrap_inline34 B, B tex2html_wrap_inline34 A}, we have seen that both tex2html_wrap_inline174 = {C tex2html_wrap_inline34 B, A tex2html_wrap_inline34 B, B tex2html_wrap_inline34 AC} and tex2html_wrap_inline182 = {C tex2html_wrap_inline34 B, A tex2html_wrap_inline34 C, B tex2html_wrap_inline34 A} are canonical covers of F. Given decomposition tex2html_wrap_inline30 = (B, C), tex2html_wrap_inline32 = (A, C) and tex2html_wrap_inline194 = (A, B, D, E, G):

tex2html_wrap_inline174 tex2html_wrap_inline198 tex2html_wrap_inline200 , because B tex2html_wrap_inline34 AC tex2html_wrap_inline204 tex2html_wrap_inline200

tex2html_wrap_inline182 = tex2html_wrap_inline210

However, this algorithm is worth trying because it is much more efficient than the naive algorithm, and spurious rejections are relatively rare for good decompositions.

Note: to test that dependencies hold, the system must test the canonical cover used, NOT the original set of functional dependencies F - because testing F would often require computing joins.

Return to Table of Contents