在 SQL Server 2008 R2 中为实体设计批准队列和审计跟踪的最佳方法是什么?

Dan*_*Dan 6 sql-server-2008 best-practices

简化说明:我有三个主要表:customer、phone 和customer_phone 来解决多对多问题。我需要确保只有管理员才能在未经批准的情况下插入/更新这些表。其他所有人都需要将他们的东西放入批准队列,以便管理员批准。管理员需要在批准/拒绝之前查看当前值和提议的更改。系统应该在审计跟踪中记录谁提交了信息,谁批准了它(如果适用),以及任何修改它的人。当前采用的方法为每个实体提供三个表:

  1. 主实体表
  2. 未批准记录的保存表
  3. 每个实体的审计日志表

我认为应该有一些更简单的解决方案。当前系统在以下情况下存在问题:

  • 管理员在主实体被批准之前尝试批准一个实体,它链接到
  • 该记录已存在于数据库中,但需要批准将其链接到另一条记录

这对我来说似乎不是最佳解决方案。有没有更好的办法?

更长的解释:这是场景的简化视图:我有一个主要实体和次要实体通过链接表链接到它。管理员可以随意添加/编辑任何实体,但标准用户必须在更改生效之前获得管理员的批准。问题是,有时当标准用户输入主实体和链接实体时,管理员必须先批准主实体,链接才能生效。我希望管理员能够在批准之前查看旧值和提议的新值,并且我希望确保他们首先批准主要实体。例如,假设我们有下表,客户是主要实体,电话是次要实体,然后有一个链接表来解决多对多关系:

CREATE TABLE [dbo].[customer](
  [Customer_ID] [int] NOT NULL,
  [Customer_Name] [varchar](255) NOT NULL,
PRIMARY KEY CLUSTERED ([Customer_ID] ASC)

CREATE TABLE [dbo].[phone](
  [Phone_ID] [int] NOT NULL,
  [Phone_Number] [int] NOT NULL,
PRIMARY KEY CLUSTERED ([Phone_ID] ASC)

CREATE TABLE [dbo].[customer_phone](
  [Customer_Phone_ID] [int] NOT NULL,
  [Customer_ID] [int] NOT NULL,
  [Phone_ID] [int] NOT NULL,
  [Approved] [char](1) NOT NULL, --Y/N
PRIMARY KEY CLUSTERED ([Phone_ID] ASC)
Run Code Online (Sandbox Code Playgroud)

现在,只有管理员才能在未经批准的情况下添加客户或电话号码。如果标准用户想要添加某人,它会进入一个保留表。这就是目前在我的系统中的样子。除了以上表格:

CREATE TABLE [dbo].[customer_holding](
  [Customer_ID] [int] NOT NULL,
  [Customer_Name] [varchar](255) NOT NULL,
  [Standard_User_ID] [int] NOT NULL, --who added record
PRIMARY KEY CLUSTERED ([Customer_ID] ASC)

CREATE TABLE [dbo].[phone_holding](
  [Phone_ID] [int] NOT NULL,
  [Phone_Number] [int] NOT NULL,
  [Standard_User_ID] [int] NOT NULL, --who added record
PRIMARY KEY CLUSTERED ([Phone_ID] ASC)
Run Code Online (Sandbox Code Playgroud)

以编程方式标准用户提交的内容将转到保留表,直到管理员批准它们。但是,我还需要提交原始记录的用户以及批准记录和更新记录的用户的审核日志。当前系统通过每个记录的第三个审计表来实现这一点:

CREATE TABLE [dbo].[customer_audit](
  [Customer_ID] [int] NOT NULL,
  [User_ID] [int] NULL,
  [When_Approved] [datetime] NOT NULL,
  [Approved] [char](1) NOT NULL, --Y/N
PRIMARY KEY CLUSTERED ([Customer_ID] ASC)

CREATE TABLE [dbo].[phone_audit](
  [Phone_ID] [int] NOT NULL,
  [User_ID] [int] NULL,
  [When_Approved] [datetime] NOT NULL,
  [Approved] [char](1) NOT NULL, --Y/N
PRIMARY KEY CLUSTERED ([Phone_ID] ASC)

CREATE TABLE [dbo].[customer_phone_audit](
  [Customer_Phone_ID] [int] NOT NULL,
  [User_ID] [int] NULL,
  [Action_Performed] [datetime] NOT NULL,
PRIMARY KEY CLUSTERED ([Phone_ID] ASC)
Run Code Online (Sandbox Code Playgroud)

本质上,每个实体表都有一个保存表和一个审计表,用于与该实体关联的操作。这对我来说似乎是多余且有问题的,尽管当前系统确实主要使用这种设计。我认为应该有一些更简单的解决方案。当前系统在以下情况下存在问题:

  1. 在客户被批准链接到该电话之前,管理员尝试批准该电话
  2. 该电话号码已存在于数据库中,但需要批准将其链接到其他客户

这些问题似乎可以通过更好的设计来解决。什么可以做得更好?每个实体的三个表对我来说似乎是多余的,有没有更好的方法?谢谢,

JNK*_*JNK 5

您可以通过向现有表中添加一些字段来大大简化此操作。

添加:

  • ChangeDate-smalldatetime表示添加记录的时间
  • Active —— BIT
  • ChangeBy - 添加记录的用户
  • ApprovedBy - 确认记录的管理员

您保留所有旧记录,因此更新实际上只是一个新行,然后ACTIVE将旧记录的位更改为关闭,新记录的位更改为开启。您的审计跟踪内置于您的数据中。

用于公开数据的视图可以过滤 ACTIVE 位,因此不会发出未经批准的更改。它还将有助于解决冲突,因为每个提议的更改都有争议。如果两个用户提议更改,管理员可以选择一个接受,或者创建一个新条目来合并它们。