Jedan trik, database history

Jedan trikić da podijelim,
…a tko zna, možda je to što želim reći već uobičajena praksa u svijetu da se tako radi.

Nebi bilo zanimljivo kada bih odmah rekao rješenje, pa prvo da postavim pitanje.

Ako bi htjeli pratiti history promjena baze podataka, kako bi ga pratili?

Što smatram pod history? Ne mora sada to baš biti mogućnost da vidite sve što se ikada dešavalo na bazi…ali u tom smjeru nešto.

Npr. imate administratore na stranici. I administratori imaju ovlasti da obrišu korisnika, poruku…ili nešto treće.

Vi kao main-admin možda želite vidjeti koji je administrator što pobrisao.

E sad, koje su solicije ovom problemu?

Jedna od solucija je otvoriti novu tablicu koja se zove recimo:

adminPobrisaoUsera

…i onda kod svakog brisanja usera unesti u tu tablicu koji admin je koga obrisao.

To je malo pain-in-ass rješenje, jer moramo posebno evidentirati svaku akciju koju pratimo.
Moramo također imati više različitih tablica za praćenje history-a.
Ok, možemo imati jednu tablicu za history…ali onda struktura te tablice mora podržavati različite history akcije koje pratimo.
A nije lako pratiti sve akcije…zato jer one mogu biti skroz specifične. Ne radi se samo o brisanju nekog usera ili artikla. Može se raditi i o updejtu nekog artikla. A kako artikl može imati “dvajst-pet” različitih polja (attributa) …malo je nespretno sve to popratiti koji točno attribut artikla je updejtan…

Svejedno, mislim da ima skroz elegantno rješenje za ovaj problem i da se sa nekoliko linija code-a može ispratiti baš sve živo i neživo što se dešava na bazi :smiley: :smiley:

Ako se kome mozga, izvolite. (Svoje) rješenje dam malo kasnije.

To ti se zove audit users.

Oracle baza već to ima ugrađeno,

Postgresql


https://wiki.postgresql.org/wiki/Audit_trigger

Za mysql nisam istraživao, ali isto postoji.

MS Sql server
https://docs.microsoft.com/en-us/sql/relational-databases/security/auditing/sql-server-audit-database-engine?view=sql-server-2017

Najbolja opcija za ovo je Audit kao što je jorgovan opisao. Audit sam koristio u MSSQL i odličan posao radi.

Ako neželiš audit pogledaj si ovo

Ovdje opisuje te stvari što tebe muči.
Unutar velike količine podataka kao što su DataWareHousi možeš pratit promjene na tablici tipa da dodaš još jedan atribut pa pratiš prošlu vrijednost samo. Ima mnogo tipova pa si prouči to.

https://www.datawarehouse4u.info/SCD-Slowly-Changing-Dimensions.html

1 Like

A inače ovako je zanimljivije. :sunglasses::sunglasses::sunglasses::sunglasses:

1 Like

Znamo mi da naš prijatelj @bozoou voli uvjek odstupati od nekog standarda.
Za Slowly Changing Dimension imaš Type 0 do Type 6. Čekamo tebe da Type 7 smisliš.

Nedostaje i 5. :smile::smile::smile::smile:
Reserved for future expansion.

1 Like

To su ostavili za ovakve kao @bozoou da složi.

2 Likeova

Ok, nije loše da postoje već gotova rješenja za to…kao što pretpostavih:

Ako se nekom mozga, i dalje je trick pitanje kako bi to elegantno ubacili u bazu koja nativno ne pruža takvu mogućnost. :slight_smile:

Imaš moj link za postgresql

Evo ga opet
https://wiki.postgresql.org/wiki/Audit_trigger

Event driven development

Nisam baš upoznat, da li bi mySQL podržao takav pristup?

koji pristuip? ako misliš na ovaj način kao kod postgresq-a, neznam. treba probati.
inače za mysql ima:
https://www.mysql.com/products/enterprise/audit.html

ali u enterprise varijanti, licenca koja se plaća god. po serveru.

free rješenje – podržava i mysql.

Ok, vidim gotova rješenja postoje. Nisam ni sumnjao. :slight_smile:

Uglavnom, ja sam se prije petljao sa svakakvim tablicima da pratim history ovoga …pa history onoga…i sve mi nekako uvijek smušeno bilo.

Onda sam se jednom sjetio da mi je dovoljna samo jedna tablica u koju ću zapisivati samo svaku SQL naredbu koja u sebi sadrži instrukciju Insert, Update ili Delete. I naravno, korisnika koji je aktivirao tu SQL naredbu…i timestamp kada je aktivirao.

Radi manje težine podataka, INSERT niti nebi pratio…ionako je najbitnije ispratiti Update i Delete akcije.
A po želji sam mogao setupirati da pratim i određene insertove.

Uglavnom, to se dalo full lako automatizirati i sve potrebne informacije o historyu baze su mi uvijek ostajale zapisane.

(Pričam u prošlosti jer se već godinu i pol nisam trebao taknuti rad s bazom xd)

Kako god, ne kažem da ova gore profi riješenja ne valjaju…ali ovo što napisah je skroz simple i radi relativno ok svoj job. I ne zavisi niti malo od nativne podrške vrste baze s kojom se radi…

Kad uzmeš neku bazu s njome se i vjenčaš. Prelazak na drugu bazu tj. migracija – skupo.

Ako mi netko kaže pa postoji migracija u frameworku i sl., ne pričam o takvim aplikacijama. Pričam o velikim app, gdje ima hrpa trigera, procedura, funkcija i sl.

Riječ simple je jako volim i to je razlog zašto ću raditi svoj mvc framework. :smile::smile:

Zaboravio sam napisati.

U ovom mojem mvc frameworku što radim, dodao sam logiranje grešaka.

Npr. meni se klasa zove model, i imam funkcije:

  1. query
  2. prepareQuery
    3.prepareInsertStatement
    4.prepareUpdateStatement

Ako mi query ne prođe hvatam exception i pozivam log klasu, funkciju logdb,
a u funkciji logdb imam zapis opet kroz prepareInsertStatement, i dodao sam source log u funkciju i u exception provjeravam da li je source !== “log”,
jer ako mi se dogodi greška u zapisu kod inserta u log, otići će u petlju, ovako se neće dogoditi ništa.

U svaku funkciju mogu dodati još logiranje i mogao bi zapisivati svaki query i usera koji ga zove itd…, ali ako se prati svaki select, onda bi bilo jako puno podataka i veličina tablice može otići na stotine GB.

Pravilo je da se uglavnom iz baze ništa ne smije brisati.

Što, ako se pogriješi kod izrade fakture , ponude i sl., ili se ispravlja, ako se ne može onda se moraju moći kopirati podaci u novu fakturu ili ponudu, a stara faktura ili ponuda dobivaju status – nevažeći.

Uglavnom sve te svari se rješavaju sa flag-ovima.

Isto tako trebalo bi možda pratiti uz update i insert, da se zna koji je korisnik što radio, ili kod zapisa recorda imati user_id.

1 Like