mysql - 跟踪数据库中的更改

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


上面的模式只是一个高度简化的示例,但包含了本质。

从本质上讲,雇员是否可以加入养老金计划,必须跟踪对此属性的更改。当需要对该属性进行更改时
将插入带有时间戳的新行。

如果要弄清楚该雇员是否正在使用养老金计划,则必须找到带有最新时间戳的行。

我当前看到的唯一缺陷是,如果插入了Employee,则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)

本文翻译自 https://stackoverflow.com/questions/48481967/

网站遵循 CC BY-SA 4.0 协议,转载或引用请注明出处。

标签 mysql sql database mariadb change-tracking


相关文章:

python - Pandas写表到MySQL:“无法回滚”

c# - 在C#中选择简单的SQL?

android - 错误仅在sqlite中插入没有这样的表

php - 在没有数据库的情况下运行Drupal 7网站

c# - 我的ComboBox3无法将第二个数据类型转换为我的textbox1

php - 在MySQL中插入URL

c# - C#潜在的日期格式问题-System.Data.SqlClient.SqlException:''x'附近的语法不正确。

php - WordPress样式表和其他文件未链接

php - MySQL-更新和删除查询不起作用

mysql - 如何在mysql中只返回唯一值