Avatar billede snedled Nybegynder
04. februar 2003 - 11:23 Der er 23 kommentarer og
2 løsninger

en til mange

Hej.

Jeg har prøvet at finde "den rigtige måde" at lave et kald til 2 tabeller i mySQL.

Det aktuelle eksempel er at liste alle personer efter hvornår de sidst var på.

tabel 1: person(personID, navn)
tabel 2: logged(personID, dato, tid)

...med "Den rigtige måde" hentydes selvfølgelig til den hurtigste :-D

/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 11:29 #1
I tabel 1 skal personid være primær nøgle
I tabel 2 bør du udvide med en primærnøgle (et
autonummereret felt er fint her), og gøre personid
til et index.
Avatar billede snedled Nybegynder
04. februar 2003 - 11:32 #2
Jeg har lavet en kombineret primærnøgle på personID, dato og tid.
Er det ikke det smarteste?

/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 11:34 #3
Nej, det tager for meget plads og tid. Du vil aldrig søge
efter den præcise kombination.
Avatar billede snedled Nybegynder
04. februar 2003 - 11:42 #4
OK. Det kan godt være at det er det smarteste. Men selvom jeg tilføjer et logID her, har jeg stadig probs med at få det rigtige hentet.

 I virkeligheden ville jeg gerne kunne hente fx. de sidste 3 logs fra hver person, sådan at man kunne få listet:
| navn1 | dato, tid | dato, tid | dato, tid |
| navn2 | dato, tid | dato, tid | dato, tid |

Det jeg hidtil har gjort er at benytte php til at samle flere kald, men er i tvivl om det er det hurtigste....

 Den anden måde, som jeg egentlig spørger om her, har jeg tidligere brugt en MAX() til, men er det egentlig hurtigst?

...er måske lidt uklar?!


/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 11:47 #5
Du bør forøvrigt kombinere dato og tid til ét felt af typen
DATETIME i MySql - så kan du nemmere håndtere at finde den nyeste
dato.

Du siger at du i en udskrift gerne vil have de 3 sidste datoer/tid
for hver person? Hmm, det kan man da ikke lave med én sql-sætning.
Kan man?
Avatar billede arnvig Nybegynder
04. februar 2003 - 11:49 #6
Tabellerne er gode nok, du skal bare joine dem i SQL
Avatar billede arnvig Nybegynder
04. februar 2003 - 11:51 #7
Select *
from person p,logged l
where p.personid = l.personid
Avatar billede arnvig Nybegynder
04. februar 2003 - 11:52 #8
de tre nyeste:

Select top 3 *
from person p,logged l
where p.personid = l.personid
order l.dato,l.tid
Avatar billede snedled Nybegynder
04. februar 2003 - 11:54 #9
Ja, det er jo lidt det spørgsmålet er :-D
Men det kan godt være at det er hurtigere at klare det i PHP'en....

Jeg prøver bare at rykke lidt videre, da jeg aldrig har benyttet mange af de muligheder (jeg tror) mySQL har....
Avatar billede snedled Nybegynder
04. februar 2003 - 11:56 #10
...for lang tid om at skrive :0)
Arnvig > Kan man joine disse 2 i sql? - Eller skal jeg gøre det i PHP'en?
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 12:00 #11
Ja, du bør joine i MySql-en, men den eneste måde du kan
gøre det er så du får alle datoer for alle personer. Og
det er jo lidt usmart. Det er også usmart at tage personerne
én for én og så lave en SELECT med LIMIT 3.

Skal vi se om der kommer nogen med en god idé.
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 12:09 #12
Men det er nemt nok at få den sidste datotid for hver
person i én forespørgsel, forudsat datotid er ét felt.
Avatar billede snedled Nybegynder
04. februar 2003 - 12:15 #13
OK. - Nu har jeg selv fundet en løsning:
SELECT person.*, logged.*
FROM person, logged
WHERE person.personID = logged.personID
GROUP BY person.personID
ORDER BY logged.dato

Denne løser mit umiddelbare problem, og henter alle personerne sorteret efter deres sidste logon(dato).

mht. DATETIME, skal de kun sorteres efter dato, tiden er irrellevant i den forbindelse, det er derfor jeg har lavet den som 2 kolonner..

/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 12:29 #14
Ellers kan du udvide din person med tre felter, som du så opdaterer
ved en ny dato.

update person set dato1=dato2, dato2=dato3, dato3='2003-02-04' where id=117

(sådan ca.) Så har du altid de tre sidste
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 12:33 #15
Nå ja, og teste for om det er en allerede registreret dato er nem:

update person set dato1=dato2, dato2=dato3, dato3='2003-02-04' where id=117 and dato3<>'2003-02-04'

Det generaliserer ikke så nemt, den dag du hellere vil have de
sidste 4 datoer :)
Avatar billede snedled Nybegynder
04. februar 2003 - 12:36 #16
Ja, det overvejer jeg også, men det bryder lidt med normaliseringsreglerne, ikke?

Jeg tror at jeg undlader de 2 andre datoer og nøjes med den sidste.

Erik, du siger at det kræver mere plads og tid at have en kombineret primærnøgle. Vil det sige at det generelt - rent effektivitetsmæssigt - er bedre at have én primærnøgle og så tjekke for dubletter i php'en?

/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 12:41 #17
Hvis du skal checke for dubletter skal man overveje et index
på det der skal checkes for. Men du søger da ikke efter
dubletter på id,dato og tid?

Joh, det er nok ikke så kønt, mit forslag. Alternativet er
jo at have en tabel ved siden af, hvor du indsætter den nye
dato, og så sletter den ældste så der altid er 3. Det generaliserer
nemmere, men er knap så effektivt.
Avatar billede snedled Nybegynder
04. februar 2003 - 13:05 #18
Jeg tjekker ikke på dubletter egentlig, men den samme person kan ikke være logget på samtidig, så den er ihvertfald unik, så tænkte jeg bare at spare en kolonne og lavede istedet de 3 kombinerede. Troede egentlig ikke at de var langtsomme....

Jeg tror at den smarteste måde at hente de tre på er ved at lave "joinet" i PHP'en. På den måde undgås nok alt for unødigt komplicerede løsninger....
- spørgsmålet er bare om det er væsentligt langtsommere på den måde (ved at det er den forkerte kategori til PHP-spørgsmål).

/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 13:09 #19
Hvis du aldrig rydder op i dine data, vil din join, og dit
gennemløb af resultatet blive langsommere med tiden. Derfor
kan det jo godt være hurtigt nok i dag.
Avatar billede snedled Nybegynder
04. februar 2003 - 13:22 #20
Ja det er rigtigt. - Men det kan vel løses ved løbende at rydde op, eller fx slette de ældste logons hver gang en person logger på?
Avatar billede snedled Nybegynder
04. februar 2003 - 13:49 #21
Jeg tror jeg vil lukke sprøgsmålet igen.

Du skal ha' tak for hjælpen Erik. Jeg skal nok vende tilbage hvis jeg har nogle andre underlige problemer..... :-D

Hvis du vil have del i pointne, må du lige lave et svar....

/snedled
Avatar billede erikjacobsen Ekspert
04. februar 2003 - 13:52 #22
Ingen point tak (jeg skal ikke have mig et gratis PRO abonnement)
Avatar billede snedled Nybegynder
06. februar 2003 - 13:31 #23
...hmmm...
Hvad skal jeg så gøre af pointene?

/snedled
Avatar billede erikjacobsen Ekspert
06. februar 2003 - 14:06 #24
Jeg er sådan set ligeglad :)
Avatar billede snedled Nybegynder
06. februar 2003 - 15:14 #25
OK :-D
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