当前位置:  开发笔记 > 编程语言 > 正文

数据库设计用于数据的时间点"快照"?

如何解决《数据库设计用于数据的时间点"快照"?》经验,为你挑选了2个好方法。

如何设计一个支持某个功能的数据库,该功能允许应用程序用户在某个时间点创建其数据的快照,有点像版本控制.

它将使用户能够返回并查看他们过去的数据.

假设"快照"的数据很复杂并且包括多个表的连接.

我正在寻找一种方法,让每个应用程序用户能够快照他们的数据并返回它.整个数据库快照不是我想要的.

编辑:谢谢你的回答.6NF的答案很有说服力,因为快照数据由于其简单性而去标准化的建议.

澄清:这不是数据仓库问题,也不是关于数据库备份和恢复的问题; 它是关于如何构建一个模式,允许我们在某个时间点捕获一组特定的相关数据的状态.应用程序用户在认为合适时生成快照.用户不会对整个数据库进行快照,只会对他们感兴趣的数据对象进行快照.



1> tpdi..:

这并不容易.

你基本上要求一个时间数据库(Christopher Date称之为第六范式,或6NF).

要为6NF,模式也必须是5NF,并且基本上,对于每个数据,您需要附加该值的数据适用的时间范围.然后在连接中,连接必须仅包括在所考虑的时间范围内的行.

时态建模很难 - 它是第6个普通形式的地址 - 并且在当前的RDBMS中得不到很好的支持.

问题是粒度.第6范式(正如我所理解的)支持时间建模,通过使每个非关键(非关键:,即,在实体上"可以在没有实体失去其身份的情况下改变"的任何东西)成为单独的关系.为此,您可以添加时间戳或时间范围或版本号.使所有内容成为连接可以解决粒度问题,但这也意味着您的查询会更复杂,速度更慢.它还需要确定所有键和非键属性; 这往往是一项巨大的努力.

基本上,无论你有关系("泰德拥有通用汽车股票证书编号为789")添加时间:"泰德拥有通用汽车股票证书编号为789 ,现在 ",这样就可以同时说,"弗雷德拥有通用汽车股票2000年2月3日至昨天的证书,编号为789.显然,这些关系是多对多的(ted现在可以拥有多个证书,并且在他的一生中也可以拥有多个证书),而fred现在可以拥有证书杰克拥有的证书.

因此,我们有一个所有者表,一个股票证书表和一个多对多表,通过id关联所有者和证书.对于多对多表,我们添加了一个start_date和一个end_date.

现在,想象一下每个州/省/土地对股票的股息征税,因此为了税收目的,记录股票证书所有者的居住状态.

所有者居住的地方显然可以独立改变股权; 泰德可以住在内布拉斯加州,购买10股,获得内布拉斯加州的股息,转移到内华达州,向弗雷德出售5股,再购买10股.

但对我们来说,这是泰德可以移动到内布拉斯加州的一段时间,买入10股,在一段时间内,得到了股息在某些时候,这内布拉斯加州的税收,转移到Neveda 在一段时间内,售出500万股弗雷德在一段时间内,购买10 在某个时候更多的股票.

如果我们想要计算内布拉斯加州和内华达州所欠的税款,加入person_stockcertificate和person_address中的匹配/重叠日期范围,我们需要所有这些.一个人的地址不再是一对一的,它是一对多的,因为它是在时间范围内的地址.

如果特德买了10股,我们是否用单个购买日期对买入事件进行建模,或者我们是否为每个股票添加了date_bought?取决于我们需要模型回答的问题.



2> Kamiel Wanro..:

我们这样做了一次,创建了包含我们想要快照的数据的单独数据库表,但是非规范化,即每个记录包含有意义所需的所有数据,而不是对可能或可能不再存在的id的引用.它还为每一行添加了一个日期.

然后,我们为在所有受影响的表上执行连接的特定插入或更新生成触发器,并将其插入到快照表中.

这样,编写将用户数据恢复到某个时间点的内容将是微不足道的.

如果你有一张桌子:

用户:

id, firstname, lastname, department_id

部门:

id, name, departmenthead_id

您的用户表快照可能如下所示:

user_id, user_firstname, user_lastname, department_id, department_name, deparmenthead_id, deparmenthead_firstname, departmenthead_lastname, snapshot_date

和一个类似的查询

INSERT INTO usersnapshot
SELECT user.id AS user_id, user.firstname AS user_firstname, user.lastname AS user_lastname,
department.id AS department_id, department.name AS department_name
departmenthead.id AS departmenthead_id, departmenthead.firstname AS departmenthead_firstname, departmenthead.lastname AS departmenthead_lastname,
GETDATE() AS snapshot_date
FROM user
INNER JOIN department ON user.department_id = department.id
INNER JOIN user departmenthead ON department.departmenthead_id = departmenthead.id

这可确保快照中的每一行在该时刻都为真,即使部门或部门负责人在此期间发生了变化.

推荐阅读
oDavid_仔o_880
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有