Avatar billede larsjansen Nybegynder
20. januar 2010 - 18:01 Der er 18 kommentarer og
1 løsning

Hjælp til simpel kode

Hej

Jeg har lavet en relation mellem 2 entiteter.

1 - artikel
Har følgende attributer;
artikel_id
overskrift
emne (fungerer som Foreign Key, og kan have en værdi som
svarer til emne_id i entiteten 2 - emne)
forfatter
dato

2 - emne
Har følgende attributer;
emne_id (emne_id'en skal så karakterisere artiklens emne, eks. mad)

Hvis dette indtil videre ser nogenlunde fornuftigt ud, kunne jeg godt tænke mig at høre et bud på en SQL/php kode, hvorved jeg kunne få emne attributten (den Foreign Key) til at kalde på emnet mad, i entiteten emne?

Er det nogenlunde rigtigt? Eller?
Hjælp påskønnes meget!
Avatar billede claes57 Ekspert
20. januar 2010 - 18:45 #1
Avatar billede larsjansen Nybegynder
20. januar 2010 - 18:53 #2
Hej Claes

Tak for dit input!
Kan dog ikke helt udlede et svar af dit link :)
Kunne du have lyst til kort at sætte det i perspektiv til mine 2 tabeller?

Jeg er meget ny på området...
Avatar billede claes57 Ekspert
20. januar 2010 - 19:15 #3
så går vi fra
SELECT column_name(s)
FROM table_name1
INNER JOIN table_name2
ON table_name1.column_name=table_name2.column_name
til
SELECT *
FROM artikel
INNER JOIN emne
ON artikel.emne=emne.emne_id

men der skal nok en
WHERE xxx=yyy (fx forfatter='Peter')
med for at vælge en speciel type.

og så lad være med at kalde et felt (emne) for det samme som en tabel - det vil bare forvirre dig, når du læser koden.
20. januar 2010 - 20:17 #4
claes57, jeg er ikke uenig i hvad du siger, men det er ikke et akkurat svar paa spoergsmaalet foreign key.  Foreign key er kun indirekte relateret til join, det er primaert et redskab til at sikre referentiel integritet, sikre at dataerne i tabellerne svarer til hinanden.  Hvis larsjansen vil at tabellen Emne indeholder alle de emner der er 'tilladte' saa skal han sikre sig mod at brugere i tabellen artikel indsaetter et emne_id som ikke findes i tabellen Emne.  Syntaksen er:

CREATE TABLE Artikel(artikel_id.... emne_id .... Foreign Key(emne_id) references Emne(emne_id)

Hvis larsjansen vil udvide samlingen af emner saa skal han foerst fylde de nye emner i Emne, derefter kan man i Artikel lave referencer til disse emner.  Hvis nogen af uvidenhed eller som fejl proever at indsaette en emnereference i Artikel som ikke findes i Emne saa afviser systemet det direkte.

Man kan sagtens lave Join soegninger uden der er foreign keys, men med de rette foreign keys paa plads vil soegningerne give de forventede resultater.
Avatar billede larsjansen Nybegynder
20. januar 2010 - 20:34 #5
Puuha

Sikke noget jeg har rodet mig ud i :)
Jeg er ikke sikker på jeg forstår det :)
Forstår knap hvad jeg selv skrev.

Nuvel, jeg havde ellers allerede createt et table;

CREATE TABLE `artikel` (

`artikel_id`     INT        ( 6 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`overskrift`    VARCHAR    (32) CHARACTER SET latin1 COLLATE latin1_danish_ci NOT NULL,
`emne`        VARCHAR    ( 32 ) CHARACTER SET latin1 COLLATE latin1_danish_ci NOT NULL ,
`forfatter`     VARCHAR    ( 32 ) CHARACTER SET latin1 COLLATE latin1_danish_ci NOT NULL ,
`dato`        DATE NOT NULL

)

Er det forkert?
Avatar billede larsjansen Nybegynder
20. januar 2010 - 21:24 #6
http://img163.imageshack.us/img163/3321/illustration.png

Sådan ser mine 2 entiteter ud, sammen med dataordbogen..

Giver det et bedre overblik?

Jeg vil gennem en SQL syntaks, hente oplysninger om hvilket emne en artikel er, via entiteten artikel.

Kan det lade sig gøre?
Avatar billede larsjansen Nybegynder
20. januar 2010 - 21:25 #7
FK (Foreign key) skulle så referere til emne_id i emne entiteten...
20. januar 2010 - 21:45 #8
larsjansen, enig at fk skal referere til emne_id.  Men saa skal i Artikel tabellen datatypen for emne vaere den samme som for emne_id nemlig INT.  Jeg sad lige og puslede med det samme.  Spoergsmaal, hvilken database program bruger du?  Det ser ud til at mysql slet ikke stoetter foreign key.  Jeg laeste at man skal bruge Engine=InnoDB og det har jeg gjort i nedenstaaende, men alligevel kan jeg indsaette vaerdier der ifoelge den foreign key ikke er tilladte.  For oejeblikket arbejder jeg i Access og der er der fuld support.

Men jeg lavede, for test, en tabel LarsEmne og en tabel LarsArtikel.  Det med character set har jeg ingen forstand paa saa det sprang jeg over, men her er mine skripts:

CREATE TABLE LarsEmne(emne_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, emne VARCHAR(32)) ENGINE=InnoDB;

CREATE TABLE LarsArtikel(artikel_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, overskrift VARCHAR(32), emne INT, forfatter VARCHAR(32), dato DATE, FOREIGN KEY(emne) REFERENCES LarsEmne(emne_id)) ENGINE=InnoDB;

Saa satte jeg tre emner ind i LarsEmne: 

INSERT INTO LarsEmne VALUES('', 'Mad og drikke');
INSERT INTO LarsEmne VALUES('', 'Ryge og rejse');
INSERT INTO LarsEmne VALUES('', 'Rende og hoppe');

Det danner saa emne_id numre 1, 2, og 3.  Saa skulle den foelgende insert i LarsArtikel afvises, men det goer min mysql ikke:

INSERT INTO LarsArtikel VALUES('', 'overskrift1', 4, 'forfatter1', '2010-1-18');

Men saadan er teorien i hvert fald.
Avatar billede larsjansen Nybegynder
20. januar 2010 - 21:56 #9
Herligt stykke arbejde Christian! Det stter jeg pris på.

Jeg er først i dag startet med at rode med databaser, så jeg fatter ikke helt hoved og hale i de forskellige ting.

Jeg har PT. ikke planer om at implementere databasen, og køre den, da jeg blot skal illustrere formålet med databasen, og syntaksen bag... Jeg er slet ikke kommet til at skulle sætte databasen op endnu, det ved jeg ikke hvordan man gør, har heller ikke tid til det eftersom denne opgave afleveres fredag morgen.

Men umiddelbart ser din kode fin ud, jeg håber jeg er i stand til at forklare den i praksis :)
20. januar 2010 - 22:52 #10
Naa, det er noget du skal snakke dig fra.  Saa er "referentiel integritet" et godt "buzzword."  I dit tilfaelde er der en en-til-mange relation mellem Emne og Artikel: Et emne kan forekomme i mange artikler, men en artikel kan kun have et emne, og ydermere skal Artiklens emne vaere et der forekommer i Emne.  Med den foreign key, ligesom database-softwaren ikke maa tillade at et emne bliver indsat i Artikel der ikke er i Emne saa skal softwaren ogsaa soerge for at et emne ikke kan slettes (eller aendres) i Emne saa laenge der er artikler i Artikel med det emne.  Designeren af databasen kan bestemme, hvis et emne skal slettes, om brugeren foerst skal slette artikler med emnet et for et og saa slette emnet i Emne eller om "cascade" er tilladt.  Det vil sige at softwaren sletter emnet i Emne og samtidig sletter alle artikler med det emne.  Saa hedder koden "FOREIGN KEY(emne) REFERENCES Emne(emne_id) ON DELETE CASCADE".  Paa den maade bevares den referentielle integritet ogsaa.  Der er ogsaa en ON UPDATE CASCADE saaledes at en aendring i et emne resulterer i en aendring af emnet i alle relevante artikler.

Under alle omstaendigheder held og lykke med din eksamen (eller hvad det er.)

Jeg oprettede dette som svar idet du angiver at jeg har svaret paa hvad du spurgte om.  Saa afslutter du maaske spoergsmaalet.
Avatar billede larsjansen Nybegynder
20. januar 2010 - 22:59 #11
Det har været en stor hjælp!
Tak for din tid og tålmodighed!

Ja, det er en eksamen :) Så må vi se om min model holder tæt.

Jeg accepterer selvf. dit svar nu ja!
Tak igen!
21. januar 2010 - 08:53 #12
Lige en ting mere, det slog mig at du i indlaeg #6 sagde: "Jeg vil gennem en SQL syntaks, hente oplysninger om hvilket emne en artikel er, via entiteten artikel."  Ved at oprette en foreign key henter du ikke nogen oplysninger.  Oplysningerne henter du med dit join query (som claes67 forklarede.)  Foreign key laver du for at sikre at tabellerne svarer til hinanden saaledes at oplysningerne er paa plads naar der skal soeges.  Hvis der ikke var forign key fra Artikel til Emne kunne du risikere at nogen havde puttet et emne i Artikel der ikke bestod i Emne saaledes at en soegning paa det emne ikke ville give noget resultat.
Avatar billede larsjansen Nybegynder
21. januar 2010 - 11:51 #13
Altså

Jeg er nået frem til følgende;
Jeg vil have vist forfatteren sammen med artiklens emne.
(entiteten artikel er nu artikler, og emne er emner)

SELECT forfatter,emne
FROM artikler,emner
WHERE artikler.emne_id = emner.emne_id

Det skulle gerne kunne klare den handling ikke?
21. januar 2010 - 12:30 #14
Det ser helt rigtigt ud.

Hvis du vil forvirres (ellers skip de foelgende) saa er der en anden metode til at opnaa det samme, med JOIN.  Den metode er tit mere overskuelig naar det kommer til komplicerede soegninger der involverer flere tabeller:

SELECT forfatter, emne
FROM artikel
JOIN emner ON artikel.emne_id = emner.emne_id

Begge disse queries giver dig en komplet oversigt over alle artikler og deres emner.  Hvis du vil have en mere begraenset oversigt, for eksempel over artikler af forfatteren Klodshans, skriver du enten:

SELECT forfatter,emne
FROM artikler,emner
WHERE artikler.emne_id = emner.emne_id AND forfatter = 'Klodshans'

eller:

SELECT forfatter, emne
FROM artikel
JOIN emner ON artikel.emne_id = emner.emne_id
WHERE forfatter = 'Klodshans'

Og vi snakker stadig teori.  Hvis du vil benytte en bestemt database skal du holde regning med de forskellige begraensninger.  For eksempel Access vil ikke acceptere JOIN men insistere paa at specificere INNER JOIN, LEFT JOIN, etc.  Der findes forskellige JOIN typer alt eftersom precis hvad man vil opnaa.  I simple tilfaelde som dit er det INNER JOIN eller blot JOIN som de fleste database systemer accepterer.  Jeg naevner det blot saa det ikke kommer bag paa dig hvis nogen til eksamen begynder at snakke om INNER JOIN.
Avatar billede larsjansen Nybegynder
21. januar 2010 - 12:54 #15
Fantastisk :) Det er guldkorn for mig.
Jeg sidder nu med 1 sidste problem.

Jeg kan ikke se hvilken normaliseringsform jeg har gang i.
Ville umiddelbart sige 1. normaliseringform, men har en bekendt som siger mig imod.

Kan du se/argumentere for hvilken form du/jeg har anvendt?
Avatar billede larsjansen Nybegynder
21. januar 2010 - 13:13 #16
Og skal det ikke være

SELECT forfatter, emne
FROM artikel
JOIN emner ON artikler(!).emne_id = emner.emne_id

?

Da den nu hedder artikler i stedet for artikel.
I know, forvirrende at jeg lavede det om.
Men var nødt til at omdøbe entiteterne så jeg nemmere kunne holde styr på hvad der var entitet og attribut
21. januar 2010 - 15:04 #17
Nu begynder det at blive grove loejer - du vil have mig til at taenke saa jeg risikerer hovedpine og at finde boeger frem der var daekket af stoev saa jeg risikerer at faa astma.  Men ....

Lad os forestille os at du havde lavet en database der bestod af en tabel med denne struktur (jeg forkorter "forfatter" til "f" for at have det paa en linie):

artikel:
id emne f-fornavn, f-efternavn, f-bopael
                                gade nr by

altsaa vaerdien af feltet f-bopael er selv en tabel med tre kolonner, en saakaldt gentagende gruppe. 

Denne database ville overhovedet ikke vaere normaliseret.  Men hvis du laver en saerskilt tabel for adresse med tre kolonner gade, nr, og by (og maaske en fjerde kolonne for adresse_id) og saa laver en fremmednoegle fra forfatter til adresse saa er du foerste normalform.

Men lad os nu antage at der er en forfatter der hedder Klodshans Jensen som har skrevet syv artikler.  For de syv artikler siger tabellen ikke alene at Klodshans er forfatter men ogsaa at han hedder Jensen til efternav.  Oplysningen at Klodshans og Jensen hoerer sammen forekommer derved adskillige gange, kaldet redundancy (maaske noget andet paa dansk).  At det er spild af database plads er det mindste problem, det giver ogsaa risiko for ved en artikel at komme til at skrive Klodshans Hansen, og saa der der fejl i databasen.  Saa man kan fjerne redundancyen ved at lave en saerskilt tabel for forfatter med tre kolonner, forfatter_id, fornavn, og efternavn.  Tabellen artikel indeholder saa kun forfatter_id med fremmednoegle til forfattertabellen.  Saa indeholder databasen kun paa et sted oplysning om en forfatters navn og efternavn. 

Afhaengig af hvad slags redundancy man fjerner (teorien pensler det ud) kommer man til anden eller tredje normale.  Saa bestaar der ogsaa en Boye-Codds normale og en fjerde og en femte normale hvor forskellige typer multiple- og kombinerede redundancies fjernes.  Men det er special kendskab som jeg vil anse ligger udenfor den nuvaerende opgave.

Hvis du skal fortaelle hvilken normale din database er i saa vil jeg foreslaa svaret:  "Tredje normale fordi der ikke er nogen gentagne grupper (tabeller i tabeller) og al redundancy er fjernet."  Og saa kan du, hvis du vil vaage dig ud paa det dybe vand, sige:  "Fordi databasen er saa begraenset og ukompliceret tilfredsstiller den i princippet ogsaa Boye-Codds normale og fjerde og femte normale."
21. januar 2010 - 15:11 #18
Tilfoejelse:  I det foregaaende indlaeg smuttede "gade nr by" for langt til venstre.  De skulle have staaet under f-bopael.

Og saa ville jeg have skrevet, men glemte det, at antagelsen er at din forfatter kolonne i artikel indeholder et enkelt navn paa forfatter fordi fokus er paa artikel og ikke paa forfatter.  Hvis du vil udvide databasen saa du fortaeller mere om forfatterne maa du, for at forblive i 3. normale, lave en saerskilt tabel for forfatter og bruge forfatter_id i tabellen artikel og med fremmednoegle til forfatter tabellen.
Avatar billede larsjansen Nybegynder
21. januar 2010 - 15:19 #19
Hehe, ja det er noget af det gode gamle jeg fandt frem :)

"Hvis du skal fortaelle hvilken normale din database er i saa vil jeg foreslaa svaret:  "Tredje normale fordi der ikke er nogen gentagne grupper (tabeller i tabeller) og al redundancy er fjernet.""

Tabeller i tabeller? Den forstår jeg ik.
Men ellers giver alt det andet du skrev god mening!
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester