我正在数据库中设计一个表,它将存储来自应用程序的日志条目。有一些东西让我比平常更多地考虑这个设计。
我在想的是将它们写入实时表/数据库,然后使用ETL解决方案将“旧”条目移动到存档表/数据库 - 这很大且速度较慢。
我的问题是你知道有关数据库/表格设计的任何提示,技巧或建议,以确保尽可能好吗?如果您认为这是一个坏主意,请告诉我,以及您认为更好的想法。
答案 0 :(得分:3)
有些数据库提供“分区”(例如Oracle)。分区就像一个视图,它将具有相同定义的多个表收集到一个中。您可以定义将新数据分类到不同表中的条件(例如,月份或年份%6)。
从用户的角度来看,这只是一个表。从数据库PoV,它是几个独立的表,因此您可以以有效的方式对它们运行全表命令(如截断,删除,从表中删除(没有条件),加载/转储等)。
如果您没有分区,则会对视图产生类似的效果。在这种情况下,您可以在一个视图中收集多个表,并重新定义此视图,例如,每月一次,以从其余表中使用旧数据“释放”一个表。现在,您可以有效地归档此表,清除它并在完成大量工作时将其再次附加到视图中。这应该有助于提高绩效。
[编辑] SQL Server 2005及更高版本(企业版)支持分区。感谢Mitch Wheat
答案 1 :(得分:1)
大表速度很快,使用ETL从大表中提取数据,然后删除旧行是一个很大的性能开销。答案是使用多个表 - 根据您的数字,可能是1个表/月。当然,您需要一些逻辑来在查询中生成表名。
我同意使用触发器填充'CurrentMonthAudit'表,在月末,您可以将该表重命名为MonthAuditYYYYMM。使用ETL将旧表从主服务器上移开将很容易,并且每个表都是可管理的。相信我,这比尝试管理大约250M行的单个表要好得多。
答案 2 :(得分:1)
你的第一个好决定是让一切尽可能简单。
我对你的简单只写事务日志文件的模式运气不错,其中记录按时间顺序排列。然后,您有多个选项可用于切换老化数据。只要记住简单性,即使每月使用不同的表也是可管理的查询。如果您正在运行任何类型的复制,则可以推出复制的表并将其用作存档。然后在每个月的第一天用新的空桌开始。
通常我对做这样的事情的关系设计后果不寒而栗,但我发现只写时间顺序日志表是常见设计模式的一个例外,原因就在于你在这里处理。
但要远离触发器。越远越好。最简单的解决方案是您在这里讨论的类型的主表,具有简单强大的现成时间证明的复制机制。
(顺便说一句 - 如果设计得很好,大型桌子不会很快减速 - 它们会慢慢减速。)
答案 3 :(得分:0)
如果您不需要搜索最近的日志记录,还有另一种选择:根本不使用数据库。而是将日志信息写入文件并每晚旋转文件名。写入文件后,您可以启动后台作业,将数据直接导入存档数据库。
数据库并不总是最佳选择,尤其是对于日志文件:)