Database design 什么';存储对数据库记录的更改的最佳方法是什么?这些更改在可见之前需要获得批准?

Database design 什么';存储对数据库记录的更改的最佳方法是什么?这些更改在可见之前需要获得批准?,database-design,Database Design,我需要将用户输入的更改存储到特定表中,但在管理员用户查看和批准这些更改之前,不会显示这些更改。虽然这些更改仍处于挂起状态,但我仍然会显示数据的旧版本。存储这些等待批准的更改的最佳方式是什么 我想了好几种方法,但不知道什么是最好的方法。这是一个非常小的web应用程序。一种方法是使用一个PendingChanges表来模拟另一个表的模式,然后一旦更改被批准,我就可以用信息更新真实的表。另一种方法是执行某种记录版本控制,在表中存储数据的多个版本,然后始终使用标记为approved的最高版本号提取记录。

我需要将用户输入的更改存储到特定表中,但在管理员用户查看和批准这些更改之前,不会显示这些更改。虽然这些更改仍处于挂起状态,但我仍然会显示数据的旧版本。存储这些等待批准的更改的最佳方式是什么

我想了好几种方法,但不知道什么是最好的方法。这是一个非常小的web应用程序。一种方法是使用一个PendingChanges表来模拟另一个表的模式,然后一旦更改被批准,我就可以用信息更新真实的表。另一种方法是执行某种记录版本控制,在表中存储数据的多个版本,然后始终使用标记为approved的最高版本号提取记录。这将限制额外表的数量(我需要对多个表执行此操作),但需要我在每次提取一组记录时进行额外处理,以确保获得正确的记录

这些方法或其他方法的个人经验可能是好的吗

更新:只是澄清一下,在这种特殊情况下,我对历史数据不太感兴趣。我只需要一些方法来批准用户在网站上线之前所做的任何更改。因此,用户将编辑他们的“配置文件”,然后管理员将查看该修改并批准它。一旦批准,该值将成为显示值,并且不需要保留旧版本

有人尝试过下面的解决方案吗?您将来自任何表的挂起的更改存储在一个特殊的PendingChanges表中,该表需要将这些更改作为XML进行跟踪?每个记录都有一个列,说明更改针对哪个表,一个列可能存储要更改的记录的id(如果是新记录,则为null),一个datetime列在更改时存储,以及一个列存储更改记录的xml(可能序列化我的数据对象)。因为我不需要历史记录,所以在批准更改后,将更新实际表,并删除PendingChange记录


对这种方法有什么想法吗

明确地将它们存储在主表中,并用一列指示数据是否已批准


批准变更后,无需复制。过滤未经批准的数据的额外工作是数据库应该做的事情,当您考虑它时。如果您为approved列编制索引,那么做正确的事情应该不会太麻烦。

我认为第二种方法是更好的方法,因为它可以更好地扩展到多个表。另外,额外的处理将是最小的,因为您可以基于“已批准”位创建表的索引,并且您可以将查询专门化为拉取已批准(用于查看)或未批准(用于批准)的条目。

大小是您的敌人。如果您处理的是大量数据和大量行,那么将历史数据与当前数据混合在一起将对您造成冲击。如果您加入到其他数据中,并确保获得了正确的行,那么您也会遇到问题

如果您需要保存历史数据以显示随时间的变化,我将使用单独的历史表,该表在批准后更新实时真实数据。这只是一个全面的清洁剂


如果有很多数据类型具有这种机制,但不需要保留历史记录,我建议使用一个公共队列来检查挂起的项,比如存储为xml。这将允许管理员只读取一个表,并使您能够相当轻松地将此功能添加到系统中的任何表中。

鉴于大多数公开交易公司面临的SOx合规运动,我在这方面有相当多的经验。通常我使用一个单独的表,带有时间戳,带有某种标志列的挂起更改。负责管理此数据的人员将获得挂起的更改列表,并可以选择接受或不接受。当一段数据被接受时,我使用触发器将新数据集成到表中。尽管有些人不喜欢触发器方法,宁愿将其编码到存储的进程中。这对我来说非常有效,即使在相当大的数据库中也是如此。复杂性可能会变得有点难以处理,特别是在处理一个变更与另一个变更直接冲突的情况以及处理这些变更的顺序时。保存请求数据的表永远不能被删除,因为它保存着“面包屑”,可以说是在需要追溯特定情况下发生的事情时所必需的。但在任何方法中,都需要对风险进行评估,比如我提到的冲突数据,并且需要一个业务逻辑层来确定这些情况下的流程


我个人不喜欢相同的表方法,因为在数据存储不断更改的情况下,表中的这些额外数据可能会不必要地阻塞表上的请求,并且需要更多关于如何索引表和执行计划的细节

由于这是一个web应用程序,我将假设读操作比写操作多,并且您需要一些相当快的操作,而您的冲突解决(即无序批准)也会导致相同的行为——使用的是最新的更新

您提出的两种策略都是相似的,它们每个更改集都有一行,必须处理冲突等,唯一的区别是将数据存储在一个表还是两个表中。在这种情况下,出于性能原因,两个表似乎是更好的解决方案。您还可以使用一个表和mos视图来解决这个问题
 CREATE OR REPLACE VIEW AS 

  SELECT * FROM my_table where approved = 1