class R (key a) { attribute integer a; relationship Set<V> RtoV inverse V::VtoR; }; class S (key b) { attribute integer b; relationship Set<V> StoV inverse V::VtoS; }; class T (key c) { attribute integer c; relationship Set<V> TtoV inverse V::VtoT; }; class U (key d) { attribute integer d; relationship Set<V> UtoV inverse V::VtoU; }; class V (key VtoR VtoS VtoT VtoU) { relationship R VtoR inverse R::RtoV relationship S VtoS inverse S::StoV relationship T VtoT inverse T::TtoV relationship U VtoU inverse U::UtoV };V is the type of class that would have been obtained via a pushed-out E/R diagram (i.e., V would be a multiway relationship between R, S, T, and U; after the push-out it would become an entity set with many-one relationships to each of the other four entity sets). Recall that we cannot have multiway relationships in ODL and so we would have employed the push-out construction to render the diagram in ODL.
Closure of A = {A,D} Closure of B = {B} Closure of C = {C} Closure of AB = {A,B,D,E} Closure of AC = {A,C,D,E,B} This gives AC->B Closure of BC = {B,C}Thus, the only FD we can state for S is AC->B.
AB->C DE->C B->D BE->C
a1 b1 c1 a2 b1 c2Decomposing it, we get:
a1 b1 a2 b1and
b1 c1 b1 c2Joining them back gives, instead:
a1 b1 c1 a1 b1 c2 a2 b1 c1 a2 b1 c2i.e., we get two extra tuples. The decomposition is thus lossy. How did we arrive at this example? Notice how we did the decomposition. We performed it based on the assumption that either B->C or B->A holds. We have designed the example (cleverly) to ensure that both of these FDs
a1 b1 c1 a2 b2 c2 a3 b2 c2 a4 b1 c1If you started with the other FD, you will get a solution of a different type.