【问题标题】:Should I extract the "time" part of "timestamp" into "json" data type?我应该将“时间戳”的“时间”部分提取为“json”数据类型吗?
【发布时间】:2021-10-27 13:32:13
【问题描述】:

我正在设计一个数据库(postgresql),它可以存储用户全天的膳食,并且将来会根据这些日常信息进行每周、每月或每年的分析。我最初的设计是有一个meals 表,看起来像:

meals(表名)

  • id(主键)
  • user_id(外键)
  • picture_ids
  • 标签
  • 注意
  • 时间戳

通过这种结构,查询用户在指定的用餐数据可以先过滤mealsuser_id,再过滤timestamp。而对于一个用户,一天的多餐会插入多条记录。


另一种方法是使用 [json 或 jsonb 类型](https://www.postgresql.org/docs/current/datatype-json.html) 从 `timestamp` 中提取“时间”部分,因此 `timestamp` 仅包含 ' year', 'month', 'date',因此我可能有一个名为 `meals_of_day` 的表:

meals_of_day(表名)

  • id(主键)
  • user_id(外键)
  • 记录(json类型
  • 日期

records 列中的数据可能如下所示:

{
  "08:30": {
    picture_ids: [1,2],
    labels: ['meat', 'apple'],
    note: 'meat was too salty'
  },

  "12:45": {
    // some data
  },

  "19:05": {
    // some data
  }
}

这样一个用户每天只有一行,插入一顿饭实际上是更新user+date对应行的records列。



  1. 当用户登录用餐时,哪种方法的响应时间更短?
  2. 如果分析功能涉及大量与时间相关的查询,哪种方法更有效?

谢谢。

【问题讨论】:

  • 我认为响应时间差异是过早的优化。即使一个速度快 50%……您可能在谈论亚毫秒级的差异。我会考虑许多其他考虑因素(例如这些方法如何影响您的应用程序层、前端等),但不会考虑写入性能的差异。
  • 您希望对哪些与时间相关的查询进行分析?您可以对 JSONB 内的键进行索引,因此可以对嵌套的 JSON 数据进行非常高效的查询,但这在很大程度上取决于您要执行的操作。

标签: sql json postgresql database-design database-schema


【解决方案1】:

在这两种方法中(并且对您的应用层、前端架构等一无所知),我更喜欢meals 表方法。它很简单,相当灵活(似乎对如何使用数据做出了一些假设),防止了 jSONB 结构上可能的更新冲突,并且在需要时可以很容易地从(到 mails_per_day 方法或其他方法)迁移出现。

【讨论】:

  • 谢谢@melcher。您的 cmets 和回答确实提到了一些我没有考虑过的问题。 meals_of_day 方法降低了查询的一些复杂性,但失去了一些灵活性。在该列上使用jsonjsonb 需要more effort to implement constrains。前端仍处于原型设计阶段,如果您有兴趣,我会构建 a low fidelity prototype on figma
  • 还有一个名为states 的表,它接收用户关于他们在某一时刻的感受的输入。 statesmeals 将显示在同一时间线上,以提供有关他们的饮食习惯与状态之间关系的可能见解。这个timeline + meals + states 图表可以以不同的比例(日、周、月等)查看。每个meal的主要数据是用户拍摄的照片,我最初的想法是在meals表中实现一个array类型的外键列(见问题描述中的picture_ids)来引用照片数据.
  • Postgres (目前)不支持外键数组。见stackoverflow.com/questions/41054507/…
  • 取而代之的是,您可以在图片表上使用 meals_id 外键或使用连接表(例如,“meals_pictures”带有图片 ID 和餐点 ID)
  • 我考虑了连接表和外键数组。我想我可能会使用一个数组来保存一顿饭的所有图片 id,然后使用包含检查来查找所有相应的图片——例如:select * from pictures where id = ANY(picture_ids_of_a_meal);mentioned here。但正如答案所说,这不能保持参照完整性,所以我认为连接表更可行。感谢@melcher :)
猜你喜欢
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2019-08-11
  • 2012-09-02
  • 1970-01-01
  • 2021-06-25
  • 1970-01-01
  • 2017-03-26
相关资源
最近更新 更多