44

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

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

对这些方法或其他可能好的方法有任何个人经验吗?

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

任何人都尝试过下面的解决方案,您可以在特殊的 PendingChanges 表中存储任何需要将它们作为 XML 跟踪的表中的未决更改?每条记录都会有一列表示更改是针对哪个表的,一列可能存储将要更改的记录的 id(如果是新记录,则为 null),一个日期时间列,用于存储更改发生的时间,以及用于存储更改记录的 xml 的列(可能会序列化我的数据对象)。由于我不需要历史记录,因此在批准更改后,将更新真实表并删除 PendingChange 记录。

对这种方法有什么想法吗?

4

8 回答 8

21

绝对将它们存储在主表中,并用一列指示数据是否被批准。

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

于 2008-09-19T17:12:23.920 回答
12

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

如果您需要保存历史数据以显示随时间的变化,我会使用单独的历史表,一旦获得批准,它就会更新实时的真实数据。它只是全方位的清洁剂。

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

于 2008-09-19T17:16:14.007 回答
6

我在银行领域工作,我们有这样的需求——一个用户所做的更改必须在得到另一个用户的批准后才能反映。我们使用的设计如下

  1. 主表 A
  2. 另一个存储更改记录的表 B(因此与第一个完全相同)+ 2 个附加列(C 的 FKey 和指示更改类型的代码)
  3. 第三个表 C 存储所有需要批准的记录
  4. 存储历史的第四个表 D(您可能不需要这个)。

我推荐这种方法。它非常优雅地处理所有场景,包括更新和删除。

于 2008-09-19T18:16:32.737 回答
4

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

我个人不喜欢相同的表方法,因为在不断更改的数据存储的情况下,表中的这些额外数据可能会不必要地阻碍表上的请求,并且需要更多详细信息来了解您的操作方式正在索引表和您的执行计划。

于 2008-09-19T17:23:41.397 回答
2

另一个想法是拥有三张桌子。

  • 一个是保存原始数据的主表。
  • 第二个将保存建议的数据。
  • 第三个将保存历史数据。

这种方法使您能够快速轻松地回滚,并在需要时为您提供审计跟踪。

于 2008-09-19T17:44:37.900 回答
2

我会创建一个带有标志的表并创建一个类似的视图

 CREATE OR REPLACE VIEW AS 

  SELECT * FROM my_table where approved = 1

它可以帮助分离 aprovement 和查询之间的依赖关系。但如果需要对视图进行更新,这可能不是最好的主意。

移动记录可能有一些性能考虑。但是分区表可以做一些非常相似的事情。

于 2008-09-19T18:38:36.677 回答
1

由于这是一个网络应用程序,我将假设读取次数多于写入次数,并且您想要一些相当快的东西,并且您的冲突解决(即乱序批准)会导致相同的行为 - 最新更新是用来。

您提出的两种策略都相似,因为它们每个更改集都保留一行,必须处理冲突等,唯一的区别是是将数据存储在一个表还是两个表中。鉴于这种情况,出于性能原因,两个表似乎是更好的解决方案。如果您的数据库支持,您还可以使用一个表和最近批准的更改视图来解决此问题。

于 2008-09-19T17:36:46.810 回答
0

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

于 2008-09-19T17:14:24.743 回答