sql >> Database teknologi >  >> RDS >> Mysql

Databaser:Lav en log over handlinger, hvordan håndterer man forskellige referencer?

Det følgende er, hvordan jeg ville gøre det. Jeg har nogle flere kommentarer nederst, efter du har set skemaet.

Log

LogID - unikt log-id

Tid - dato/tidspunkt for begivenheden

LogType - String eller ID

(sidekommentar, jeg ville gå med et id her, så du kan bruge en meddelelsestabel vist nedenfor, men hvis du vil have hurtig og snavset, kan du bare bare en unik streng for hver logtid (f.eks. "Game Started", "Message Sendt" osv.)

LogActor

LogID - ekstern nøgle

LogActorType - Streng eller ID (som ovenfor, hvis ID skal du bruge en opslagstabel)

LogActorID - Dette er et unikt id til tabellen for typen f.eks. Bruger, Gruppe, Spil

Sekvens - dette er en bestilling af skuespillerne.

LogMessage

LogType - ekstern nøgle

Besked - lang streng (varchar(max)?)

Sprog - streng(5), så du kan slå et andet sprog fra, f.eks. "US-en"

Eksempeldata (ved hjælp af dine 3 eksempler)

Log

ID  Time   LogType 
1   1/1/10 1
2   1/1/10 2
3   1/1/10 3
 

LogActor

LogID LogActorType LogActorID Sequence
1     User         1          1
1     User         2          2
2     User         1          1
2     User         2          2
2     User         2          3
2     Game         1          4
3     User         3          1
3     Group        1          2
 

LogMessage

LogType Message 
1       {0} Made a new friend {1}
2       {0}, {1}, {2} played a game ({3})
3       {0} joined a group ({1})
 

Bruger

ID Name
1  User A
2  User B
3  User C
 

Spil

ID Name
1  Name of game
 

Gruppe

ID Name
1  Name of group
 

Så her er de fine ting ved dette design.

  • Det er meget nemt at forlænge

  • Det håndterer flersprogede spørgsmål uafhængigt af aktørerne

  • Det er selvdokumenterende, LogMessage-tabellen forklarer nøjagtigt, hvad de data, du gemmer, skal sige.

Nogle dårlige ting ved det.

  • Du skal lave noget kompliceret behandling for at læse beskederne.

  • Du kan ikke bare se på DB og se, hvad der er sket.

Efter min erfaring opvejer de gode dele af denne form for design de dårlige ting. Hvad jeg har gjort for at give mig et hurtigt og beskidt kig på loggen, er at lave en visning (som jeg ikke bruger til applikationskoden), som jeg kan se på, når jeg skal se, hvad der foregår via bagsiden ende.

Sig til, hvis du har spørgsmål.

Opdatering – Nogle eksempler på forespørgsler

Alle mine eksempler er i sqlserver 2005+, lad mig vide, hvis der er en anden version, du vil have mig til at målrette mod.

Se LogActor-tabellen (Der er en række måder at gøre dette på, den bedste afhænger af mange ting, herunder datadistribution, use cases osv.) Her er to:

a)

SELECT 
  LogId,
  COLLESCE(U.Name,Ga.Name,Go.Name) AS Name,
  Sequence
FROM LogActor A
LEFT JOIN User U ON A.LogActorID = U.[ID] AND LogActorType = "User"
LEFT JOIN Game Ga ON A.LogActorID = Ga.[ID] AND LogActorType = "Game"
LEFT JOIN Group Go ON A.LogActorID = Go.[ID] AND LogActorType = "Group"
ORDER BY LogID, Sequence
 

b)

SELECT 
  LogId,
  U.Name AS Name,
  Sequence
FROM LogActor A
INNER JOIN User U ON A.LogActorID = U.[ID] AND LogActorType = "User"
UNION ALL
SELECT 
  LogId,
  Ga.Name AS Name,
  Sequence
FROM LogActor A
INNER JOIN Game Ga ON A.LogActorID = Ga.[ID] AND LogActorType = "Game"
UNION ALL
SELECT 
  LogId,
  Go.Name AS Name,
  Sequence
FROM LogActor A
INNER JOIN Group Go ON A.LogActorID = Go.[ID] AND LogActorType = "Group"
ORDER BY LogID, Sequence
 

Generelt tror jeg, at a) er bedre end b) Hvis du for eksempel mangler en skuespiller, vil type a) inkludere den (med et nulnavn). Men b) er lettere at vedligeholde (fordi UNION ALL-sætningerne gør det mere modulært.) Der er andre måder at gøre dette på (f.eks. CTE, visninger osv.). Jeg er tilbøjelig til at gøre det som b), og ud fra hvad jeg har set ser det ud til at være i det mindste standard praksis, hvis ikke bedste praksis.

Så de sidste 10 elementer i loggen ville se sådan ud:

SELECT LogId, M.Message, COLLESCE(U.Name,Ga.Name,Go.Name) AS Name, Time, A.Sequence FROM Log LEFT JOIN LogActor A ON Log.LogID = A.LogID LEFT JOIN User U ON A.LogActorID = U.[ID] AND LogActorType = "User" LEFT JOIN Game Ga ON A.LogActorID = Ga.[ID] AND LogActorType = "Game" LEFT JOIN Group Go ON A.LogActorID = Go.[ID] AND LogActorType = "Group" LEFT JOIN LogMessage M ON Log.LogType = M.LogMessage WHERE LogID IN (SELECT Top 10 LogID FROM Log ORDER BY Date DESC) ORDER BY Date, LogID, A.Sequence

NB - Som du kan se, er det nemmere at vælge alle log-elementer fra en dato end sidste X, fordi vi skal bruge en (sikkert meget hurtig) underforespørgsel til dette.



  1. Visual Query Builder

  2. Kan ikke indsætte en enkelt kolonneværdi i python ved hjælp af MySQL

  3. Tilslutning af PowerShell til Salesforce.com

  4. Hvordan kan jeg sætte en database under git (versionskontrol)?