Sql 日志表中的外键
嘿,这里有一个设计问题: 我正在从事一个项目,该项目要求我跟踪用户何时执行插入、更新或删除操作。我试图决定的是让Logs表引用受影响行的主键还是其他标识符。为了在使用外键时记录删除,我需要为每个表创建一个已删除列。然而,如果我使用的是没有外键的命名标识符,我最终会在Logs表中遇到名称重复,并且不清楚条目所指的是什么。是否有人对此有实际经验,特别是使用已删除列来维护完整日志对性能的影响 日志表本身的设计中也存在一个相关问题。如果我在单个日志表中使用外键引用,我的第一反应是为每个被监视更改的表创建一个引用列。这对我来说并不理想,好像我必须添加一个新表,然后更改Logs表和任何相关的存储过程。我可以看到的另一种选择是有两列,TableName和RowId。但这将没有固有的外键引用,因为它不知道引用的是什么表Sql 日志表中的外键,sql,sql-server-2008,database-design,Sql,Sql Server 2008,Database Design,嘿,这里有一个设计问题: 我正在从事一个项目,该项目要求我跟踪用户何时执行插入、更新或删除操作。我试图决定的是让Logs表引用受影响行的主键还是其他标识符。为了在使用外键时记录删除,我需要为每个表创建一个已删除列。然而,如果我使用的是没有外键的命名标识符,我最终会在Logs表中遇到名称重复,并且不清楚条目所指的是什么。是否有人对此有实际经验,特别是使用已删除列来维护完整日志对性能的影响 日志表本身的设计中也存在一个相关问题。如果我在单个日志表中使用外键引用,我的第一反应是为每个被监视更改的表创建
谢谢你的意见 日志表中不需要四列吗<代码>用户标识,
表名
,标识
,操作
Action
将是“delete”、“update”或“insert”,Id
将是相关表的主键,其余的都是不言自明的
这样,您就不必有很多列和外键,这只会使插入日志表的速度变慢。无论如何,您都需要使用触发器执行此操作,因此将表名添加到日志表中不会有问题。假设您跟踪的每个表的日志信息都相同,我将使用一个包含TableID和RowPKValue列的日志表。确实,您不能将RowPKValue移回每个单独的表,但是由于用户(或除您的log SP以外的任何代码)永远不会触及日志表,因此我认为它相当安全 我肯定会使用正在记录的行的PK值,而不是任何其他值(即使您没有引用它的FK),因为PK值就是用于此的 至于删除问题,我认为这取决于1)您希望执行的删除次数和2)您必须将“取消删除”作为应用程序的一部分的可能性 如果删除的次数相对较少,则可以使用“已删除”标志将其保留在表中,然后在指定的时间段结束后将其删除。如果您这样做,我建议使用一种方案,在该方案中,基本表被称为CustomerAll,并且您有一个表视图
CREATE view Customer AS SELECT*FROM CustomerAll,其中Deleted=false
,供前端程序员使用
如果您有大量的删除,我会在删除时将它们移动到第二个表(CustomerDeleted)中,甚至从数据库中移出,这取决于您认为需要再次查找它们的可能性。首先,取决于行数和索引类型,添加已删除的列可能比删除该行效果更好 其次,我认为最好的选择是将整行存储在日志表中(这将允许记录任何更新)。您还可以使用更规范化的日志表来实现这一点—类似于:
- 身份证
- 行动
- 有效列
- 旧价值
- 新价值
至于对行的标识符或其他值的引用,无论您如何操作,都会有相同的问题。为了识别影响的行,该行中也必须存在相同的唯一值。一旦该行被删除,唯一值(GUID(t-sql中的uniqueidentifier)也将被删除,顺便说一句,这是一个选项) 您也可以使用2表日志文件设置 LogA-日志id、表名、操作、日期和时间 LogB-日志ID、表ID、列更改、旧值、新值 (编辑到calrify,上面的“table_id”指的是该表中的主键。多个主键可能需要多个字段) 在new_value字段中使用空值表示删除,在旧值中使用空值表示插入 如果您希望避免在每个表上出现“已删除”列,则可以创建一个已删除表来存储已删除的行,并使用视图仅显示活动记录(即在已删除表中没有unqiue键的记录)
有很多有效的方法可以设计这个…RE:一个日志表而不是影子表 不过,这将是更多的工作,你不会从中得到那么多加布里埃尔·麦克亚当斯 我完全不同意 你的目标是: 跟踪用户何时执行插入、更新或删除 如果每个表都有一个影子表,您如何回答这些问题: