【问题标题】:Storing logs in postgres database as text vs json type将日志存储在 postgres 数据库中作为文本与 json 类型
【发布时间】:2021-08-14 23:35:43
【问题描述】:

假设我们要创建一个表来在数据库中存储用户活动日志。我可以想到两种方法:

  1. 每个日志条目都有一行,其中包含日志 ID、用户的外键和日志内容。这样,我们将为发生的每个活动单独设置一行。

  2. 每个唯一用户的活动(用户的外键)和一个日志 ID 有一行。我们可以有一个json 类型的列来存储与每个用户关联的日志。每次发生活动时,我们都可以获取关联的日志条目并通过将新活动附加到它来更新其 JSON 列。

方法 1 提供了一种无需更新旧日志条目即可添加新日志条目的简洁方式。但是查询这样的表来获取用户的活动会查询整个表。

方法 2 增加了添加新用户活动的复杂性,因为我们必须获取和更新 JSON 对象,但查询只会返回一行。

我需要帮助来了解一种方法是否明显优于另一种方法。

【问题讨论】:

  • 我猜,对于第 1 点。将日志保存为 csv,使用 fdw 查询文件...我记得一个 aws 工程师制作了一些脚本来将日志(在 csv 中)导入到表中( aws.amazon.com/blogs/database/…)

标签: sql postgresql database-design


【解决方案1】:

数据库经过优化,可以在大表中存储和检索小行。所以选择第一个解决方案。索引使连接变得如此之快。

将用户的所有数据集中到单个 JSON 对象中不会让您满意:每次更新都必须读取、修改和写入整个 JSON,这根本没有效率。

【讨论】:

    【解决方案2】:

    如果您记录大量更改,就属性而言,我会创建一个表:

    log_iduser_id (fk) 和 log 采用 json 格式,每一行作为一个活动。

    如果您为表编制索引,则不会出现性能问题。在 postgresql 中,您可以对 json 列中的字段进行索引。

    随着列大小的增加,每次更新后方法 2 的更新速度都会变慢。此外,查询会更复杂。

    【讨论】:

      【解决方案3】:

      另外考虑一个可以parse semi-structured data into database columns的日志框架,比如Serilog。

      否则我也会推荐您的选项“1”,即每个日志一行,并在 user_id 上有一个索引,但建议在您的列中添加时间戳,以便查询引擎可以在必须解析之前按事件顺序排序json 本身作为时间戳:

      CREATE TABLE user_log
      (
          log_id             bigint, -- (PRIMARY KEY),
          log_ts             timestamp NOT NULL DEFAULT(now()),
          user_id            int NOT NULL, --REFERENCES users(user_id),
          log_content        json
      );
      CREATE INDEX ON user_log(user_id);
      
      SELECT user_id, log_ts, log_content => 'action' AS user_action FROM user_log WHERE user_id = ? ORDER BY log_ts;
      

      【讨论】:

        猜你喜欢
        • 2016-08-20
        • 1970-01-01
        • 2020-01-15
        • 2014-08-06
        • 2013-03-05
        • 1970-01-01
        • 2013-07-13
        • 1970-01-01
        • 2014-12-03
        相关资源
        最近更新 更多