最近我想到了将历史数据存储在MySQL数据库中的最佳实践。目前,每个可版本化的表都有两列 - valid_from
和valid_to
,两个DATETIME
类型。包含当前数据的记录在其创建日期填充了valid_from
。当我更新此行时,我会在valid_to
中填写更新日期,并在上一行中添加valid_from
与valid_to
相同的新记录 - 简单的内容。但是我知道这个表格会非常快,所以获取数据可能会很慢
我想知道你是否有存储历史数据的做法?
答案 0 :(得分:9)
担心“大”表和性能是一个常见的错误。如果您可以使用索引来访问您的数据,那么如果您有1000条1000000条记录并不重要 - 至少不是您能够衡量的。你提到的设计是常用的;这是一个很棒的设计,时间是业务逻辑的关键部分。
例如,如果您想知道客户下订单时商品的价格是多少,那么就能够搜索产品记录,其中valid_from< order_date和valid_until为null或> order_date是迄今为止最简单的解决方案。
情况并非总是如此 - 如果您仅为了存档目的而保留数据,那么创建存档表可能更有意义。但是,您必须确保时间确实不是业务逻辑的一部分,否则搜索多个表的痛苦将是巨大的 - 想象每次都必须搜索产品表或product_archive表您想在下订单时了解产品的价格。
答案 1 :(得分:0)
这不是完整的答案,只是一些建议。
您可以添加像is_valid
这样的索引布尔字段。这应该通过包含历史和当前记录的大表来提高性能。
一般而言 - 在seprate表中存储历史数据可能会使您的应用程序复杂化(想象一下应该通过混合当前和历史记录获取数据的查询的复杂性......)。
今天电脑真的很快。我认为您应该将性能与单个表和单独的表进行比较/测试以获取历史记录。
此外 - 尝试测试您的硬件,看看MySQL与大表的速度有多快,以确定如何设计数据库。如果它对你来说太慢了 - 你可以调整MySQL配置(从增加缓存/ RAM开始)。
答案 2 :(得分:0)
我即将完成一个正是这样做的应用程序。我的大多数索引首先按键字段索引,然后根据当前记录设置为valid_to
的{{1}}字段,从而可以轻松,即时地找到当前记录。由于我的大多数应用程序都处理实时操作,因此索引提供了快速的性能。偶尔有人需要查看历史记录,并且在那种情况下会有性能损失,但是通过测试它并不太糟糕,因为大多数记录在其生命周期内没有很多变化。
如果您可能拥有比当前记录多得多的各种密钥的过期记录,则可能需要在任何关键字段之前对valid_to 进行索引。