首页 > 解决方案 > 我应该使用 JSONB 还是 JOIN 表来记录 PostgreSQL 中的用户操作和注释?

问题描述

我正在设计一个数据库,我想在其中跟踪用户操作和注释的多个区域。

日志记录示例:

Sally edited this note at 11:34 on 11/25/2019
Matt changed note status from 'incomplete' to 'complete' at 13:57 on 12/15/2019

注释示例:

This customer is difficult to work with. - Matt 14:32 12/17/2019
Called customer, they told me they have a dog named George - Matt 18:32 12/17/2019

我的应用程序代码将格式化数据并将其解析为结构,如何做到这一点没有问题。

我的问题是,最好为每个表格使用单独的表格来记录笔记和日志。

我会有很多桌子,你可以想象它们都需要。其他用户需要能够记录的供应商/联系人/客户。

最好将这作为 JSON 存储在customers表中,每个用户操作都在操作 JSON 对象下,并且我基本上制作了一个不断扩展的数组?customers.notes就像

"notes": [{
  {
    "user": "Matt",
    "timestamp": "2019-04-21T16:18:18+00:00"
    "note": "Customer has a dog named fluffy"
  },
  {
    "user": "Sally",
    "timestamp": "2019-05-28T9:11:56+00:00"
    "note": "Called them just now"
  }
]

或者这会导致性能问题,我应该创建一个 JOIN 表和一个customers_noteandcustomer_log表,以及类似的其他表,如联系人、供应商等/

标签: postgresql

解决方案


RDBMS 最擅长的是将结构良好的数据存储在表中。jsonb当您处理的数据只是半结构化的,也就是说,当它们的结构因记录而异时,必须使用诸如字段之类的非 SQL 内容。一个典型的例子是某些数据库中的“附加信息”字段,其中每条记录都有一组不同的附加信息项。(SQL 纯粹主义者会说这样的数据库设计得很糟糕。)

这不是你的情况。

每个注释由一个操作员 ID、一个时间戳和一个小文本组成。添加另外两个字段(一个note_id自动递增的主键和customer_id要加入的外键),您就有了一个高效的notes表。使用它来回答各种问题(例如,“操作员 X 是否偏向于某些类别的客户?”)将比那些塞入客户表且难以处理的 json 数组更容易。

如果您的应用程序确实更喜欢 json 数组而不是记录集作为笔记,那么无论如何您都可以使用 json 格式的 PostgreSQL 答案json_agg(row_to_json(...))

至于性能,你告诉我们的太少,无法正确评估它的问题:一个客户会有多少笔记?多久需要一次?非常古老的笔记在当前的交互中是否真的相关?这些都是评估性能时要考虑的方面。


推荐阅读