En foreign key mot en composite key måste också vara composite. Svårare än så är det inte.
Hur selectar man mot en sammansatt nyckel?
26 svar · 1 543 visningar · startad av CokeLight · sida 2 av 2
Frågan, av CokeLight
Hejsan, Jag har col1, col2, col3 och col1, col2 utgör tillsammans en primärnyckel. Hur skriver man select med JOIN om man vill att SELECT ... FROM ... INNER JOIN.. (PK) = (PK)
Läs frågan i sin helhet →Om du har en primär nyckel som är sammansatt av 2 kolumner, den ena tex ett numeriskt värde och det andra ett varchar(255) värde. Då måste jag implementera 2 foreign key kolumner av samma datatyper i alla child tabeller om jag ska använda composite key?. Det blir rätt många foreign key kolumner man måste skapa på childtabellerna då. På vilket sätt är detta bättre än att använda 1 kolumn som surrogat primärnyckel och 1 foreign key av samma datatyp som primärnyckeln i alla childtabeller?.
Det är bättre på det logiska planet.
1. Databasens nycklar motsvarar faktiska identifieringar, och man gömmer inte de faktiska relationerna bakom intetsägande nycklar.
2. Uppdateringar av tabellerna kan baseras på verklig, tillgänglig data och kräver inte att man först får vetskap om surrogatnyckeln
3. Med en naturlig nyckel som foreign key så har man gett relevant data direkt till foreign-tabellen, och vi kan därmed klara oss utan bastabellen i många fall, i synnerhet om vi har upprätthållen referensintegritet. Med en surrogatnyckel måste vi JOINa in bastabellen.
Därmed inte sagt att man helt och hållet ska undvika surrogatnycklar. En sammansatt nyckel med t.ex. 4-5 kolumner blir snabbt ohanterlig, och då finns det inget annat att göra än att införa surrogat. Det jag vänder mig mot är hur många slentrianmässigt inför surrogatnycklar, bara för att det är så enkelt att slänga på en räknare el. dyl. Referensintegriteten blir sannolikt lidande och man riskerar att addera till databasens komplexitet, i stället för tvärtom.
En surrogatnyckel ska användas för att lösa ett problem, och inte bara för att det går.
1. Databasens nycklar motsvarar faktiska identifieringar, och man gömmer inte de faktiska relationerna bakom intetsägande nycklar.
Jag anser att det är bättre att man låter databasens innehåll vara skilt från databasens konstruktion, vid surrogat nycklar har man helt separerat det man ska spara i databasens med dess konstruktion, eftersom tabellernas relationer utgörs av intetsägande nycklar som inte har något med innehållet man ska spara att göra.
2. Uppdateringar av tabellerna kan baseras på verklig, tillgänglig data och kräver inte att man först får vetskap om surrogatnyckeln
Du måste ändå ha dina naturella nycklar för att kunna göra en update, likaväl som man måste ha surrogatnyckeln för att göra en update, dessa måste ändå upp till applikationen även vad det är för typ av nycklar. Det kommer man aldrig ifrån.
3. Med en naturlig nyckel som foreign key så har man gett relevant data direkt till foreign-tabellen, och vi kan därmed klara oss utan bastabellen i många fall, i synnerhet om vi har upprätthållen referensintegritet. Med en surrogatnyckel måste vi JOINa in bastabellen.
Notera följande scenario: Om du använder tex eposten som primärnyckel i parent tabellen och eposten som foreign key i child tabellen och personen vill ändra sin epost. Då måste man förutom att göra en update på parent tabellens primary key även göra en update på child tabellens foreign key. Och om childtabellen består av 1000 foreign keys som ska uppdateras blir det rätt många updates. Vid surrogat nycklar uppdaterar man bara 1 rad dvs parenttabellen, och eftersom man alltid joinar behöver man inte uppdatera childtabellerna. Därför känns naturella nycklar nästan som en onormaliserad databas men ändå inte.
Och Många databaser har flera generationer av parent->child->grandchild->grandgrandchild och så vidare, hierarkiska relationer. Så för tex grandgrandchild tabellen finns bara grandchild foreign key dvs den tabellen som står 1 steg upp i hierarkin, och om du gör en select som ska ta med child->grandchild->grandgrandchild tabellerna måste du ändå joina in de tabellen/tabellerna som står 2 steg högre upp i hierarkin.
Referensintegriteten blir sannolikt lidande
Varför skulle den bli det om man använder surrogat nycklar?.
En surrogatnyckel ska användas för att lösa ett problem, och inte bara för att det går.
Men du svarade inte riktigt på förra frågan ang. composite nycklar. Om du har en primärnyckel som är sammansatt av 3 kolumner så måste lika många kolumner implementeras i child tabellens foreign keys, vilket betyder 3 extra kolumner. Vid surrogatnycklar behövs bara 1 foreign key kolumn på childtabellen. Är detta bra att så många extra kolumner behövs för att upprätthålla denna designen?.
:D
natas skrev:
1. Databasens nycklar motsvarar faktiska identifieringar, och man gömmer inte de faktiska relationerna bakom intetsägande nycklar.
Jag anser att det är bättre att man låter databasens innehåll vara skilt från databasens konstruktion, vid surrogat nycklar har man helt separerat det man ska spara i databasens med dess konstruktion, eftersom tabellernas relationer utgörs av intetsägande nycklar som inte har något med innehållet man ska spara att göra.
Det är måhända en smaksak, men jag har svårt att se någon generell fördel med att abstrahera databasens innehåll.
natas skrev:
2. Uppdateringar av tabellerna kan baseras på verklig, tillgänglig data och kräver inte att man först får vetskap om surrogatnyckeln
Du måste ändå ha dina naturella nycklar för att kunna göra en update, likaväl som man måste ha surrogatnyckeln för att göra en update, dessa måste ändå upp till applikationen även vad det är för typ av nycklar. Det kommer man aldrig ifrån.
Det resonemanget håller jag inte med om. Kan du elaborera lite?
natas skrev:
3. Med en naturlig nyckel som foreign key så har man gett relevant data direkt till foreign-tabellen, och vi kan därmed klara oss utan bastabellen i många fall, i synnerhet om vi har upprätthållen referensintegritet. Med en surrogatnyckel måste vi JOINa in bastabellen.
Notera följande scenario: Om du använder tex eposten som primärnyckel i parent tabellen och eposten som foreign key i child tabellen och personen vill ändra sin epost. Då måste man förutom att göra en update på parent tabellens primary key även göra en update på child tabellens foreign key.
Om en kolumn är så föränderlig så är den definitivt inte en kandidat till att vara del av en primärnyckel.
natas skrev:
Och Många databaser har flera generationer av parent->child->grandchild->grandgrandchild och så vidare, hierarkiska relationer. Så för tex grandgrandchild tabellen finns bara grandchild foreign key dvs den tabellen som står 1 steg upp i hierarkin, och om du gör en select som ska ta med child->grandchild->grandgrandchild tabellerna måste du ändå joina in de tabellen/tabellerna som står 2 steg högre upp i hierarkin.
Jajamen, det går inte att komma ifrån, oavsett nyckeltyp.
natas skrev:
Referensintegriteten blir sannolikt lidande
Varför skulle den bli det om man använder surrogat nycklar?.
Den reella referensintegriteten upprätthålls inte längre, eftersom den inte är en del av designen. Huruvida man ser till att upprätthålla den ändå är en annan fråga.
natas skrev:
En surrogatnyckel ska användas för att lösa ett problem, och inte bara för att det går.
Men du svarade inte riktigt på förra frågan ang. composite nycklar. Om du har en primärnyckel som är sammansatt av 3 kolumner så måste lika många kolumner implementeras i child tabellens foreign keys, vilket betyder 3 extra kolumner. Vid surrogatnycklar behövs bara 1 foreign key kolumn på childtabellen. Är detta bra att så många extra kolumner behövs för att upprätthålla denna designen?.
Ja, det är bra, på det logiska designplanet. Självklart måste man dock själv ta ställning till om den sammansatta nyckeln blir ett problem, vad gäller design och/eller prestanda.
Debatten om sammansatta nycklar vs. surrogatnycklar är alltid het och kommer nog alltid att drivas. I princip är det helt fel att ge ett kategorisk svar på vilket som är bäst. Min åsikt är helt enkelt att surrogatnycklar är fullständigt nödvändiga men också oerhört överanvända.
intressant diskussion.. hjälpte min förståelse också.. :)
hmm.. men, jag vet inte om jag förstod det rätt, men skulle jag i mitt fall då lägga till epost_typ till även adresser och namn tabellerna enligt nedan?
adresser (ny tabell)
n_id (PK) (key1 - PK) (ex: 1, 2, 3..)
epost_typ (key2 - PK) (ex:D, S)
adress
...
epost (tabellen)
n_id (key1 - PK) (ex: 1, 2, 3..)
epost_typ (key2 - PK) (ex:D, S)
epost
...
namn (tabellen)
n_id (key1 - PK) (ex: 1, 2, 3..)
epost_typ (key2 - PK) (ex:D, S)
snamn
.. är det detta som är svaret alltså eller..? så när jag gör min JOIN så slänger jag på
SELECT epost, namn, ansvarig
FROM namn ibn
INNER JOIN adresser iba ON ibn.n_id = iba.n_id
INNER JOIN epost ibe ON ibe.n_id = iba.n_id
WHERE len(epost) > 0
AND ibn.epost_typ = iba.epost_typ
AND ibe.epost_typ = iba.epost_typ
GROUP BY epost, namn, ansvarig
ORDER BY ibe.epost
också..? (taget ur luften då men nåt sånt..?)
Nej, du behöver inga foreign keys till epost-tabellen. Strukturen var helt rätt från början.