1

语言:C#
编译器:Visual Studio 2012
操作系统:Windows 7 Home Premium

这是一个关于许多问题的问题,并且经过了几次辩论。
我知道目前有针对功能时间线的临时 .net 控件,以及有关如何完成流程的提示和技巧,但我(到目前为止)还没有找到关于维护良好的 SQL 存储时间线系统的完整教程.

我需要记录我的网站几乎所有的变化。从增加用户声誉,到加入/创建和最终提交成员、部落游戏等。
据我所知,应该避免使用 SQL 数据库中的DateTime,尤其是大量使用。

时间线的实施、过程和最终输出是什么?

4

1 回答 1

2

您所描述的有时被称为“审计历史” - 它通常使用单个非规范化表来实现,但是当您失去强类型时,许多数据库纯粹主义者会反对它。

该表如下所示:

AuditTable( EventId bigint, DateTime datetime, Subject nvarchar, Table varchar, Column varchar, TablePK bigint, OldValueInt bigint nullable, OldValueStr nvarchar nullable )
-- add more nullable columns for more types, if necessary

每次更改值时,例如增加用户的声誉,您将在此表中添加一行,例如:

INSERT INTO AuditTable( Now(), N'User reputation increased', 'Users', 'Reputation', @userId, 100 )

您只需要存储旧值(更改前的值),因为新(即当前)值将在实际表行中。

使用 SQL Server 表触发器可以完全自动添加到审计表。

要查看用户的信誉历史记录,您可以执行以下操作:

SELECT * FROM AuditTable WHERE Table = 'Users' AND Column = 'Reputation' AND TablePK = @userId

现在正如我所说,这种设计更多的是用于审核而不是维护易于用户访问的历史记录,这些是缺点:

  • 您无法对表进行语义索引,因此查找和列表总是很慢
  • 您将数据库元数据存储为字符串,因此有很多开销
  • 没有参照完整性(这可能是一件好事,因为如果您重新构建原始表,数据将保留,例如从用户表中删除 Reputation 字段)

如果你想更“纯粹”,那么你真的必须设计一个直接支持你想要构建的历史跟踪的表结构。您不需要为每个字段创建历史记录表 - 即使 Stackoverflow 也不会存储所有内容的历史记录。例如:

 UserReputationHistory ( UserId bigint, ReputationChange int, DateTime when, Subject nvarchar )

当然,必须维护这些不同的 FooHistory 表确实会使您的代码复杂化。

您评论的原始问题中的其他内容,例如成员的加入日期不需要历史记录表,您可以从DateJoined成员自己的数据库行中的字段中获取。

于 2012-09-17T19:14:18.287 回答