简体   繁体   English

跟踪数据库中的更改

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM