将日志存储在 postgres 数据库中作为文本与 json 类型
Storing logs in postgres database as text vs json type
假设我们要创建一个 table 来将用户 activity 的日志存储在数据库中。我可以想到两种方法:
A table 每个日志条目都有一行,其中包含日志 ID、用户的外键和日志内容。这样,我们将为发生的每个 activity 单独一行。
A table 每个唯一用户(用户的外键)和日志 ID 的 activity 有一行。我们可以有一个 json
类型的列来存储与每个用户关联的日志。每次出现 activity 时,我们都可以获取关联的日志条目并通过向其附加新的 activity 来更新其 JSON 列。
方法 1 提供了一种无需更新旧日志条目即可添加新日志条目的简洁方法。但是查询这样一个 table 来获取用户的 activity 将查询整个 table.
方法 2 增加了添加新用户的复杂性 activity,因为我们必须获取和更新 JSON 对象,但查询只会 return 一行。
我需要帮助来了解一种方法是否明显优于另一种方法。
如果您记录了很多更改,就属性而言,我会创建一个 table 具有:
log_id
、user_id
(fk) 和 log
采用 json 格式,每行为一行 activity。
如果您为 table 编制索引,则不会出现性能问题。在 postgresql 中,您可以在 json 列内的字段上建立索引。
每次更新后,随着列大小的增加,方法 2 的更新速度会变慢。另外,查询会比较复杂。
数据库经过优化,可以从大 table 中存储和检索小行。因此,寻求第一个解决方案。索引使连接如此快速。
将一个用户的所有数据集中到单个 JSON 对象中不会让您满意:每次更新都必须读取、修改和写入整个 JSON,这在以下方面效率不高全部.
还要考虑一个可以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;
假设我们要创建一个 table 来将用户 activity 的日志存储在数据库中。我可以想到两种方法:
A table 每个日志条目都有一行,其中包含日志 ID、用户的外键和日志内容。这样,我们将为发生的每个 activity 单独一行。
A table 每个唯一用户(用户的外键)和日志 ID 的 activity 有一行。我们可以有一个
json
类型的列来存储与每个用户关联的日志。每次出现 activity 时,我们都可以获取关联的日志条目并通过向其附加新的 activity 来更新其 JSON 列。
方法 1 提供了一种无需更新旧日志条目即可添加新日志条目的简洁方法。但是查询这样一个 table 来获取用户的 activity 将查询整个 table.
方法 2 增加了添加新用户的复杂性 activity,因为我们必须获取和更新 JSON 对象,但查询只会 return 一行。
我需要帮助来了解一种方法是否明显优于另一种方法。
如果您记录了很多更改,就属性而言,我会创建一个 table 具有:
log_id
、user_id
(fk) 和 log
采用 json 格式,每行为一行 activity。
如果您为 table 编制索引,则不会出现性能问题。在 postgresql 中,您可以在 json 列内的字段上建立索引。
每次更新后,随着列大小的增加,方法 2 的更新速度会变慢。另外,查询会比较复杂。
数据库经过优化,可以从大 table 中存储和检索小行。因此,寻求第一个解决方案。索引使连接如此快速。
将一个用户的所有数据集中到单个 JSON 对象中不会让您满意:每次更新都必须读取、修改和写入整个 JSON,这在以下方面效率不高全部.
还要考虑一个可以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;