Avatar billede Slettet bruger
22. juni 2011 - 11:40 Der er 14 kommentarer og
2 løsninger

Log tabel - uden at lægge server ned ?

Jeg har brug for at logge hvem som retter data, og hvornår.

Log:
XiD (INT) hvad
UiD (INT) hvem
TiD (TIMESTAMP)

Så langt så godt.

Men nu vil jeg gerne oplyse brugeren om hvornår data blev rettet senest.
- Altså ikke HELE loggen (førend hun aktivt beder om denne) - kun det allerseneste entry:

SELECT UiD,Time FROM Log WHERE XiD=? ORDER BY Time DESC LIMIT 1

Men hvad nu hvis data er blevet rettet en million gange ?
Jeg frygter at den vil hente alle 1 million records op i ram, sortere pr. Time, og først SÅ limit'e til 1

Hvad ville være en mere effektiv måde at bede om dén seneste ?
22. juni 2011 - 12:14 #1
Du vil have den sidste rettelse i den pågældende XID.  Ikke testet, men hvad med;

SELECT UID,MAX(TiD) FROM Log WHERE XiD = ?

(Jeg går ud fra at TiD og Time er det samme)
Avatar billede Slettet bruger
22. juni 2011 - 12:25 #2
Ups ja, Time=TiD : )

Men med MAX(TiD) bliver den vel NØDT til at at læse samtlige 1 million records, før den kan afgøre hvilken der er størst - netop det jeg vil undgå..
Avatar billede mcb2001 Nybegynder
22. juni 2011 - 13:42 #3
rent logisk spørgsmål. Hvordan vil du have at systemet skal kunne fortælle hvad der er "den første" eller "max" uden at tage stilling til hvad den har i listen?

Umiddelbart er den eneste løsning at du kører et index på både XiD og TiD og på denne måde kan bruge en WHERE til at begrænse til kun én Xid, og så bruge MAX eller LIMIT til at vælge den korrekte. Og ja, er der én million poster tilbage efter WHERE, så skal den en million poster igennem...
Avatar billede mediman Nybegynder
22. juni 2011 - 14:14 #4
Læg den seneste entry i en buffer (en tabel for sig).

Dvs. at når der skrives til systemet, så flytter du først data fra bufferen til log-tabellen, og skriver derefter til bufferen.

Det giver så 2 operationer ved skrivning, men til gengæld kan du læse den nyeste entry uden at sortere.

Noget i retning af

INSERT INTO blog (XiD,UiD,TiD) SELECT (XiD,UiD,TiD) FROM buffer
UPDATE buffer SET XiD=$Xid, UiD=$UiD, TiD=$TiD
22. juni 2011 - 14:16 #5
Men at læse en million rækker i en enkelt tabel er vel heller ikke noget der lægger en stor farlig server ned.  Hvis det var en join søgning der involverede en fem-seks tabeller hver med en million rækker ville det nok begynde at kunne mærkes.
Avatar billede Slettet bruger
22. juni 2011 - 14:23 #6
Der er kun de 3 felter i tabellen, og de indgår alle i primary key.
- gør det nogen forskel ?

Eller er der en bedre måde at opnå resultatet på (intet er implementeret endnu) ?

Alternativ (jvf. #4)
Jeg kunne gemme den seneste linje (UiD + TiD) direkte på XiD (foruden i Log).
- så er de klar med det samme. Og jeg behøver kun at kigge i Log, når brugeren beder om mere..
Avatar billede mcb2001 Nybegynder
22. juni 2011 - 14:18 #7
helt enig med #5 - jeg har en logpost i mit drift system med over 200 millioner rækker. Der kan jeg da stadig slå data op (indexeret data dog) på millisekunder...
Avatar billede mcb2001 Nybegynder
22. juni 2011 - 14:26 #8
hvis de tre felter udgør en primærnøgle, så er de indexeret, og så kan du ikke komme nærmere end dette. Og ja, alternativet er at bruge en separat tabel til "sidste" post.
Her ville jeg nok gøre brug af Stored Procedures, og så gennem dette sikre at hvis der gemmes, så gemmes der begge steder. Så kan du også lave en Stored Procedure der henter fra den korrekte tabel, alt efter om der bedes om 1 post eller mange poster.
På denne måde skal dit "program" kun gemme og hente, og ikke have logik til at finde ud af om det er én eller mange og hvor der skal gemmes hvornår.
Avatar billede arne_v Ekspert
22. juni 2011 - 14:30 #9
Jeg er meget skeptisk overfor at bruge en log tabel til dette formaal.

lastmodified og lastmodifiedby i tabellerne synes bedre til dette formaal.
Avatar billede Slettet bruger
22. juni 2011 - 14:37 #10
#8
Ja, det var selvfølgelig en mulighed..
- men det gør jeg "næsten" allerede, bare med en PHP-function.

Så mit "program" bruger faktisk kun en enkelt linje til at hente/gemme XiD.

Nej. Jeg tror jeg skærer igennem her, og benytter aternativet i #7.

Points til jer alle tre: Formidable 10 til hver!
- hvis i lægger et svar: Christian_Belgien, mediman og mcb2001
Avatar billede Slettet bruger
22. juni 2011 - 14:41 #11
Hov, dér kom arne_v
- Og det lyder som om du er enig i alternativet ?
22. juni 2011 - 17:46 #12
Svar fra mig.
Avatar billede arne_v Ekspert
22. juni 2011 - 18:15 #13
Jeg taenkte faktisk paa 2 felter i samme tabel ikke en separat tabel.
Avatar billede Slettet bruger
22. juni 2011 - 18:44 #14
#13 Det var også det jeg nåede frem til.
XiD refererer til 4 forskellige typer data som kan gemmes - i hver deres tabel.
- jeg tilføjer de 2 sidst-gemt-felter til hver af dem.

Og når jeg gemmer, overskriver jeg disse + opretter en record i log-tabellen.

mcb2001 og mediman - lægger i ikke også et svar ?
Avatar billede mediman Nybegynder
22. juni 2011 - 19:30 #15
Jeg samler ikke på points.
Avatar billede mcb2001 Nybegynder
22. juni 2011 - 20:43 #16
hermed et svar
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