自然关键审计表

时间:2013-01-07 19:41:37

标签: sql-server database database-design relational-database

我正在设计带有自然密钥的SQL Server表,而不是主键的代理键。我遇到的问题是它与我过去使用Surrogate Key表的Audit表格式不兼容。通常,我将创建一个与正在审计的表具有相同列的审计表。正在审计的表上的触发器将新行写入审计表,该行与更新或删除之前的行的状态相匹配。为了实现完整性,我使用Surrogate Key和修改日期列作为表的复合PK。如果我不使用代理键,那么如果组成组合键的其中一列发生更改,则无法跟踪更改。

Log table example with Surrogate Key:

LogId (PK)
LogType
Data
ModifedDate
ModifedBy

LogAudit Table for Log table with Surrogate Key:

LogId (PK)
LogType
Data
ModifedDate (PK)
ModifedBy 


Log table example with Natural Key:

LogType (PK)
Data
ModifedDate (PK)
ModifedBy

LogAudit Table for Log table with Natural Key:
LogType 
Data
ModifedDate
ModifedBy 

如果LogType或ModifiedDate发生变化,如何跟踪Audit表中的Natural Key Log表记录的更改?

2 个答案:

答案 0 :(得分:2)

我认为你在这里误解了基本概念。

如果{LogType, ModifedDate}表是Log表中的自然键(情况2),那么第一个表中的替换密钥(AK)(唯一)也是如此示例

所以第一个例子中的Log表看起来像这样。

LogId        (PK)
LogType      (AK1.1)
Data
ModifedDate  (AK1.2)
ModifedBy 

因此,对于给定的{LogID}{LogType, ModifedDate}无法更改,反之亦然。

但是,这不是你想要完成的。答案可能是你的Log表首先没有“自然键”。


根据评论

编辑

根据经验,创建基于行的审计表:

  1. 复制原始表格结构(列)。

  2. 在表格中添加ChangedAt(日期时间)和ChangedBy列。

  3. ChangedAt列添加到原始PK。

  4. 将PK列的副本添加到表中。这是为了捕获任何PK变化。

  5. 使用ON UPDATE CASCADE添加FK,ON DELETE NO ACTION。这可以防止硬删除,因此请使用软删除。

  6. 从原始表上的AFTER INSERT,UPDATE触发器填充。

  7. 示例1

          Table: {ID, SomeData}                               ; key: {ID} 
    audit table: {ID, SomeData, ChangedAt, ChangedBy, ID_CPY} ; key: {ID, ChangedAt}
    

    示例2

          Table: {UserID, UserOrderNo, SomeData}                       ; key: {UserID, UserOrderNo} 
    audit table: {UserID, UserOrderNo, SomeData, ChangedAt, ChangedBy, UserID_CPY, UserOrderNo_CPY} ; key: {UserID, UserOrderNo, ChangedAt}
    

    示例3 (根据您的描述)

          Table: {LogType, ModifedDate, SomeData}                       ; key: {LogType, ModifedDate} 
    audit table: {LogType, ModifedDate, SomeData, ChangedAt, ChangedBy, LogType_CPY, ModifedDate_CPY} ; key: {LogType, ModifedDate, ChangedAt}
    

答案 1 :(得分:0)

嗯,特别是那个自然键很奇怪。 你有两套钥匙,自然和代理,没有任何限制。 我会将两个表混合使用LogID for PK并为LogType + ModifiedDate创建一个唯一索引,这样你就可以使用单个字段PK来连接表(我认为这是一件好事)并且你有自己的业务/自然无论你需要什么钥匙(仍然是唯一的,不是主要的)。