Retrieving kandidate-keys
Retrieving the candidate keys: Although more efficient methods exist to retrieve the candidate keys, this is an easy way to get the keys for only few attributes. In principle all different combinations of attributes are tested while impossible combinations are discarded as soon as possible. Original schema: ({A, B, C, D, E, F}, {A → B, C → D E, B → A})
The calculation of the canonical cover ({A, B, C, D, E, F}, {A → B, C → D E, B → A}) for the schema should ease the finding of the candidate-keys as the keys stay the same whereas functional dependencies may be simplified.
The attribute-set {F} isn't a subset of the functional dependencies' attributes and hence part of each candidate-key for sure.
The attribute-set {C} is only part of at least one α-side of a functional dependencies α → β and is hence surely a part of each candidate-key.
Now the remaining combinations of attributes have to be tested (e.g. by building the attribute-closure and discarding all sets of attributes that aren't superkeys and those which are supersets of other superkeys). The found attributes {C, F} have to be part of each candidate-key.
Set of found candidate-keys: {{A, C, F}, {B, C, F}}.
The calculation of the canonical cover ({A, B, C, D, E, F}, {A → B, C → D E, B → A}) for the schema should ease the finding of the candidate-keys as the keys stay the same whereas functional dependencies may be simplified.
The attribute-set {F} isn't a subset of the functional dependencies' attributes and hence part of each candidate-key for sure.
The attribute-set {C} is only part of at least one α-side of a functional dependencies α → β and is hence surely a part of each candidate-key.
Now the remaining combinations of attributes have to be tested (e.g. by building the attribute-closure and discarding all sets of attributes that aren't superkeys and those which are supersets of other superkeys). The found attributes {C, F} have to be part of each candidate-key.
Set of found candidate-keys: {{A, C, F}, {B, C, F}}.