Idag
Hur vet vi att vår databas är tillräckligt bra?
I Vad är ett beroende?
I Vad gör man om det blivit fel?
I Vad är en normalform?
I Hur når man de olika normalformerna?
Databaskvalitet(??)
I Det finns metoder för att kontrollera kvaliteten på det man åstadkommit och för att förbättra den om man hittar problem
I Med kvalitet i det här sammanhanget menar man hur enkelt (eller svårt) det är att hitta i databasen och hur enkelt det är att upprätthålla
dataintegritet (försäkra sig om att data enkelt kan hållas korrekt)
I Man vill minimera dubbellagringen (utom vad gäller nyckelvärden i index)
Databaskvalitet . . .
enkelt och lätt att förstå (en sammanslagning av tre tabeller, create view avdvara as select * from försäljning natural join vara natural join avdelning)
avd varunr volym typ våning
möbler 334 332 stol 8
möbler 335 305 stol 8
väskor 336 87 stol 4
möbler 336 95 stol 8
priset är dubbellagring (= redundans) och om vi vill uppdatera så måste vi hitta alla platser där en viss information finns representerad. Vill vi ta bort något kanske det inte går utan att annan viktig information försvinner och vill vi sätta in något nytt kanske det inte går utan att ta reda på mer information.
Databaskvalitet . . .
informativt
avd våning
möbler 8
väskor 4
avd varunr volym
möbler 334 332
möbler 335 305
väskor 336 87
möbler 336 95
varunr typ
334 stol
335 stol
336 stol
till priset av att det inte är lika lätt att förstå men vi kan mata in nya varor utan att tvingas veta vilken avdelning som ska sälja dem, vi kan flytta en avdelning till en annan våning utan att behöva uppdatera alla rader med varor, vi kan lägga till avdelningar utan att tvingas förse dem med varor direkt . . .
Vad är ett beroende?
Hur kommer man då fram till att den mer informativa är bättre?
Vi behöver ett verktyg som låter oss avgöra vilka värden som hör ihop
Om vi betraktar den sammanslagna tabellen avdvara ser vi att varje gång avdelningen ”möbler” dyker upp så har vi alltid samma värde på ”våning”
Vi förväntar att det ska vara så och bestämmer att ”våning” beror av ”avd”
Vi säger att ”våning” är funktionellt beroende av ”avd” och skriver det:
avd → våning
Med motsvarande resonemang kan vi se att varunr → typ och att trots att {avd, varunr} → {volym, typ, våning} så är avd → våning och varunr → typ starkare
Det ger oss också ett verktyg för att ”normalisera”, dela upp tabeller som inte uppfyller de restriktioner som beroendena lägger på datamängden
Vad finns det för normalformer?
Det finns ett stort antal normalformer, några med kryptiska och svårbegripliga definitioner, men man brukar kunna nöja sig med de tre första
Högre NF 5NF 4NF BCNF
3NF
2NF
1NF
Hur resonerar man?
Några exempel från varuhuset:
I En person kan bara arbeta på en avdelning:
namn → avd
I På varje avdelning kan det arbeta mer än en person:
avd 6→ namn
I Man måste veta varunumret för att få reda på en varas typ:
varunr → typ
I Det kan finnas mer än en vara av en viss varutyp:
typ 6→ varunr
I Ett visst företag levererar varor till varje avdelning för sig:
{företag, avd, varunr} → volym
Hur når man de olika normalformerna?
I Man kan använda beroenden för att, utgående från en universell relation, finna en uppdelning som är i 3NF eller högre
I Men vanligast är att man använder beroenden för att analysera varje tabell man får från en modell. Har man minst 3NF så är man nöjd
I För att kunna det behöver man definitionerna för de olika normalformerna
I Det räcker med de tre första, högre normalformer är ganska kryptiskt formulerade
I Man har 1NF om man bara har ett värde i varje kolumn för varje rad
I Man har 2NF om man har 1NF och inget värde är beroende av bara en del av nyckeln (alltså behöver man bara kolla sambandsklasser)
I Man har 3NF om man har 2NF och om dessutom inget värde är beroende av nyckeln via ett annat attribut.
I Vi ska titta på lite bilder och också vässa de här informella ”definitionerna”
1NF
Antag att vi har en tabell över böcker och deras författare
Bok
Titel Författare Datum Språkkod Språk DBTeori Lindqvist 940322 46 Svenska
Dahl
ODBMS Johnson 940312 0 Engelska
Peterson
Tabellen är inte i 1NF! Men om vi gör en rad per upprepat värde
Bok
Titel Författare Datum Språkkod Språk DBTeori Lindqvist 940322 46 Svenska
DBTeori Dahl 940322 46 Svenska
ODBMS Johnson 940312 0 Engelska
ODBMS Peterson 940312 0 Engelska
så är den det
1NF . . .
Man kan i den sista tabellen också se att det inte räcker med bokens titel för att unikt identifiera en rad i tabellen. Ett resonemang kring beroenden i
tabellen ger följande:
I Både ”Titel” och ”Författare” behövs för att identifiera en rad
I Titel → {Datum, Språkkod, Språk}
I Språkkod → Språk
I Språk → Språkkod (!!)
Alla de beroendena visar att tabellen bör delas upp så det endast finns ett beroende i varje resulterande tabell. För detta behövs verktyg (regler)
En av reglerna har vi just sett, vi kan utöka antalet i-termer tills vi hittar ett sätt att unikt identifiera en tabellrad
Man kan också gå motsatt väg. Antag att alla termer är i-termer och tag sedan bort de termer som nås via något beroende
1NF . . . reducera fram en nyckel
I Antag att {Titel, Författare, Datum, Språkkod, Språk} är nyckel
I Börja med de enklaste, t.ex. Språkkod → Språk, så tag bort ”Språk”.
{Titel, Författare, Datum, Språkkod} är kvar
I Titel → {Datum, Språkkod} så tag bort {Datum, Språkkod}. {Titel, Författare} är kvar
I Fler beroenden finns inte så en möjlig nyckel, {Titel, Författare}, har vi hittat
I Har man många beroenden testar man olika reduceringsordning
Kandidatnycklar, primärnycklar och prima attribut
I Det kan hända att man hittar flera möjligheter att unikt identifiera en rad i en tabell.
I Varje uppsättning attribut som duger kallas för en kandidatnyckel
I Hittar man mer än en kandidatnyckel väljer man en som primärnyckel
I Alla attribut som ingår i någon kandidatnyckel kallar man primattribut eller prima attribut med betydelsen att de kan ingå i en primärnyckel
I De är viktiga så man brukar hålla reda på primärnyckel, alla kandidatnycklar och ha en lista över alla prima attribut
Fullständigt funktionellt beroende (FFD)
I Om man har flera attribut (i-termer) i nyckeln kan man kontrollera om alla e-termer är beroende av hela nyckeln eller bara av en del av nyckeln. Ex.:
i varuhusets tabell för försäljning är det klart att man måste veta både avdelning och varunr för att få reda på försäljningsvolymen för en viss vara. Alltså beror volym av både avd och varunr ({avd,varunr} → volym.
Man säger att volym är fullständigt funktionellt beroende av avd och varunr.
I Faktiskt gäller även {avd,varunr,typ} → volym men det är meningslöst att utvidga vänsterledet i ett beroende. Med det utvidgade vänsterledet har vi inte längre ett fullständigt funktionellt beroende.
I Vi kan kontrollera om vänsterledet är minimalt eller inte genom att på försök ta bort ett eller flera attribut ur vänsterledet och se om beroendet med reducerat vänsterled fortfarande gäller
2NF
I En tabell är i 2NF omm den är i 1NF och det varje attribut som inte är primt är fullständigt funktionellt beroende av varje kandidatnyckel
I Låter krångligt men är i själva verket enkelt att kontrollera
I Vi kan strunta i alla primattribut och kontrollera om övriga är FFD av alla nycklar
I Om villkoret inte är uppfyllt så är något attribut beroende av bara en del av någon nyckel och då delar vi tabellen
Titel Datum Språkkod Språk DBTeori 940322 46 Svenska
ODBMS 940312 0 Engelska
Titel Författare DBTeori Lindqvist DBTeori Dahl ODBMS Johnson ODBMS Peterson
3NF
I Om ett attribut är beroende av någon kandidatnyckel i en tabell via ett icke primt attribut så säger vi att det är ett transitivt beroende. Sådana ger också upphov till redundans och uppdaterings-, borttagnings- och insättningsproblem
I En tabell är i 3NF omm den är i 2NF och det inte finns några transitiva beroenden. Finns sådana delar vi tabellen
Titel Datum Språkkod DBTeori 940322 46
ODBMS 940312 0
Språkkod Språk 46 Svenska
0 Engelska
Normalformer
I Här kan vi sluta och vara nöjda
I Vi har förvandlat en orimlig tabell till något generellt användbart:
Titel Författare Datum Språkkod Språk DBTeori Lindqvist 940322 46 Svenska
Dahl
ODBMS Johnson 940312 0 Engelska
Peterson
Till:
Normalformer
Titel Datum Språkkod DBTeori 940322 46
ODBMS 940312 0
Språkkod Språk 46 Svenska
0 Engelska
Titel Författare DBTeori Lindqvist DBTeori Dahl ODBMS Johnson ODBMS Peterson
Funktionella beroenden
Komplexa modeller blir lätt oöverskådliga och även i relativt små modeller händer det att man får in oavsiktliga och dolda beroenden.
Med normalisering kan vi avslöja och eliminera dessa oönskade beroenden Ur diskussionen som varit kan vi härleda regler för funktionella beroenden.
Låt X , Y, Z betyda mängder av attribut
1. För varje attributmängd X gäller alltid att X → Y om Y är en del av X . Detta kallas för trivialt beroende.
2. Om X → Y så X Z → YZ
3. Om X → Y och Y → Z så X → Z
4. Om X → YZ så X → Y (och X → Z) 5. Om X → Y och X → Z så X → YZ