0

我在stackoverflow中研究了一些问题,但我想要的是为了以后的查询目的,而不是为了记录目的。

我有一个项目需要从某个时刻获得价值。例如我有一个用户表

User:
id
name
address

Pet:
id
name
type

Adoption:
id
user_id
pet_id

数据:

User:
1, John, One Street
Pet:
1, Lucy, Cat
Adoption:
1, 1, 1

假设用户更改地址,看起来像

User:
1, John, Another Street

我需要的是 用户收养宠物时的地址(或其他字段)是什么。

我在想的是总是在同一个表中创建一个新行(在这种情况下是用户)并将新行引用到前一行

User:
2, 1, John, Another Street ( where 1 is referring to the previous id / updated from)
1, NULL, John, One Street, deleted (NULL means this is newly created data)

使用它的好处是,查询方便(我只是像往常一样查询。缺点是表会很大,无法记录每次更新。有什么解决办法吗?

谢谢

4

2 回答 2

0

对此有不同的方法。

也许最简单的方法是对数据进行非规范化。如果您在采用时需要数据,请将其作为列包含在采用表中。该地址是“时间点”地址。

这种方法对简单的事情很有用,但不能很好地扩展。你必须预先定义你想要的列。

下一步是为所有表或至少所有感兴趣的表创建审计表。每次更改记录时user,都会将新记录添加到userAudit. 审计表通常使用触发器来维护。

审计表的优点是它们不会弄乱现有的表(和逻辑)。相同的查询适用于现有表。

最后,您可以屈服并意识到您的数据模型被过度简化了。你真的有慢慢变化的维度。该数据可以使用每行的版本生效日期和版本结束日期来表示。用户表最终看起来像:

user_id   name    address    version_eff_dt    version_end_dt

因为 user_id 不再是主键,您可能需要两个表usersuserHistory,或类似的东西。

这是任何时间点数据的“正确”表示。但是,它通常需要重组查询,因为单个用户在表中出现多次——并且user_id不再是主键。

于 2020-10-03T12:27:32.323 回答
0

这就是我有时会做的事情:

对于我需要跟踪值更改的任何字段,我设计了一个单独的更改表。

例如,对于作为与用户实体相关联的概念并且不是采用实体的直接属性的地址字段,我定义了表: UserAddressChanges(UserID, Address, ChangeDateTime, ChangerPersonID)

这样,更改数据可以在任何其他子系统或系统中使用,而与您当前的采用用例无关。


我对非常简单的表使用表内更改跟踪,例如: UniversityManagers(PersonID, AssignDateTime, AssignorPersonID)


对于需要完整记录日志的频繁更改的更复杂的表(通常很少引用以前的数据),我将(当前记录的)主表和具有额外字段的日志表分开,例如 LogID、ChangeDateTime、ChangerPersonID、换IP,...

于 2020-10-03T06:39:32.947 回答