Reputation: 8564
I have the following set of functional dependencies on the relation
schema r(A, B, C, D, E, F )
:
A -> BCD
BC -> DE
B -> D
D -> A
Can anyone show with explanation how to find the candidate keys for this relation ?
Upvotes: 4
Views: 506
Reputation: 476544
Short answer: The candidate keys are (A,F), (B,F) and (D,F).
Like this Wikipedia article says:
The set of all candidate keys can be computed e.g. from the set of functional dependencies. To this end we need to define the attribute closure α+ for an attribute set α. The set α+ contains all attributes that are functionally implied by α.
It is quite simple to find a single candidate key. We start with a set α of attributes and try to remove successively each attribute. If after removing an attribute the attribute closure stays the same, then this attribute is not necessary and we can remove it permanently. We call the result minimize(α). If α is the set of all attributes, then minimize(α) is a candidate key.
So now we only need to put this into practice. Let's start with all attributes α0=(A,B,C,D,E,F). Now we can look whether removing A generates a problem. With α'0=(B,C,D,E,F), α'0+ is (B,C,D,E,F,A) (since D→ A holds). Now by kicking out A permanently and trying to remove B, we will end up with a candidate key.
So now we generated minimize(α0)=α4=(D,F). We could use a brute force approach where in each iteration we iterate over all possible keys we can remove. But this will cost exponential time to generate.
The Wikipedia article however includes a way to generate all candidate keys polynomial in the number of keys and the functional dependencies. The algorithm is defined as:
function find_candidate_keys(A, F) /* A is the set of all attributes and F is the set of functional dependencies */ K[0] := minimize(A); n := 1; /* Number of Keys known so far */ i := 0; /* Currently processed key */ while i < n do foreach α → β ∈ F do /* Build a new potential key from the previous known key and the current FD */ S := α ∪ (K[i] − β); /* Search whether the new potential key is part of the already known keys */ found := false; for j := 0 to n-1 do if K[j] ⊆ S then found := true; /* If not, add if if not found then K[n] := minimize(S); n := n + 1; i := i + 1 return K
So if we run the algorithm, we first have to calculate minimize(A), but the nice thing is: we already did that above. So K[0] = (D,F), n=1 and i=0.
Now we take the while loop and start iterating over all functional dependencies.
This is the end of the first iteration. So K is now K=[(D,F),(A,F),(B,F)]. n=3 and now i=1. So for K[i]=(A,F) we now iterate:
This is the end of the second iteration. So K is now K=[(D,F),(A,F),(B,F)]. n=3 and now i=2. So for K[i]=(B,F) we now iterate:
So at the end K=[(D,F),(A,F),(B,F)]. These are all candidate keys.
Upvotes: 3