Relationell databasdesign, FB Teori 7-20 Uppdelning Låt R vara ett relationsschema. R 1, R 2,..., R n är en uppdelning av R om R i = R, i=1,...,n. Dvs. varje R i är en delmängd av R och varje attribut i R förekommer i åtminstone ett delschema R i. Låt F vara en mängd funktionella beroenden på relationsschema R och låt R 1, R 2,..., R n vara en uppdelning av R. Restriktionen av F till R i är mängden F i av alla funktionella beroenden i F + som bara innehåller attribut ur R i. Låt F = F 1 F 2... F n.f är en mängd av funktionella beroenden på R som kan testas effektift (ty bara attribut ur ett schema ingår i varje funktionellt beroende)
Relationell databasdesign, FB Teori 7-21 En nödvändig egenskap för uppdelningar. Förlustfri uppdelning Betrakta Lending schemat R: Lending_schema= (loan_number, amount, customer_name, branch_name, branch_city, assets) Uppdela Lending schema i R 1 : Branch_customer_schema = (branch_name, branch_city, assets, customer_name) och R 2 : Customer_loan schema = (customer_name, loan_number, amount) Alla attribut i det ursprungliga schemat R måste förekomma i uppdelningen (R 1, R 2 ): R = R 1 R 2 Rekonstruera Lending schema m.h.a natural join branch_customer customer_loan Tabellerna i en databas måste kunna joinas korrekt. Leder till Lending + falska tupler och att information försvinner, dvs. informationen om vem som är låntagare i vilken branch. lending b_name b_city assets c_name l_num amount a Åbo 2000 Kalle L-23 50 b T:fors 23999 Kalle L-02 100 c H:fors 16666 Pelle L-11 23 branch_customer b_name b_city assets c_name a Åbo 2000 Kalle b T:fors 23999 Kalle c H:fors 16666 Pelle customer_loan c_name l_num amount Kalle L-23 50 Kalle L-02 100 Pelle L-11 23 branch_customer customer_loan b_name b_city assets c_name c_name l_num amount a Åbo 2000 Kalle Kalle L-23 50 a Åbo 2000 Kalle Kalle L-02 100 a Åbo 2000 Kalle Pelle L-11 23 b T:fors 23999 Kalle Kalle L-23 50 b T:fors 23999 Kalle Kalle L-02 100 b T:fors 23999 Kalle Pelle L-11 23 c H:fors 16666 Pelle Kalle L-23 50 c H:fors 16666 Pelle Kalle L-02 100 c H:fors 16666 Pelle Pelle L-11 23 branch_customer customer_loan b_name b_city assets c_name l_num amount a Åbo 2000 Kalle L-23 50 a Åbo 2000 Kalle L-02 100 b T:fors 23999 Kalle L-23 50 b T:fors 23999 Kalle L-02 100 c H:fors 16666 Pelle L-11 23
Relationell databasdesign, FB Teori 7-22 Branch_customer_schema = (branch_name, branch_city, assets, customer_name) Customer_loan schema = (customer_name, loan_number, amount) Exemplet ovan är en lossy-join uppdelning: Resultatet av att utföra -operationen på delarna ger mera tupler, men mindre information jämfört med den ursprungliga relation som uppdelades. Motsatsen är en förlustfri, lossless-join uppdelning. Exempel på en lossless-join uppdelning: Betrakta en alternativ uppdelning, där Lending_schema uppdelas i Branch_schema = (branch_name, branch_city, assets) Loan_info_schema = (branch_name, customer_name, loan_number, amount) branch_name assets branch_city Om en kund råkar ha lån från flera grenar, så kan vi inte säga vilket lån som hör till vilken gren. branch b_name b_city assets a Åbo 2000 b T:fors 23999 c H:fors 16666 loan_info b_name c_name l_num amount a Kalle L-23 50 b Kalle L-02 100 c Pelle L-11 23 branch loan-info = lending b_name b_city assets c_name l_num amount a Åbo 2000 Kalle L-23 50 b T:fors 23999 Kalle L-02 100 c H:fors 16666 Pelle L-11 23 Varför är den första uppdelningen "lossy" men inte den andra? Branch_customer_schema Customer_loan_schema = { customer_name } Branch_schema Loan_info_schema = { branch_name } Problemet i det första fallet är att assets och branch_city alltid är desamma för en gren, medan customer_name inte funktionellt bestämmer loan_number : Dvs. de gemensamma attributen vid joinen måste funktionellt bestämma den ena delrelationen, dvs. vara en supernyckel för den ena delrel.
Relationell databasdesign, FB Teori 7-23 Mera formellt: Låt R vara ett relationsschema. R 1, R 2,..., R n är en uppdelning av R Låt r vara en relation på R, och låt r i = Π R (r),i = 1, 2,..., n, dvs. uppdelningen ger relationerna r 1, r 2,..., r n. i Då gäller r r i Uppdelningen är lossless-join om inga falska tupler ingår, dvs. r = r i Givet relationsschema R och funktionella beroenden F, så är R = R 1 R 2 lossless om åtminstone en av följande gäller i F: R 1 R 2 R 1 R 1 R 2 R 2 Är BCNF uppdelning förlustfri? Exempel på icke lossless-join uppdelning: Uppdelning av R = (A, B) i R 1 = (A) och R 2 = (B) Π A (r) r r A B a 1 a 2 b 1 Π B (r) Π A (r) Π B (r) A a b r A B a 1 a 2 b 1 b 2 B 1 2
Relationell databasdesign, FB Teori 7-24 Ex.: Vidare uppdelning av Lending schemat: Loan_info_schema = (branch_name, customer_name, loan_number, amount) customer_name, loan_number Loan_info_schema uppdelas i Loan_schema = (branch_name, loan_number, amount) Borrower_schema = (customer_name, loan_number) Uppdelningen är lossless: Loan_schema Borrower_schema = {branch_name, loan_number, amount} {customer_name, loan_number} = { loan_number } Det gäller att loan_number branch_name, amount aug, x x=x loan_number loan_number, branch_name, amount (loan_number + = loan_number branch_name amount ) loan_number Loan_schema dvs. loan_number är kandidatnyckel i Loan_schema: Loan_schema Borrower_schema Loan_schema v.s.b. lending b_name b_city assets c_name l_num amount a Åbo 2000 Kalle L-23 50 b T:fors 23999 Kalle L-02 100 c H:fors 16666 Pelle L-11 23 branch b_name b_city assets a Åbo 2000 b T:fors 23999 c H:fors 16666 loan_info b_name c_name l_num amount a Kalle L-23 50 b Kalle L-02 100 c Pelle L-11 23 borrower c_name l_num Kalle L-23 Kalle L-02 Pelle L-11 loan b_name l_num amount a L-23 50 b L-02 100 c L-11 23
Relationell databasdesign, FB Teori 7-25 En önskvärd egenskap för uppdelningar. Beroende-bevarande uppdelning En uppdelning R 1, R 2,..., R n av ett relationsschema R är beroendebevarande om F = F, dvs. om alla FB i F ingår i någon restriktion av F till R i Att en uppdelning är beroende-bevarande innebär att varje funktionelt beroende i F kan testas i åtminstone en av relationerna i uppdelningen. En uppdelning kan vara beroende-bevarande fastän F F: Låt F = F i, F är en mängd av funktionella beroenden på R som vanligen är olika F, men F + = F + kan gälla. Om så är fallet är varje beroende i F logiskt implicerat av F. det räcker att testa F, ty om F är satisfierat är F det även. Ex.: R = (A, B, C) F = { A B, B C }, F + = { A B, B C, A C} Uppdelning i R 1 = (A, B) med F 1 = { A B} och R 2 = (B, C) med F 2 = { B C}, F = { A B, B C }: uppdelningen är lossless-join: R 1 R 2 = { B } och aug B BC ty (B) + = BC = R 2 under F 2 (B C B BC ) uppdelningen är beroende-bevarande: ty F = F A B kan testas i R 1 och B C i R 2
Relationell databasdesign, FB Teori 7-26 Uppdelning i R 1 = (A, B) med F 1 = { A B} och R 2 = (A, C) med F 2 = { A C}, F = { A B, A C }: uppdelningen är lossless-join: R 1 R 2 = { A }, och A AB = R 1 uppdelningen är ej beroende-bevarande: F F och F + F + A B kan testas i R 1 men B C måste testas i R 1 R 2.
Relationell databasdesign, FB Teori 7-27 Ex.: Uppdelningen av Lending schema är beroende-bevarande: Branch_schema = (branch_name, assets, branch_city) Loan_schema = (branch_name, loan_number, amount) Borrower_schema = (customer_name, loan_number) branch_name assets branch_city loan_number amount branch_name Betrakta varje funktionellt beroende i F + ; visa att det kan testas i (åtminstone) en relation i uppdelningen. branch_name assets branch_city kan testas i Branch_schema loan_number amout branch_name kan testas i Loan_schema I detta exempel är det enkelt att verifiera att uppdelningen är beroende-bevarande ty F = F (tillräckligt villkor för beroende-bevarande). Om testen ovan misslyckas testas för beroende-bevarande med följande test (som beräknar höljet av F och F ): Algoritm för test av beroende-bevarande D = {R 1, R 2,..., R n } är en uppdelning av ett relationsschema R F är mängden av funktionella beroenden på R. beräkna F + for varje schema R i i D do begin F i = restriktionen av F + till R i end F := F i ; beräkna F + if (F + = F + ) then return (true) else return (false)
Relationell databasdesign, FB Teori 7-28 En effektivare test som undviker att beräkna F + : Tillämpa följande procedur på varje funktionellt beroende α β i F: resultat = α while (förändringar i resultat) do for each R i i D t = (resultat R i ) + R i resultat = resultat t Dvs. varje FB α β testas i F genom att använda en modifierad form av attributhölje för att se om det bevaras av uppdelningen. Attributhöljet är m.a.p. de funktionella beroendena i F. Omresultat innehåller alla attribut i β, så bevaras α β. Uppdelningen är beroende-bevarande omm alla beroenden i F bevaras. Observera att i stället för att beräkna restriktionen av F på R i och använda den för att beräkna attributhöljet av resultat, använder vi attributhöljet för (resultat R i ) m.a.p. F och snittar det sedan med R i för att få ett ekvivalent resultat. Denna procedur är snabbare (polynomiell mot exponentiell). Repetition av information I uppdelningen av Lending-schema blir det inget problem med upprepning av information som i Lending-schemat där det är nödvändigt att upprepa branch och assets för varje lån. Uppdelningen separerar gren- och lånedata i två olika relationer och eliminerar därvid upprepning. Den grad av "lack of redundancy" vi kan uppnå representeras av flera normalformer.