[英]Tracking changes in a database
My database requires some columns to be tracked, but not all. 我的数据库需要跟踪某些列,但不是全部。 I've looked at a couple of designs to implement tracking such as( Ideas on database design for capturing audit trails ). 我已经看过一些实现跟踪的设计,例如( 关于捕获审计跟踪的数据库设计的想法 )。
However this seems highly wasteful and since I only really need to track a couple of critical columns I feel like this wouldn't be the optimal solution for me. 但是,这似乎非常浪费,并且由于我真的只需要跟踪几个关键列,所以我觉得这不是我的最佳解决方案。
Now I thought of a way to tackle my situation, but I am not sure if I might be overlooking a design flaw with this approach. 现在,我想到了一种解决我的情况的方法,但是我不确定是否可以忽略这种方法的设计缺陷。
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
The schema above is just a highly simplified example, but captures the essence. 上面的模式只是一个高度简化的示例,但包含了本质。
Essentially an Employee can be on a pension scheme or not, the changes to this attribute have to tracked. 从本质上讲,雇员是否可以加入养老金计划,必须跟踪对此属性的更改。 When a change to that attribute needs to happen a new row is inserted with a timestamp. 当需要对该属性进行更改时,将插入带有时间戳的新行。
If you want to figure out whether the employee is on a pension scheme or not you would have to find the row with the most recent timestamp. 如果您想弄清楚该雇员是否正在使用养老金计划,则必须找到带有最新时间戳的行。
The only flaw that I currently see is, that if an Employee is inserted that there is no matching row in the PensionScheme table. 我当前看到的唯一缺陷是,如果插入了Employee,则PensionScheme表中没有匹配的行。 Though I am thinking of solving this with and INSERT trigger to add a default row. 虽然我正在考虑使用INSERT触发器来解决此问题,以添加默认行。
I am really just looking for thoughts on this design. 我真的只是在寻找有关此设计的想法。 I am quite inexperienced with change tracking in databases. 我对数据库中的更改跟踪非常缺乏经验。
You might be interested in system versioning functionality available in MariaDB starting from the version 10.3.4-beta . 您可能会对从10.3.4-beta版本开始的MariaDB中可用的系统版本控制功能感兴趣。
The basic idea is this (although you will of course need to tune the structure according to your real needs): 基本思想是这样(尽管您当然需要根据实际需要调整结构):
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.