Salutare
La proiectul la care lucrez acum, am întâmpinat o “mică” problemă, așa că am decis să apelez la ajutorul vostru.
Am mai multe formulare prin care pot adăuga și edita informațiile existente. Ideea de bază este că mi-aș dori să am o evidență la absolut tot ce se adaugă sau se modifică, cu alte cuvinte un log a activității. Cel mai bun exemplu pe care l-am găsit este în Zoho CRM (am adăugat o poză mai jos).
Dilema cea mare este că nu îmi dau seama care este cel mai eficient mod de a stoca aceste informații în baza de date. Precizez că am nevoie de aceste date doar pentru a afișa acest jurnal, nu o să le mai folosesc și în alte părți.
Daca esti pe mysql 5.7, poti sa incerci noua coloana de tip json. E pentru date cam de genul asta. Niste articole despre asta: unu, doua, plus un video cu un tip de la Oracle care vorbeste despre asta (partea de indecsi este extrem de interesanta).
Depinde mult de ce tech stack folosesti. Daca ai un CRM care iti impune o anumita structura a tabelelor din DB, o sa-ti fie mai greu decat daca folosesti ceva gen Django/Laravel etc. unde tu decizi ce tabele ai si cum.
O strategie OK este urmatoarea: pentru fiecare entitate X sa ai doua tabeluri Xs si XEvents. X este tableful standard pe care l-ai avea, iar XEvents este un jurnal al fiecărei modificări din X. Ideal e sa pui modificări semantice, la nivelul serviciului care controlează entitatea. De exemplu, pentru o sesiune ai avea evenimente de genul creat, expirat, ok la cookies, logout etc. Asadar nu modificari de genul “câmpul Z devine 10”. Ca model e folositor sa ai un id, timestamp, id-ul entității care este vizata și o coloana Json cu date despre schimbare. Un index pe (entity_id, timestamp) e folositor de asemena.
Mulțumesc pentru sugestie. Am încercat până acum să nu externalizez niciun serviciu din diferite motive. Nu pare o treabă atât de complicată ținând cont că nu gestionez un volum mare de informații.
PS: Mi-a plăcut modul de a trimite id-ul “picture:10”, “activity:10”. Asta m-a făcut să regândesc o parte din sistemul de notificări.
Este o idee chiar bună ținând cont că nu o să am niciodată nevoie de a face o interogare pe acea coloana. Nu îmi pot face griji cu privire la timpul de execuție.
Am sa incerc sa scriu un articol pe blog despre treabă asta, pentru că un comentariu nu e cel mai bun mediu ptr elaborarea de tipul asta. Un mic tutorial. Revin de indata ce e gata.
creat clasa separata cu o serie de functii:
2.1 add_log() -> user_id (luat din sesiunea user-ului logat), description: 2 variante: adaugat String in limba romana sau parametrizat cu un lang_event_id
Asa scriem log-uri pe fiecare user la operatiile necesare.
Apoi un modul separat care facem doar afisarea, dupa bunul plac.
Ce parere aveti de urmatoarea abordare? Triggeri la nivelul bazei de date care se declanseaza “before update”, prin care se salveaza inregistrarile intr-un tabel separat? O implementare de genul asta:
System-versioning for a table is implemented as a pair of tables, a current table and a history table. Within each of these tables, the following two additional datetime2 columns are used to define the period of validity for each row.
The current table contains the current value for each row. The history table contains each previous value for each row, if any, and the start time and end time for the period for which it was valid.
Event Sourcing este un pattern destul de vechi si des folosit in multe aplicatii enterprise. Atunca o privire si vezi daca ti se pare ok pentru ce ai tu nevoie.
Also, daca o tabela mysql pentru stocat evenimentele respective ti se pare o solutie ne-eleganta(nu este, dar in fine, alta discutie), poti implementa ca solutie de stocare elasticsearch, ca apoi sa accesezi usor respectivul endpoint(chiar restful).
Nu detaliez pana la capat, insa notez cateva observatii:
Triggerele sunt bune in development mode / MVP mode, etc, in cazurile in care nu se cere performanta si consistenta 100%. E de retinut faptul ca pt fiecare insert in baza de date, triggerele asociate vor incetini performanta sistemului, practic pe cel care face operatia de insert il costa si asteptatul dupa logarea diverselor date aditionale Si odata pornit bulgărele de triggere, se vor dori tot mai multe.
Ca preferință personală, și eu as merge pe ideea lui @tacheshun cu evenimentele. În ideea în care am un RESTful API care primește cereri de a loga diverse evenimente, iar acesta folosește 204 trick pentru a nu aștepta după răspunsul sistemului de logare. Se poate lansa comanda de logare fie din controllerul care a persistat informația inițială, fie din client (ex. browser). Aici strategia depinde de proiect.
Pentru a nu încărca sistemul cu prea multe moduri de persistare, un tabel cu loguri e o bună soluție de start. Eu aș face 4 coloane: user_id (cine a declansat evenimentul), category (de ce fel e evenimentul), details (json cu datele), occurred_at (cand s-a petrecut). In functie de ati ales la itemul 2 ca declansator (controllerul sau clientul) data poate diferi cu cateva ms.