你描述的内容有时被称为“审计历史” - 它通常使用单一的非规范化表格来实现,但是很多DB纯粹主义者会在你失去强大的输入时反对它。
表看起来是这样的:
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
现在,这样的设计更加审核,而不是保持一个轻松的用户访问的历史,这些都是缺点:
- 你不能语义索引的表,所以查找和列表将永远是慢
- 你存储数据库的元数据作为字符串,所以有很多的开销
- 没有参照完整性(这可能是一件好事,因为如果重新构建原始表格,数据将保持不变)从用户表中删除信誉字段)
如果你想要更“纯”,那么你真的必须设计一个表结构,直接支持你想要建立的历史追踪。您不需要为每个字段创建历史记录表 - 即使Stackoverflow不存储所有内容的历史记录。例如:
UserReputationHistory (UserId bigint, ReputationChange int, DateTime when, Subject nvarchar)
当然,它确实使代码复杂化,不得不维护这些不同的FooHistory表。
在您原来的问题中,您评论的其他内容(如成员的加入日期)不需要历史记录表,您可以从成员自己的数据库行中的DateJoined
字段中获取该信息。
来源
2012-09-17 19:14:18
Dai
使用'DateTime'没有什么问题 - 您只需要知道如何正确使用它(例如总是以UTC存储值,并注意到.NET和MSSQL具有不同的最小值(0001-01-01 vs 1753 -01-01) – Dai
将1个表存储所有这些数据(请注意,有**可能**是一个很大的增长潜力的网站)能够管理,而被查询了很多? – TheGeekZn