Just nu i M3-nätverket
Gå till innehåll

Någon som kan hjälpa mig förstå normalisering och kandidatnycklarna?


Martin79

Rekommendera Poster

Försöker förstå mig på normalisering men förstår det inte riktigt.

 

Ett ex:

 

R(A, B, C)

{A, B} --> C

C --> B

 

Först bör man plocka ut kandidatnycklarna (dvs en minimal supernyckel, en supernyckel där man inte kan ta bort några attribut om den fortfarande ska vara garanterat unik). Vilket jag tolkar det som att man inte kan ta bort dessa ifall relationen ska vara oförändrad. Någon får gärna göra en bättre förklaring hur man får fram kandidatnycklarna ut ovanstående exempel.

 

kandidatnycklarna i exemplet är: {A, B} {A, C}

 

A och B hör ihop och för att involvera C relaterar man {A, C}. Borde inte {B, C} fungera lika bra i stället?

 

Sen ska jag komma på vilken normalform det är i. http://sv.wikipedia.org/wiki/Normalform_(databaser)

 

1 NF kan man säga att alla är

2 NF (får det inte finnas några fullständiga funktionella beroenden mellan delar av primärnyckeln och attribut i tabellen. Ett fullständigt funktionellt beroende innebär dels att ett attribut är beroende av ett eller flera andra attribut, och att de attribut som styr beroendet är så få som de kan vara utan att beroendet upphör.) I exemplet ovan, om jag tar bort ett av beroenden så finns det fortfarande en relation och är därför i 2NF

3 NF BCNF och hänger jag riktigt alls med på

 

Någon som vill göra en utförlig förklaring "på svenska" gärna utifrån mitt exempel ovan som är i 3 NF men inte BCNF eftersom i C --> B är inte C kandidatnyckel?

Länk till kommentar
Dela på andra webbplatser

  • 2 veckor senare...

Hej,

det är egentligen en ganska komplicerad matematik bakom normalisering men oftast kan man resonera sig fram.

 

{A,B}->C är ju tydligt. Alla attribut i R(A, B, C) täcks så vi har en supernyckel. Tar vi bort något ur vänsterledet så finns inte längre något stöd för att det fungerar. Om den information du angivit är allt så är det klart att A->C inte gäller och att B->C inte heller gäller. Så {A,B}->C är en kandidatnyckel.

 

C->B ger oss också att {A,C}->{A,B} eftersom vi utökat båda leden med A och A->A gäller trivialt alltid.

Men om {A,C}->{A,B} så vet vi också att {A,C} bestämmer varje del av högerledet, alltså att {A,C}->A och {A,C}->B. Med samma resonemang som tidigare kan vi alltså komma fram till att, eftersom C-> inte gäller så kan inte C vara en kandidatnyckel men {A,C} är det. Kanske enklare att helt enkelt konstatera att då {A,C}->{A,B} och

{A,B}->C så måste ju faktiskt {A,C} duga lika bra som {A,B} och måste alltså vara kandidatnyckel.

 

3 NF då? Jo definitionen av 3NF säger (det finns flera) att vi har 3 NF om alla determinanter (alla giltiga minimala vänsterled) ska antingen vara kandidatnycklar eller vara primattribut (attribut som ingår i någon kandidatnyckel). Och eftersom alla våra attribut A, B och C ingår i någon kandidatnyckel så har vi 3 NF.

 

Den andra definitionen för 3 NF är att vi ska ha 2NF och dessutom inga transitiva beroenden via attribut som inte är primattribut. Men återigen, alla attribut är ju primattribut. Så även enligt den definitionen har vi 3 NF om vi har 2 NF. 2 NF har vi eftersom vi inte kan ta bort något attribut ur någon kandidatnyckel och fortfarande bestämma allt. Ta vi bort det ena eller andra attributet ur någon av de två kandidatnycklarna så är vi körda. Vi kan inte granterat entydigt komma åt varje rad i tabellen längre. Så vi har 2 NF och alltså också 3 NF.

 

BCNF då? Nej, för att ha BCNF så trimmar vi min första definition av 3NF och tar bort "eller vara primattribut". Vi kräver att alla determinanter ska vara supernycklar (vi släpper alltså kravet på kandidatnyckel och ersätter det med supernyckel). Men i C->B är C ingen supernyckel så vi har inte BCNF.

 

Det man vill komma åt i BCNF är just beroenden mellan nyckelattribut som kan ställa till det ibland. Kan man få BCNF? Ja om vi delar R( A, B, C ) i R1( A, C ) och R2( C, B ). Men man ska vara försiktig. Det kan vara bättre att lägga till en "trigger" till databasen och strunta i uppdelningen eftersom man ju faktiskt förlorar informationen om {A,B}->C. Det beroendet ka uppenbarligen inte enkelt uprätthållas med någon automatik vare sig i R1 eller R2. Vi kan göra det i R om vi väljer {A,B} som primärnyckel och antingen skapar en trigger som vägrar insättning om insättningen gör våld på beroendet C->B eller, om vi har stöd för SQL2 i databashanteraren, deklarerar att {A,C}

är en kandidatnyckel.

 

Det skulle se ut så om vi definierar tabellen R (jag hittar på datatyper för A,B och C, påstår att alla är Integer):

CREATE TABLE R (

A Integer,

B Integer,

C Integer,

PRIMARY KEY ( A, B ),

UNIQUE ( A, C )

);

 

(Larvigt, jag fick lägga in extra mellanslag för att inte generera smileys, vet inte hur man stänger av dem)

 

Hoppas detta hjälper något.

Länk till kommentar
Dela på andra webbplatser

Kom på att jag inte riktigt svarat på din fråga om hur man får fram kandidatnycklarna.

 

Ett sätt, om det inte är väldigt mycket attribut är reduktion.

 

R(A,B,C), {A,B}->C, C->B.

 

Reducera {A,B,C} på varje sätt man kan, d.v.s. via alla permutationer av de funktionella beroendena.

Vi har bara två så det blir enkelt

1. eftersom {A,B}->C kan vi ta bort C ur {A,B,C} och får kvar {A,B}. Någon mera reduktion kan inte göras, det enda vi har kvar är C->B och det äller inte i {A,B}. Alltså är {A,B} en kandidatnyckel.

 

2. eftersom C->B tar vi bort B ur {A,B,C} och får kvar {A,C}. Någon mer reduktion kan inte heller nu utföra. A bestämmer inte C och C bestämmer inte A. Alltså är {A,C} också en kandidatnyckel.

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...