mysql - 跟踪数据库中的更改

标签 mysql sql database mariadb change-tracking

我的数据库需要跟踪某些列,但不是全部。 我研究了几种实现跟踪的设计,例如( Ideas on database design for capturing audit trails )。

然而,这似乎非常浪费,而且由于我只需要跟踪几个关键列,我觉得这对我来说不是最佳解决方案。

现在我想到了一种方法来解决我的情况,但我不确定我是否可能会忽视这种方法的设计缺陷。

User
----
ID PK        INT
Username     VARCHAR(MAX)    

Employee
-----
ID PK        INT
Name         VARCHAR(MAX)

PensionScheme
-------------
ID PK         INT
EmpID FK      INT (References Employee)
IsActive      BOOLEAN
ModifiedBy FK INT (References User)
EffectiveFrom DATETIME

上面的架构只是一个高度简化的示例,但捕获了本质。

本质上,员工可以参加养老金计划,也可以不参加,必须跟踪此属性的更改。当需要更改该属性时 插入带有时间戳的新行。

如果您想确定员工是否参加养老金计划,您必须找到具有最新时间戳的行。

我目前看到的唯一缺陷是,如果插入员工,则 PensionScheme 表中没有匹配的行。尽管我正在考虑使用 INSERT 触发器来添加默认行来解决此问题。

我真的只是在寻找对此设计的想法。我对数据库中的更改跟踪非常缺乏经验。

最佳答案

您可能对 system versioning functionality 感兴趣MariaDB 从 10.3.4-beta 版本开始可用。

基本思想是这样的(尽管你当然需要根据你的实际需要调整结构):

MariaDB [test]> CREATE TABLE PensionScheme (
                  ID INT PRIMARY KEY, 
                  EmpID INT, 
                  IsActive BOOLEAN WITH SYSTEM VERSIONING, 
                  ModifiedBy INT, 
                  EffectiveFrom DATETIME
                );
Query OK, 0 rows affected (0.17 sec)

MariaDB [test]> INSERT INTO PensionScheme VALUES (1,2,0,1,NULL);
Query OK, 1 row affected (0.05 sec)

MariaDB [test]> SELECT * FROM PensionScheme WHERE EmpID = 2;
+----+-------+----------+------------+---------------+
| ID | EmpID | IsActive | ModifiedBy | EffectiveFrom |
+----+-------+----------+------------+---------------+
|  1 |     2 |        0 |          1 | NULL          |
+----+-------+----------+------------+---------------+
1 row in set (0.00 sec)

MariaDB [test]> UPDATE PensionScheme 
                  SET IsActive = 1, ModifiedBy = 2 WHERE EmpID = 2;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Inserted: 1  Warnings: 0

MariaDB [test]> SELECT * FROM PensionScheme WHERE EmpID = 2;
+----+-------+----------+------------+---------------+
| ID | EmpID | IsActive | ModifiedBy | EffectiveFrom |
+----+-------+----------+------------+---------------+
|  1 |     2 |        1 |          2 | NULL          |
+----+-------+----------+------------+---------------+
1 row in set (0.00 sec)

MariaDB [test]> SELECT ID, IsActive, ModifiedBy, row_start, row_end 
                  FROM PensionScheme FOR system_time ALL WHERE EmpID = 2;
+----+----------+------------+----------------------------+----------------------------+
| ID | IsActive | ModifiedBy | row_start                  | row_end                    |
+----+----------+------------+----------------------------+----------------------------+
|  1 |        0 |          1 | 2018-01-28 14:59:54.955159 | 2018-01-28 15:00:56.430942 |
|  1 |        1 |          2 | 2018-01-28 15:00:56.430942 | 2038-01-19 05:14:07.999999 |
+----+----------+------------+----------------------------+----------------------------+
2 rows in set, 3 warnings (0.00 sec)

MariaDB [test]> UPDATE PensionScheme SET EffectiveFrom = NOW() WHERE EmpID = 2;
Query OK, 1 row affected (0.06 sec)
Rows matched: 1  Changed: 1  Inserted: 0  Warnings: 0

MariaDB [test]> SELECT ID, IsActive, ModifiedBy, row_start, row_end 
                  FROM PensionScheme FOR system_time ALL WHERE EmpID = 2;
+----+----------+------------+----------------------------+----------------------------+
| ID | IsActive | ModifiedBy | row_start                  | row_end                    |
+----+----------+------------+----------------------------+----------------------------+
|  1 |        0 |          1 | 2018-01-28 14:59:54.955159 | 2018-01-28 15:00:56.430942 |
|  1 |        1 |          2 | 2018-01-28 15:00:56.430942 | 2038-01-19 05:14:07.999999 |
+----+----------+------------+----------------------------+----------------------------+
2 rows in set, 3 warnings (0.00 sec)

MariaDB [test]> SELECT * FROM PensionScheme WHERE EmpID = 2;
+----+-------+----------+------------+---------------------+
| ID | EmpID | IsActive | ModifiedBy | EffectiveFrom       |
+----+-------+----------+------------+---------------------+
|  1 |     2 |        1 |          2 | 2018-01-28 15:03:19 |
+----+-------+----------+------------+---------------------+
1 row in set (0.00 sec)

关于mysql - 跟踪数据库中的更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48481967/

相关文章:

php转换数据库中的所有密码

sql - 获得从特定客户群购买的产品的百分比

mysql - Ruby on Rails,表单数据未通过sql添加到数据库

php - 在相关的两个表之间搜索 SQL 问题

mysql - 如何将远程数据库与本地codeigniter一起使用?

mysql - Ruby on Rails "Undefined method ' 编码'"同时使用 mysql 保存到 blob/二进制列

sql - 数据库设计允许存储来自可能改变的外部关系的数据

mysql - 为什么 count(column_name) 会这样?

php - 从多个文本字段获取输入到数组并插入到数据库字段

MYSQL查询将从字符串中删除字符