代码之家  ›  专栏  ›  技术社区  ›  patmortech

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

  •  45
  • patmortech  · 技术社区  · 18 年前

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

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

    你对这些方法或其他方法有什么个人经验吗?

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

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

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

    8 回复  |  直到 18 年前
        1
  •  21
  •   nsayer    18 年前

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

    更改获得批准后,不需要复制。过滤未经批准的数据的额外工作是数据库应该做的事情,当你想到它的时候。如果你对已批准的列进行索引,那么做正确的事情应该不会太麻烦。

        2
  •  11
  •   Tom Carr    18 年前

    尺寸是你的敌人。如果你正在处理大量数据和大量行,那么将历史数据与当前数据混合会让你感到头疼。如果你加入其他数据并确保你有正确的行,你也会遇到问题。

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

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

        3
  •  6
  •   Yossi Kreinin    18 年前

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

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

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

        4
  •  4
  •   stephenbayer    18 年前

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

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

        5
  •  2
  •   wcm    18 年前

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

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

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

        6
  •  2
  •   borjab    18 年前

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

     CREATE OR REPLACE VIEW AS 
    
      SELECT * FROM my_table where approved = 1
    

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

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

        7
  •  1
  •   craigb    18 年前

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

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

        8
  •  0
  •   jdmichal    18 年前

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