存储去年的每月分析数据

时间:2019-08-27 10:30:56

标签: database postgresql

我正在尝试存储过去12个月(即一年)用户每月发送的电子邮件数量。每个月都有两个值,分别是成功发送的电子邮件数和由于任何原因而失败发送的电子邮件数。

我的数据库是支持JSON数据的PostgreSQL。我在想这样的事情:一列存储所有每月数据,其结构如下:

{
    "08-2019": {"successes": 348, "fails": 1},
    "07-2019": {"successes": 947, "fails": 7},
    "06-2019": {"successes": 428, "fails": 2},
    "05-2019": {"successes": 638, "fails": 5},
    "04-2019": {"successes": 354, "fails": 2},
    "03-2019": {"successes": 693, "fails": 0},
    "02-2019": {"successes": 461, "fails": 9},
    "01-2019": {"successes": 211, "fails": 1},
    "12-2018": {"successes": 414, "fails": 3},
    "11-2018": {"successes": 627, "fails": 7},
    "10-2018": {"successes": 241, "fails": 2},
    "09-2018": {"successes": 124, "fails": 4}
}

换句话说,键是带有年份的月份,并且它们存储具有成功和失败次数的另一个JSON对象。仅当发送电子邮件时才会更新此结构。因此可以说,在2019年9月期间,电子邮件已成功发送。由于数据库中不存在键“ 09-2019”,因此将删除最旧的键“ 09-2018”,并添加一个新的键值对,显然是"09-2019": {"successes": 1, "fails": 0}。 9月发送另一封电子邮件时,密钥已经存在,因此只需对其进行更新。

有时会发生的情况是,在某些月份中,不会发送任何电子邮件,因此,该月份中的结构中没有数据。我想在查询过程中解决此问题。当用户从数据库检索此分析数据时,将创建一个新的JSON数据,其中的密钥将是最近12个月,并且每个密钥的值均为{"successes": 0, "fails": 0}。然后将比较这两种结构。新的JSON结构将被更新,以便数据库中存在的任何键,该键的值都将被数据库中的键替换。然后,此新结构将返回给用户,因此他们将仅看到最近12个月的数据。

我的问题是:这是一个好主意吗?我不知道分析数据如何存储在生产中,在我的用例中,我不能分配大量资源来存储大量数据,因为这只是一个附带项目,资金非常有限。

1 个答案:

答案 0 :(得分:1)

  1. 我不建议使用JSON,因为当数据增长时,您将面临问题。如果您只喜欢JSON,则至少使用JSONB数据类型,在其中可以使用很少的索引,而JSON类型列没有适当的索引来提高性能。

  2. 在我们不了解模式的大多数情况下,建议使用
  3. JSON类型列,但是对于您的情况,您可以有效地使用其他类型列。您可以像下面这样实现。

date_keys表将包含诸如id, date_valuedata表将具有date_keys_id, success_count, failed_count之类的列,您可以在其中存储每个日期的数据。

通过这种方式,即使表大小增加,也可以有效地进行查询。我面对JSON的许多问题,这就是为什么建议这种方式。

在date_keys表中,可以使用brin索引来固定查询,在data表中,可以使用常规类型索引btree来固定查询。

例如。

date_keys: id = 1, date_value = '10-2018'

data: date_keys_id = 1, success_count = 10, failed_count = 0