sql >> Databasteknik >  >> RDS >> Mysql

Revisionsloggning för produktdata?

Dina granskningsdata bör lagras per tabell, snarare än alla på ett ställe. Vad du skulle göra är att skapa en granskningstabell för var och en av de tabeller du vill spåra, och skapa utlösare för att skapa en post i granskningstabellen för alla datamanipuleringsåtgärder på den granskade tabellen.

Det är definitivt tillrådligt att inte tillåta DELETE operationer på items och item_options tabeller – lägg till flaggor som item_active och item_option_active så att du kan softdelete dem istället. Detta är normal praxis i situationer där du gör saker som att lagra fakturor som refererar till produkter som beställts tidigare och behöver data för historiska rapporteringsändamål, men inte för daglig användning.

Dina granskningstabeller är inte något du bör använda för att referera till gamla data, din normala datamodell bör helt enkelt stödja att "gömma" gamla data där det är troligt att det fortfarande kommer att användas, och lagra flera versioner av data som kommer att förändras över tiden.

För granskning är det också användbart att lagra användarnamnet för den senaste användaren för att ändra en given post - när den används från en webbapplikation kan du inte använda MySQL:s USER() funktion för att få användbar information om vem som är inloggad. Att lägga till en kolumn och fylla i den betyder att du kan använda den informationen i dina granskningsutlösare.

Obs! Jag antar att du inte kommer att tillåta att artikel-ID:n ändras under normala förhållanden - det skulle göra ditt revisionssystem mer komplext.

Om du lägger till aktiva flaggor och data som senast ändrats av dina tabeller kommer de att se ut ungefär så här:

Artikeltabell:

mysql> desc items;
+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| item_id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| item_name        | varchar(100) | YES  |     | NULL    |                |
| item_description | text         | YES  |     | NULL    |                |
| item_active      | tinyint(4)   | YES  |     | NULL    |                |
| modified_by      | varchar(50)  | YES  |     | NULL    |                |
+------------------+--------------+------+-----+---------+----------------+

Tabell för objektalternativ:

mysql> desc item_options;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| option_id     | int(11)      | NO   | PRI | NULL    | auto_increment |
| item_id       | int(11)      | YES  | MUL | NULL    |                |
| option_name   | varchar(100) | YES  |     | NULL    |                |
| option_price  | int(11)      | YES  |     | NULL    |                |
| option_active | tinyint(4)   | YES  |     | NULL    |                |
| modified_by   | varchar(50)  | YES  |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+

Dina granskningstabeller behöver lagra fyra extra uppgifter:

  • Revisions-ID – detta ID är endast unikt för historien om denna tabell är det inte ett globalt värde
  • Ändring gjord av - databasanvändaren som gjorde ändringen
  • Ändra datum/tid
  • Åtgärdstyp - INSERT eller UPDATE (eller DELETE om du tillät det)

Dina granskningstabeller bör se ut ungefär så här:

Revisionstabell för objekt:

mysql> desc items_audit;
+------------------+--------------+------+-----+---------+----------------+
| Field            | Type         | Null | Key | Default | Extra          |
+------------------+--------------+------+-----+---------+----------------+
| audit_id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| item_id          | int(11)      | YES  |     | NULL    |                |
| item_name        | varchar(100) | YES  |     | NULL    |                |
| item_description | text         | YES  |     | NULL    |                |
| item_active      | tinyint(4)   | YES  |     | NULL    |                |
| modified_by      | varchar(50)  | YES  |     | NULL    |                |
| change_by        | varchar(50)  | YES  |     | NULL    |                |
| change_date      | datetime     | YES  |     | NULL    |                |
| action           | varchar(10)  | YES  |     | NULL    |                |
+------------------+--------------+------+-----+---------+----------------+

Revisionstabell för objektalternativ:

mysql> desc item_options_audit;
+---------------+--------------+------+-----+---------+----------------+
| Field         | Type         | Null | Key | Default | Extra          |
+---------------+--------------+------+-----+---------+----------------+
| audit_id      | int(11)      | NO   | PRI | NULL    | auto_increment |
| option_id     | int(11)      | YES  |     | NULL    |                |
| item_id       | int(11)      | YES  |     | NULL    |                |
| option_name   | varchar(100) | YES  |     | NULL    |                |
| option_price  | int(11)      | YES  |     | NULL    |                |
| option_active | tinyint(4)   | YES  |     | NULL    |                |
| modified_by   | varchar(50)  | YES  |     | NULL    |                |
| change_by     | varchar(50)  | YES  |     | NULL    |                |
| change_date   | datetime     | YES  |     | NULL    |                |
| action        | varchar(10)  | YES  |     | NULL    |                |
+---------------+--------------+------+-----+---------+----------------+

Använd inte främmande nycklar på dina granskningstabeller; raderna i granskningstabellerna är inte underordnade rader till de poster som de granskar, så främmande nycklar är inte till någon nytta.

Triggers

Obs! MySQL stöder inte triggers av flera påståenden, så du behöver en för var och en av INSERT , UPDATE och DELETE (om tillämpligt).

Dina utlösare behöver bara INSERT alla NEW värden i granskningstabellen. Triggerdefinitionerna för items tabellen kan vara:

/* Trigger for INSERT statements on the items table */
CREATE DEFINER=`root`@`localhost` TRIGGER trigger_items_insert_audit 
AFTER INSERT ON items 
  FOR EACH ROW BEGIN
    INSERT INTO items_audit (
                  item_id, item_name, item_description, 
                  item_active, modified_by, change_by,  
                  change_date, action
                ) VALUES (
                  NEW.item_id, NEW.item_name, NEW.item_description,  
                  NEW.item_active, NEW.modified_by, USER(),  
                  NOW(), 'INSERT'
                ); 
  END;

/* Trigger for UPDATE statements on the items table */
CREATE DEFINER=`root`@`localhost` TRIGGER trigger_items_update_audit 
AFTER UPDATE ON items 
  FOR EACH ROW BEGIN
    INSERT INTO items_audit (
                  item_id, item_name, item_description, 
                  item_active, modified_by, change_by,  
                  change_date, action
                ) VALUES (
                  NEW.item_id, NEW.item_name, NEW.item_description,  
                  NEW.item_active, NEW.modified_by, USER(),  
                  NOW(), 'UPDATE'
                ); 
  END;

Skapa liknande utlösare för item_options bord.

Uppdatering:Datahistorik i e-handel

Granskningen vi gjorde ovan gör att du kan behålla en historik över en given databastabell, men skapar ett datalager som inte är lämpligt att använda för data som behöver nås regelbundet.

I ett e-handelssystem, hålla sig användbar historisk data är viktig så att du kan ändra attribut samtidigt som du fortfarande presenterar gamla värden i vissa situationer.

Detta bör vara helt skilt från din revisionslösning

Det bästa sättet att lagra historik är att skapa en historiktabell för varje attribut som måste lagras historiskt. Den här Stackoverflow-frågan har bra information om hur du sparar en historik för ett givet attribut .

I din situation, om du bara är orolig för pris och titel, skulle du skapa en prices tabell och en item_titles tabell. Var och en skulle ha en främmande nyckel till antingen item_options tabellen eller items tabell (huvudtabellerna skulle fortfarande lagra aktuella pris, eller titel), och skulle ha priset eller titeln, med dess ikraftträdandedatum. Dessa tabeller bör ha finkorniga (eventuellt kolumnbaserade) behörigheter för att undvika uppdatering av effective_from datum och de faktiska värdena när posten har infogats.

Du bör också använda revisionslösningen ovan på dessa tabeller.



  1. mysql välj uppdatering

  2. Vill du ställa in tabell teckenuppsättning/sortering med vilolägesdialekt?

  3. MySQL får ett slumpmässigt värde mellan två värden

  4. Installera luaSQL på Ubuntu