使用数据库行存储有关行的元数据?

时间:2011-09-01 16:12:56

标签: sql sql-server schema auditing

有关

以银行间财务转移为例。 Transfer可能如下所示:

CREATE TABLE Transfers (
   TransferID int,
   FromTransit varchar(10),
   FromBranch varchar(10),
   FromAccount varchar(50),
   ToTransit varchar(10),
   ToBranch varchar(10),
   ToAccount varchar(50),
   Amount money,
   Status varchar(50));

但是现在,人们当然希望看到元数据:

ALTER TABLE Transfers 
ADD
    CreatedDate datetime,
    LastModifiedDate datetime,
    CreatedByUsername varchar(50),
    CreatedByFullname varchar(200),
    CreatedByWorkstation varchar(50),

    VoidedDate datetime NULL,
    VoidedByUsername datetime NULL,
    VoidedByFullname datetime NULL,
    VoidApprovedBySupervisorUsername varchar(50) NULL,
    VoidApprovedBySupervisorFullname varchar(200) NULL,
    VoidApprovedBySupervisorWorkstation varchar(50) NULL,

    SentDate datetime NULL, 
    SentByUsername varchar(50) NULL,
    SentByFullname varchar(50) NULL,
    SentByWorkstation varchar(50) NULL,
    SendApprovedBySupervisorUsername varchar(50) NULL,
    SendApprovedBySupervisorFullname varchar(50) NULL,
    SendApprovedBySupervisorWorkstation varchar(50) NULL,
    SendConfirmationNumber varchar(50) NULL,
    SentToRemoteMachineName varchar(50) NULL,

    ReceivedDate datetime NULL, 
    ReceivedConfirmationNumber varchar(50) NULL,
    ReceivedToRemoteMachineName varchar(50) NULL,
    ReceivedByUsername varchar(50) NULL,
    ReceivedByFullname varchar(50) NULL,
    ReceivedByWorkstation varchar(50) NULL,
    ReceiveApprovedBySupervisorUsername varchar(50) NULL,
    ReceiveApprovedBySupervisorFullname varchar(50) NULL,
    ReceivedApprovedBySupervisorWorkstation varchar(50) NULL,

    ReceivedCheckedBySupervisorUsername varchar(50) NULL,
    ReceivedCheckedBySupervisorFullname varchar(50) NULL,
    ReceivedCheckedBySupervisorWorkstation varchar(50) NULL
)

这些都是明确定义的值,它们都会出现在与转移相关的硬拷贝上。

我们已经对表中的更改进行了审计记录,但这不会发生类似的事情:

UPDATE Transfers SET Status = 'TransferStatus_Received'
WHERE TransferID = 6744891

它会捕获进行更改的人的用户名 fullname 计算机名称;但是它无法知道主管的名字,该主管在人的肩膀上输入他们的凭证以“授权”转移被接收。

当他们要求跟踪另一个信息时,我的恶化就来了,我必须在数据中添加更多元数据列表

这是最佳做法吗?

2 个答案:

答案 0 :(得分:2)

这不是财务数据库的好习惯,因为您允许更新。如果您允许更新,那么记录,审核,加密密钥或您添加的任何内容都无关紧要,因为敌对方可以更新它们。

相反,你必须禁止更新;所有更改必须是插入。所有表都应具有索引顺序FK列,并且所有联接都在Max(seq)上。这意味着您对最新数据执行所有事务,但具有这些表上每个事务的永久记录。

编辑:如果您要问的是是否应将审核列添加到原始表中,则这取决于审核列是稀疏还是可空的。从你的评论来看,它们似乎都是。

在这种情况下,您应该为每个可空的审计属性组创建单独的表,并在这些表上执行外连接,并与原始数据库的顺序列连接。这意味着您可以随意添加或删除审计表,而不会影响数据表。类似的东西:

SELECT t.transferID, t.money, u.Date, u.workstation, s.name, ...
FROM Transfers t
    LEFT OUTER JOIN Users u ON u.seq = t.seq
    LEFT OUTER JOIN Supervisors s ON s.seq = t.seq
WHERE t.seq = (SELECT Max(seq) FROM Transfers WHERE whatever)

如果您需要在事务中重复使用,可以创建一个保存Max(seq)的视图或存储过程。

答案 1 :(得分:1)

我对SQL Server了解不多,但在Oracle场景中遇到这种情况时,我倾向于使用触发器(插入/更新/删除),将完整的行(之前和之后)转换为“归档/审计”表并添加他们希望与其一起记录的任何“元数据”......这样,我的以应用程序为中心的数据模型不会对应用程序/ SP等有所影响,并且没有应用程序/用户可以访问该敏感的日志记录/审计信息。 ..