存储活动/非活动时间戳

时间:2015-08-10 14:26:20

标签: sql ruby-on-rails ruby json postgresql

我在带有PostgreSQL后端的Rails应用程序上运行ruby,我想知道存储一系列时间戳的标准方法是什么。情况是我有一个布尔status属性的模型。我需要跟踪此属性更改的日期/时间,因为我需要跟踪status设置为true的时间段。我对这类问题的经验严重缺乏,而且我不确定以可扩展的方式做这种事情的最佳做法是什么。我考虑过的两种方法是:

1)JSONifying文本。我正在考虑采用可能如下所示的数组:

[
  { 
      start: "20150131103045",
      end: "20150228103045"
  },
  { 
      start: "20150531103045",
      end: "20150628103045"
  },
]

然后,我会将此数组JSONify并将其存储在text列中。

2)创建一个单独的表格,其中包含model_idstatustime_recorded属性列,然后每次模型创建一个条目{{{ 1}}属性已更新。

这些方法中哪一个更健全?这里需要考虑的是这些数据可能不会经常被读取 - 在95%的情况下,它只是被写入数据库的新数据。

选项1)对我来说似乎不那么苛刻,但是在我需要的时候读取数据并对其进行排序也会是一个更大的痛苦。选项2)将以更容易使用的方式存储数据,并且永远不需要读取/更新预先存在的数据,但是表格可能非常快,非常快。这个问题是我必须在我的应用程序中使用多个模型执行此操作,因此从一开始就做出仓促的决定并实施一个糟糕的架构可能会让以后处理起来很烦人。

这两种方法的优点和缺点是什么?这些中的任何一个显然是比另一个更好的解决方案吗?或者还有其他更好的选择,我还没有想过?

1 个答案:

答案 0 :(得分:1)

选项1:

你必须考虑连续进行更新时,Postgres会在后台创建该行的另一个版本,并在其上添加新数据,并在该表中完成真空时标记旧版本。正如您所看到的,这将导致大量“真空工作”(将其视为高磁盘/ IO工作量)。如果行的数据不适合单个数据页,那将是最糟糕的。在这种情况下,还有一个“toast”表也要被抽真空。

选项2:

这看起来更好的方法,因为一旦插入行,您将永远不会更新它。并且数据看起来足够小以适合单个数据页面(不需要Toast表)。如果使用正确的索引,则不会出现性能问题。 Postgres可以轻松处理数百万条记录。

此外,您可以使用patitioning table技术。如果你的表有数十亿和数十亿的历史记录,你可以将它“分割”成几个其他表(例如每月一个),其中每个表的索引非常小并且运行速度非常快。一切都在后台完成,因此您的应用程序将只看到“主”表,Postgres将自动处理所有其他拼接表。

如果您需要以JSON格式检索数据,也很容易。你可以创建一个视图(或者你想做的函数),其中具有“开始/结束”时间的列将以JSON数组格式安装(使用postgres 9.3及更高版本)。