PostgreSQL 的 JSON, JSONB, HStore 好用么?

2021-09-16 17:08:36 +08:00
 wwebrtsed

目前业务数据库用的是结构化的 SQL, 但考虑到业务需求, schema 可能不太稳定, 随着时间变化, 会有新字段的增加, 和老字段的删除, 感觉比较适合用 NoSQL, 或者 SQL + NoSQL 的组合.

研究了下发现, 貌似 PG 的 JSON, JSONB, HStore 数据类型对 NoSQL 支持比较好, 有没有用过的朋友给点意见? 比如函数啊, 性能啊.

另外, 表里也要存 GIS 数据, 正常 SQL 的话, 就存 geometry, geography 数据类型了, 那么如果改用 JSON/JSONB/ HStore 字段的话, 那么 GIS 数据怎么在这几种 NoSQL 的字段里面存? 会不会导致不能用 PostGIS 的一些函数? Django 对这几种数据类型的支持咋样? 因为要用 DRF 做后端...

或者用混合式的? SQL + NoSQL? 比较稳定的字段用 SQL, 除此之外的不确定稳不稳定的字段用 NoSQL 存储?

还有比较纠结的一点是, 业务上的其他很多小工具应该还是用 SQL 写的查询逻辑, 如果这些字段用 NoSQL 的话, 这些个工具的 Refactoring 的成本高不高呢? 主要指语法不同造成的语句重写...

谢谢各位大佬!!!

2555 次点击
所在节点    PostgreSQL
10 条回复
ElmerZhang
2021-09-16 17:55:49 +08:00
一般只把不作为业务中查询条件的数据放在 JSON 、JSONB 、HStore 这类字段中。
比如我设计表时经常保留一个字段叫做 extra_info 或者 extend 之类,存一些未来有可能扩展的属性。
如果后加的字段需要作为业务查询条件,可以考虑加个扩展表来存,表中字段为 id, item_id, key, value 。其中 item_id 加索引,(key, value, item_id) 做联合索引。
GIS 数据存在 NoSQL 字段里之后,我印象中是可以用 PostGIS 函数的,已经多年不用,不是很确定,楼主还是自己验证一下。
dzdh
2021-09-16 18:03:58 +08:00
无需过度担心性能问题。GIN 索引还是很强的。

HStore 解析可能是个问题。
wwebrtsed
2021-09-16 18:08:56 +08:00
@ElmerZhang 谢谢兄台解答!
但我们的业务中, 随时间变化, 可能新增或减少的字段也是会进入查询条件的.... 非常不幸.
所以这种情况下, 有没有好的解决办法呢? 还是说只能用 SQL 这一套, 到时候手工进入数据库增删字段...
Huelse
2021-09-16 18:10:31 +08:00
推荐 jsonb,如果是 kotlin 开发就更爽了
bthulu
2021-09-16 18:23:15 +08:00
上 mongodb 啊
hanssx
2021-09-16 18:40:48 +08:00
python postgreSQL sqlalchemy jsonb 用得也舒服
jabari
2021-09-16 18:55:16 +08:00
@wwebrtsed #3 复杂查询还是上 ES 吧
2i2Re2PLMaDnghL
2021-09-16 19:24:58 +08:00
具体选型的问题还考虑到你的前瞻性。
你说的 schema 不稳定,但其实如果不是记录间有差异(比如每个人有不同的职业,各种职业具有不同的参数,导致要么字段重载,要么大量空字段),否则 SQL 没有问题,都不过是用着爽不爽的问题。
记录间有差异其实也可以用辅表。

如果又要不确定的字段又要进行查询,是典型的需要 ES 的情况。但得问你是不是真的需要压这点性能。我记得说 PG 的 JSON 是可以作为查询条件的(只是效率问题)。

题外话,
我认为完全可以存在大一统的数据库,采用图论数据库的基本模型并且根据实际需求写优化查询的方案。
但是现在似乎普遍不希望数据库负担运算任务,即使实际业务的执行树已经复杂到数据库传输成本过高,也是每个前台添加 Redis 或者添加更多只读从库解决。
mx1700
2021-09-16 20:03:04 +08:00
@Huelse 求教 jsonb 与 kotlin 怎么搭配
Huelse
2021-09-16 21:54:43 +08:00
@mx1700 kotlin 用 jooq 之类的可以,前面打错了,更爽的是 scala 的 circe 和 quill

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/802338

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX