PostgreSQL 的 JSON, JSONB, HStore 好用么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
wwebrtsed

PostgreSQL 的 JSON, JSONB, HStore 好用么?

  •  1
     
  •   wwebrtsed 2021 年 9 月 16 日 3391 次点击
    这是一个创建于 1681 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前业务数据库用的是结构化的 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 的成本高不高呢? 主要指语法不同造成的语句重写...

    谢谢各位大佬!!!

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

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

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

    题外话,
    我认为完全可以存在大一统的数据库,采用图论数据库的基本模型并且根据实际需求写优化查询的方案。
    但是现在似乎普遍不希望数据库负担运算任务,即使实际业务的执行树已经复杂到数据库传输成本过高,也是每个前台添加 Redis 或者添加更多只读从库解决。
    mx1700
        9
    mx1700  
       2021 年 9 月 16 日 via Android
    @Huelse 求教 jsonb 与 kotlin 怎么搭配
    Huelse
        10
    Huelse  
       2021 年 9 月 16 日
    @mx1700 kotlin 用 jooq 之类的可以,前面打错了,更爽的是 scala 的 circe 和 quill
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1015 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 71ms UTC 18:41 PVG 02:41 LAX 11:41 JFK 14:41
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86