Relationell databasdesign Kapitel 7 Relationell databasdesign sid Uppdelning m.h.a. funktionella beroenden 3 Funktionella beroenden - teori 12 Uppdelningsalgoritmer 27 Designprocess 33 Relational oath : "A nonkey field must provide a fact about the key the key the whole key and nothing but the key so help me Codd"
Relationell databasdesign 7-1 Hur skall ett schema för en relationell databas utformas? Målet är att generera en mängd relationsscheman som tillåter att data lagras utan onödig redundans men som samtidigt möjliggör en enkel åtkomst av information. Dvs. en god uppdelning av data i relationsscheman bör hittas. Målet nås genom att utforma scheman i lämplig normalform. En normalform specifiserar krav (vilka typer av begränsningar som får finnas i ett relationsschema) på ett schema. För att kunna avgöra om ett relationsschema är i lämplig normalform eller ej behövs information om den reella värld databasen avbildar. En del av denna information finns i E-R-diagrammet, men mera information om organisationen behövs - begränsningar som ej kan uttrycks i diagrammet. En "bra" samling av relationsscheman Undviker upprepning av data Tillåter representation av all behövlig information Möjliggör kontroll av uppdateringar dvs. kontroll m.a.p. brytande av integritetsbegränsningar Ex.: Lending_schema = (branch_name, branch_city, assets, customer_name, loan_number, amount) Överflödighet: Data för branch_name och assets upprepas för varje lån som branch ger => Minnesutrymme slösas, uppdateringar kompliceras, risken för inkonsistens i DB ökas. null-värden: ingen information om en branch kan lagras om branchen ej givit lån, om ej null-värden tillåts (svåra att hantera).
Relationell databasdesign, Första normalformen 7-2 Första normalformen, 1NF Första normalformen pålägger bara ett mycket grundläggande krav på relationer: Domänerna för alla attribut är atomiska, dvs. betraktas som odivisibla. Icke-atomära domäner kan leda till designer med redundanta datalager (entitetsmängder), som i sin tur lätt leder till inkonsistens i databasen. att information kodas i program (det krävs programmering för att komma åt information) Icke-atomära domäner kan vara användbara i vissa fall varför många moderna databassystem understöder icke-atomära domäner (kap 9) Vad innebär detta?
Relationell databasdesign, Uppdelning m.h.a.fb 7-3 Uppdelning m.h.a. funktionella beroenden Funktionella beroenden (beteckning ) Nycklar, eller mera allmänt funktionella beroenden är begränsningar på databasen som kräver att relationer satisfierar vissa egenskaper. En relation som satisfierar alla sådana begränsningar säges vara legal. Låt R vara ett relationsschema. En delmängd K av R är en supernyckel om inga två tupler kan ha samma värde på attributmängden K. dvs. t 1 t 2 t 1 [K] t 2 [K] eller t 1 [K] = t 2 [K] t 1 = t 2 Def.: Låt R vara ett relationsschema. Låt α, β R. Det funktionella beroendet α βgäller på R, om för varje giltig relation r(r), för alla par av tupler t 1,t 2 i r så att t 1 [α] =t 2 [α], det även gäller att t 1 [β] = t 2 [β]. Dvs. t 1 [α] = t 2 [α] t 1 [β] = t 2 [β] M.a.o, K är en supernyckel för R, om K R, dvs, t 1 [K] = t 2 [K] t 1 [R] = t 2 [R], dvs. t 1 = t 2 Funktionella beroenden kan användas för att uttrycka begränsningar som vi ej kan uttrycka m.h.a. supernycklar. Ex.: Schemat loan_info_schema = (branch_name, loan-number, customer-name, amount) Ett givet lån kan ges åt mera än en person, så loan_number är ej en supernyckel, men de funktionella beroendena loan_number amount loan_number branch_name bör gälla.
Relationell databasdesign, Uppdelning m.h.a.fb 7-4 Funktionella beroenden används på två sätt: 1. För att specificera begränsningar på mängden av legala relationer. Vi skall alltså bara handskas med de relationer som satisfierar en given mängd F av funktionella beroenden. Vi säger då att F gäller på R. 2. För att testa relationer för att se om de (relationerna) är legala under F. Om en relation r är legal under F, säger man att r satisfierar F. Ex.: Betrakta följande relation r. Vilka funktionella beroenden gäller? A C? ja det finns två par av tupler med samma värde på A: de har samma C värde C A? nej ty t.ex. t 4 [C] = t 5 [C] men t 4 [A] t 5 [A] AB D? ja det finns inget par av olika tupler t 1 och t 2 så att t 1 [AB] = t 2 [AB] A BC? nej ty t.ex. t 1 [A] = t 2 [A] men t 1 [BC] t 2 [BC] A B C D a 1 b 1 c 1 d 1 a 1 b 2 c 1 d 2 a 2 b 2 c 2 d 2 a 2 b 3 c 2 d 3 a 3 b 3 c 2 d 4 Ett funktionellt beroende säges vara trivialt om det satisfieras av alla relationer, t.ex. A A. Allmänt kallas ett funktionellt beroende α β trivialt om β α Obs! En instans av en viss relation kan satisfiera ett funktionellt beroende som ej gäller på relationens schema. t.ex. i bankdatabasens exempelinstans gäller customer_street customer_city men eftersom gator kan tänkas ha samma namn i olika städer inkluderar vi ej customer_street customer_city i mängden av funktionella beroenden som skall gälla för customer schemat.
Relationell databasdesign, Uppdelning m.h.a.fb 7-5 I bankexemplet måste åtminstone följande icke-triviala funktionella beroenden alltid gälla: Customer_schema = (customer-name, customer_street, customer_city): customer_name customer_street customer_name customer_city Branch_schema = (branch-name, branch_city, assets): branch_name branch_city branch_name assets Loan_schema = (branch_name, loan-number, amount): loan_number branch_name loan_number amount Borrower_schema = (loan-number, customer-name ): inga FB Account_schema = (account-number, branch_name, balance ): account_number branch_name account_number balance Depositor_schema = (account-number, customer-name): inga FB
Relationell databasdesign, Uppdelning m.h.a.fb 7-6 Boyce-Codd normalform (BCNF), 2NF BCNF eliminerar all redundans som kan uppteckas på basen av funktionella beroenden. Ett relationsschema R är i BCNF om för alla funktionella beroenden på R av formen α β (α, β R) minst en av följande gäller 1. α β är ett trivialt funktionellt beroende (dvs. β α) 2. α är en supernyckel för R Vad innebär detta? En databasdesign är i BCNF om alla relationsscheman är i BCNF. Ex.: Bankexemplet - alla scheman är i BCNF Customer_schema är BCNF ty de icke-triviala funktionella beroenden har customer_name på vänstra sidan (customer_name är en kandidatnyckel). Borrower_schema är i BCNF ty det har inga funktionella beroenden. Customer_schema = (customer-name, customer_street, customer_city): customer_name customer_street customer_name customer_city Branch_schema = (branch-name, branch_city, assets): branch_name branch_city branch_name assets Loan_schema = (branch_name, loan-number, amount): loan_number branch_name loan_number amount Borrower_schema = (loan-number, customer-name ): Account_schema = (account-number, branch_name, balance ): account_number branch_name account_number balance Depositor_schema = (account-number, customer-name):
Relationell databasdesign, Uppdelning m.h.a.fb 7-7 Ex.: Schemat Loan_info_schema = (customer-name, loan-number, amount ) loan_number amount customer_name, loan_number amount är inte i BCNF ty loan_number är inte en supernyckel. Uppdelning av scheman Ett schema som inte är i BCNF kan uppdelas i två: Låt R vara ett schema som ej är i BCNF. Då finns det åtminstone ett icke-trivialt funktionellt beroende α β sådant att α inte är en supernyckel för R. Ersätt R med scheman (α β) och (R - (β - α)) Ex.: Loan_info_schema ersätts av Loan_schema = (loan-number, amount): (α β ) loan_number amount Borrower_schema =(customer-name, loan-number): (R - (β - α)) = (R - β) ty β innehåller inga av α s attribut Loan_schema är i BCNF Borrower_schema är i BCNF Resulterande scheman som ej är i BCNF uppdelas vidare.
Relationell databasdesign, Uppdelning m.h.a.fb 7-8 BCNF och beroendebevarande För att uttrycka konsistensbegränsningar i en databas finns olika metoder primärnyckelbegränsningar funktionella beroenden check-begränsningar assertationer Varje gång databasen uppdateras skall begränsningarna testas. En databas bör utformas så att begränsningar kan testas effektivt. Ett test av ett funktionellt beroende som kan göras genom att bara undersöka en relationskapsmängd är effektivt. Uppdelning i BCNF kan leda till att testning involverar flere mängder dvs. blir ineffektiv. Ex.: Bankexemplet ändras så att en kund tillåts ha flera personliga bankirer, men bara en från en gren En anställd måste nu associeras med en gren. Ändringen kunde implementeras i E-R-diagrammet på följande sätt: ursprunglig version (en bankir per kund) Ett fel i denna design : en kund kan ha flera bankirer från samma gren branch_city branch_city branch-amne assets branch-amne assets branch en anställd tillhör en gren branch customer-id customer_street customer-id customer_street customer_name customer_city customer_name customer_city customer customer cust_ banker type-ass. works_in cust_ banker type-ass. flera bankirer per kund employee employee emploee-id employee_name tel_num emploee-id employee_name tel_num
Relationell databasdesign, Uppdelning m.h.a.fb 7-9 Man borde ha en relationskapsmängd som tvingar fram begränsningen att en kund bara har en bankir per gren: Istället för att lägga till works_in ersätts cust_banker med en ternär relationskapsmängd: och FB cust_banker_branch(customer-id,employee-id, branch_name, type_ass) med customer-id,employee-id cust_banker_branch employee_id branch_name Fördel: en enda relationskapsmängd representerar begränsningen, dvs. den är enkelt att testa. Men cust_banker_branch schemat är ej i BCNF ty employee_id är ej en supernyckel och vi måste upprepa branch_name för varge gång en anställd deltar i en cust_banker_branch relationskap. Uppdelning ger: branch_city (employee-id, branch_name) assets (customer-id, emploee-id, type_ass) branch-amne Dvs. denna design är den samma som den ursprungliga versionen (med works_in som tillåter att en kund har flera bankirer från samma gren) och begränsningen (en kund kan ha högst en personlig bankir från en gren) måste uttryckas med det funktionella beroendet: customer_id, branch_name employee_id branch customer-id customer_street customer_name customer_city customer Dvs. uppdelning i BCNF är ej beroendebevarande Varför ej? cust_ banker_ branch employee type-ass. emploee-id tel_num employee_name
Relationell databasdesign, Uppdelning m.h.a.fb 7-10 Tredje normalformen, 3NF BCNF kräver att alla icke-triviala funktionella beroenden är av formen α β där α är en supernyckel. 3NF är svagare, den tillåter icke-triviala funktionella beroenden vars vänstersida ej är en supernyckel: Ett relationsschema R är i tredje normalform med avseende på en mängd F av funktionella beroenden om det gäller för varje funktionellt beroende i F + av formen α β, där α R och β R, att åtminstone en av följande gäller: 1. α β är ett trivialt funktionellt beroende 2. α är en supernyckelför R 3. Varje attribut A i β α ingår i en kandidatnyckel för R Obs! alla attribut i β α behöver ej ingå i samma kandidatnyckel. Villkor 3 medför att varje schema har en beroendebevarande uppdelning i 3NF. Obs! varje schema som satisfierar BCNF satisfierar även 3NF. Ex.: Betrakta schemat. cust_banker_branch(customer-id, employee-id, branch_name, type_ass) med det FB som medför att det ej är i BCNF employee_id branch_name Är det i 3NF? Dvs. är branch_name en del av en kandidatnyckel?
Relationell databasdesign, Uppdelning m.h.a.fb 7-11 Visa att branch_name ingår i en kandidatnyckel: Vi har de funktionella beroendena employee_id branch_name customer_id, branch_name employee_id ( samt customer_id, employee_id cust_banker_branch eftersom (customer_id, employee_id) är primärnyckel och då även en kandidatnyckel. Finns det andra kandidatnycklar? Är customer_id, branch_name en kandidatnyckel? customer_id, branch_name employee_id gäller För ett visst (customer_id, employee_id) par kan det bara finnas en relationskap i cust_banker_branch ty customer_id, employee_id cust_banker_branch Dvs. (customer_id, branch_name) är en supernyckel ty employee_id branch_name gäller Varken customer_id eller branch_name är supernycklar så (customer_id, branch_name) är en kandidatnyckel. Dvs. employee_id branch_name strider ej mot 3NF regler, dvs. cust_banker_branch är i 3NF gäller Obs! Besvärligt varför man bör använda formella metoder vid resonering om funktionella beroenden, normalformer och uppdelningar av scheman.