我想知道是否有可能将多个表中的更改记录到一个日志表中。每列应该登录到自己的行。
表格不相同,但每个都有:
某些表包含其他列,例如:
Log_Table应该包含以下列:
我想只有一个Log-Table,它记录所有表(具有或没有相同列)的所有初始值,更新和删除,除了它自己。它应该发生在mysql中,所以phpMyAdmin,php,python ...中的每个更改都会被记录并且
这样的事情是否可能?
答案 0 :(得分:0)
似乎您需要审核数据更改,而不是能够查看给定日期的数据状态,因为根据您的解决方案重建数据状态会非常复杂(如果我不正确的话)这个假设错了)。我不认为这个想法是可行的,因为即使是非常小的数据库,你的日志表也会很庞大,因此很难妥善管理。
审核数据更改的无痛解决方案是为要跟踪的每个表创建历史记录表。此表将为每行执行的每个插入,更新和删除查询都有一个条目。历史表的结构将与它跟踪的表相同,除了三个附加列,一列用于存储发生的操作,一列用于存储序列号,另一列用于保存发生时间戳。
以下查询会产生创建这些审计表所需的SQL,但只有在以下情况下才能生效:
_
开头(因为审计表会
做); 查询:
SET sql_mode = 'PIPES_AS_CONCAT';
SELECT
'CREATE TABLE __' || table_name || ' LIKE ' || table_name || ';\r\n' ||
'RENAME TABLE __' || table_name || ' TO _' || table_name || ';\r\n' ||
'ALTER TABLE _' || table_name || ' ADD Registrated TIMESTAMP NOT NULL FIRST;\r\n' ||
'ALTER TABLE _' || table_name || ' ADD Action TINYINT UNSIGNED NOT NULL FIRST;\r\n' ||
'ALTER TABLE _' || table_name || ' ADD Revision INT UNSIGNED NOT NULL FIRST;\r\n' ||
'ALTER TABLE _' || table_name || ' MODIFY ' || column_name || ' ' || UPPER(data_type) || IF(is_nullable = 'NO', ' NOT NULL', '') || ';\r\n' ||
'ALTER TABLE _' || table_name || ' DROP PRIMARY KEY;\r\n' ||
'ALTER TABLE _' || table_name || ' MODIFY COLUMN Revision INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;\r\n' ||
'CREATE TRIGGER i' || table_name || ' AFTER INSERT ON ' || table_name || ' FOR EACH ROW INSERT INTO _' || table_name || ' SELECT NULL, 1, CURRENT_TIMESTAMP, ' || table_name || '.* FROM ' || table_name || ' WHERE ' || table_name || '.' || column_name || ' = NEW.' || column_name || ';\r\n' ||
'CREATE TRIGGER u' || table_name || ' AFTER UPDATE ON ' || table_name || ' FOR EACH ROW INSERT INTO _' || table_name || ' SELECT NULL, 2, CURRENT_TIMESTAMP, ' || table_name || '.* FROM ' || table_name || ' WHERE ' || table_name || '.' || column_name || ' = NEW.' || column_name || ';\r\n' ||
'CREATE TRIGGER d' || table_name || ' BEFORE DELETE ON ' || table_name || ' FOR EACH ROW INSERT INTO _' || table_name || ' SELECT NULL, 3, CURRENT_TIMESTAMP, ' || table_name || '.* FROM ' || table_name || ' WHERE ' || table_name || '.' || column_name || ' = OLD.' || column_name || ';'
FROM information_schema.tables
JOIN information_schema.table_constraints USING (table_schema, table_name)
JOIN information_schema.key_column_usage USING (table_schema, table_name, constraint_name)
JOIN information_schema.columns USING (table_schema, table_name, column_name)
WHERE
information_schema.tables.table_schema = (SELECT DATABASE()) AND
information_schema.table_constraints.constraint_type = 'PRIMARY KEY';
注1:外键是参照完整性工具,而不是性能工具。一个好的数据库模型将表现得更好,但外键本身会导致更多的处理发生,而不是更少。 CREATE TABLE LIKE
将根据原始表的定义创建一个空表,包括任何列属性和索引,但忽略其他所有内容(如数据,外键等)。原始表约束正在验证数据完整性,因此在审计表中使用外键没有任何好处。