将更改存储到需要获得批准才能可见的数据库记录的最佳方法是什么?
我需要将用户输入的更改存储到特定表中,但在管理员用户查看并批准这些更改之前,不要显示这些更改。当这些更改仍处于待处理状态时,我仍将显示数据的旧版本。存储这些更改以等待批准的最佳方法是什么?
我已经想到了几种方法,但是无法弄清楚什么是最好的方法。这是一个非常小的网络应用程序。一种方法是拥有一个模仿另一个表的架构的PendingChanges表,然后在批准更改后,就可以使用该信息更新实际表。另一种方法是执行某种记录版本控制,其中我将数据的多个版本存储在表中,然后始终提取具有被标记为已批准的最高版本号的记录。这将限制额外表的数量(我需要针对多个表执行此操作),但是每次我提取一组记录以确保获得正确的记录时,都需要我进行额外的处理。
使用这些方法或者其他方法的个人经验可能不错吗?
更新:只是要澄清一下,在这种特殊情况下,我对历史数据并不太感兴趣。我只需要某种方法就可以批准用户在网站上发布之前所做的任何更改。因此,用户将编辑其"配置文件",然后管理员将查看该修改并批准。一旦批准,它将成为显示的值,并且不需要保留旧版本。
有人尝试过下面的解决方案,我们在其中存储了需要在特殊的PendingChanges表中以XML形式将其跟踪的任何表中的未决更改吗?每条记录都有一个列,该列指出要更改的表,一个列,该列可能存储要更改的记录的ID(如果是新记录,则为null),一个存储更改时间的datetime列,一列存储更改记录的xml(可能会序列化我的数据对象)。由于我不需要历史记录,因此在批准更改后,将更新实际表,并删除PendingChange记录。
对这种方法有什么想法吗?
解决方案
绝对将它们存储在主表中并带有一列,以指示数据是否被批准。
批准更改后,无需复制。当我们考虑时,过滤未经批准的数据的额外工作是数据库应该做的事情。如果我们为批准的列编制索引,那么做正确的事情就不会太麻烦。
我认为第二种方法是更好的方法,只是因为它可以更好地扩展到多个表。另外,额外的处理将是最少的,因为我们可以基于" approved"位为表创建索引,并且可以专门化查询以拉出批准(用于查看)或者未批准(用于批准)条目。
大小是你的敌人。如果我们要处理大量数据和大量行,那么将历史记录与当前数据混在一起会给我们带来麻烦。如果我们加入其他数据并确保行正确,也会遇到问题。
如果我们需要保存历史数据以显示随时间的变化,我将使用单独的历史表,该表在获得批准后会更新实时的真实数据。只是全方位清洁剂。
如果我们有很多具有这种机制的数据类型,但又不需要保留历史记录,那么我建议我们使用一个通用的队列表来复审待处理的项目,例如存储为xml。这将允许管理员仅读取一个表,并使我们能够相当轻松地将此功能添加到系统中的任何表。
鉴于大多数公开交易的公司都对SOx合规性提出了强烈要求,因此我在这方面有很多经验。通常,我一直在使用带有时间戳的未决表以及带有某些标志列的未决更改。负责管理此数据的人员将获得未决更改的列表,可以选择接受还是不接受。当一条数据被接受时,我使用触发器将新数据集成到表中。尽管有些人不喜欢触发方法,而是希望将其编码到存储的proc中。即使在相当大的数据库中,这对我来说也很好用。处理复杂性可能会有些困难,尤其是在处理一个更改与另一更改直接冲突以及处理这些更改的顺序冲突的情况下。保存请求数据的表永远无法删除,因为它会可以说是"面包屑",如果需要追溯在特定情况下发生的情况,这是必需的。但是,无论采用哪种方法,都需要评估风险,例如我在冲突数据中提到的风险,并且需要在这些情况下建立业务逻辑层以确定流程。
我个人不喜欢相同的表方法,因为在数据存储不断变化的情况下,表中的这些额外数据可能会不必要地使表上的请求陷入困境,并且将需要更多有关我们如何操作的详细信息正在索引表和执行计划。
由于这是一个网络应用程序,我将假设读取的次数多于写入的次数,并且我们想要的速度相当快,并且冲突解决(即无序批准)导致相同的行为-最新的更新是用过的。
我们提出的两种策略是相似的,因为它们每个变更集都只占一行,必须处理冲突等,唯一的区别是是否将数据存储在一个或者两个表中。在这种情况下,出于性能原因,两个表似乎是更好的解决方案。如果数据库支持,我们也可以使用一个表和一个最近批准的更改的视图来解决此问题。
还有一个想法是拥有三个桌子。
- 一个将是保存原始数据的主表。
- 第二个将保存建议的数据。
- 第三个将保存历史数据。
这种方法使我们能够快速轻松地回滚,并在需要时提供审计跟踪。
我在银行业工作,我们有一个需求,即一个用户所做的更改必须在另一位用户批准后才能反映出来。我们使用的设计如下
- 主表A
- 另一个表B存储更改后的记录(因此与第一个完全相似)+ 2个添加列(C的FKey和指示更改类型的代码)
- 第三个表C存储所有需要批准的此类记录
- 存储历史记录的第四个表D(我们可能不需要此表)。
我推荐这种方法。它非常优雅地处理了所有情况,包括更新和删除。
我将创建一个带有标志的表并创建一个类似的视图
CREATE OR REPLACE VIEW AS SELECT * FROM my_table where approved = 1
它可以帮助分离证明和查询之间的依赖关系。但是如果需要对视图进行更新,可能不是最好的主意。
移动记录可能有一些性能方面的考虑。但是分区表可以做一些非常相似的事情。