Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Registro de auditoria para dados de produtos?


Seus dados de auditoria devem ser armazenados por tabela, em vez de todos em um só lugar. O que você faria é criar uma tabela de auditoria para cada uma das tabelas que deseja rastrear e criar gatilhos para criar um registro na tabela de auditoria para qualquer operação de manipulação de dados na tabela auditada.

É definitivamente aconselhável não permitir DELETE operações nos items e item_options tabelas - adicione sinalizadores como item_active e item_option_active para que você possa excluí-los de forma reversível. Essa é uma prática normal em situações em que você está fazendo coisas como armazenar faturas que fazem referência a produtos encomendados no passado e precisa dos dados para fins de relatórios históricos, mas não para uso diário.

Suas tabelas de auditoria não são algo que você deve usar para fazer referência a dados antigos, seu modelo de dados normal deve suportar simplesmente "ocultar" dados antigos onde é provável que ainda sejam usados ​​e armazenar várias versões de dados que serão alteradas ao longo do tempo.

Para auditoria, também é útil armazenar o nome de usuário do último usuário a modificar um determinado registro - quando usado de um aplicativo da Web, você não pode usar o USER() do MySQL para obter qualquer informação útil sobre quem está conectado. Adicionar uma coluna e preenchê-la significa que você pode usar essas informações em seus gatilhos de auditoria.

NB: Suponho que você não permitirá que os IDs dos itens sejam alterados em condições normais - isso tornaria seu sistema de auditoria mais complexo.

Se você adicionar sinalizadores ativos e dados modificados pela última vez às suas tabelas, eles serão parecidos com:

Tabela de itens:

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    |                |
+------------------+--------------+------+-----+---------+----------------+

Tabela de opções de itens:

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    |                |
+---------------+--------------+------+-----+---------+----------------+

Suas tabelas de auditoria precisam armazenar quatro informações extras:
  • ID de auditoria - este ID é exclusivo apenas para o histórico deste tabela, não é um valor global
  • Alteração feita por - o usuário do banco de dados que fez a alteração
  • Alterar data/hora
  • Tipo de ação - INSERT ou UPDATE (ou DELETE se você permitisse)

Suas tabelas de auditoria devem se parecer com:

Tabela de auditoria de itens:

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    |                |
+------------------+--------------+------+-----+---------+----------------+

Tabela de auditoria de opções de itens:

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    |                |
+---------------+--------------+------+-----+---------+----------------+

Não use chaves estrangeiras em suas tabelas de auditoria; as linhas nas tabelas de auditoria não são linhas filhas dos registros que estão auditando, portanto, as chaves estrangeiras não são úteis.

Acionadores


NB: O MySQL não suporta gatilhos do tipo multi-instrução, então você precisa de um para cada INSERT , UPDATE e DELETE (se aplicável).

Seus gatilhos simplesmente precisam INSERT todos os NEW valores na tabela de auditoria. As definições de gatilho para os items tabela pode ser:
/* 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;

Crie acionadores semelhantes para as item_options tabela.

Atualização:histórico de dados no comércio eletrônico


A auditoria que fizemos acima permitirá que você mantenha um histórico de qualquer tabela de banco de dados, mas cria um armazenamento de dados que não é adequado para uso de dados que precisam ser acessados ​​regularmente.

Em um sistema de comércio eletrônico, manter utilizável os dados históricos são importantes, para que você possa alterar os atributos enquanto ainda apresenta valores antigos em determinadas situações.

Isso deve ser completamente separado de sua solução de auditoria

A melhor maneira de armazenar o histórico é criar uma tabela de histórico para cada atributo que precisa ser armazenado historicamente. Esta pergunta do Stackoverflow tem algumas boas informações sobre como manter um histórico de um determinado atributo .

Na sua situação, se você estiver preocupado apenas com preço e título, crie um prices tabela e um item_titles tabela. Cada um teria uma chave estrangeira para o item_options tabela ou os items tabela (as tabelas mestras ainda armazenariam o valor atual preço ou título), e teria o preço ou título, com suas datas de vigência. Essas tabelas devem ter permissões refinadas (possivelmente baseadas em colunas) para evitar a atualização do effective_from datas e os valores reais uma vez que o registro é inserido.

Você também deve usar a solução de auditoria acima nessas tabelas.