我的数据库需要跟踪某些列,但不是全部。 我研究了几种实现跟踪的设计,例如( 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/