PG 中 JSON 字段的应用
13 年发现 pg 有了 json 类型,便从 oracle 转 pg,几年下来也算比较熟稔了,总结几个有益的实践。
用途一:存储设计时无法预料的文档性的数据。比如,通常可以在人员表准备一个 json 类型字段,名字叫 info、tag 之类。人员表是系统很难设计的表,常常需要扩充各类信息,如驾照号、社保号等等,在设计时不能全盘考虑到,这些信息的特点是用于登记、检索,但与其它表没有外键关系。有的信息有多个,比如教育经历,包含有中学大学研究生等等。以往需要分出子表或以嵌套表存储,实现复杂,ER 图规模庞大。引入 JSON 类型后,此类嵌套表几乎都可以合并入 JSON 字段。
又如,网站系统的会员信息中需要保存用户的 APP 设置,这类设置取决于设备程序,专属于该会员,可将设置定义为 JSON 类型,具体需要保存什么信息由 APP 自己掌握。以往也将设置定义为文本,文本丢失了结构,不能适应会员有多个设备(会员可能同时拥有 Android、iOS 两种设备)的情形,JSON 类型拥有数据结构,可以表达 {设备类型: 设置:{}}。
可见,JSON 字段就像可以装入大象的冰箱,打开了这道门就可以存储无尽的信息。采用 JSON 字段后,数据库设计阶段只需要考虑主要业务实体之间的结构,抓大放小,设计思路也更清晰而不至于琐碎。我们知道,软件系统是一个生长的过程,很多东西在设计初期都难以预料,考虑再周详也有未尽之处,何况随着系统使用,需求变更,原以为是属性的,可能要改为数组,原以为是 flat 数组的,可能发现要改用对象数组,这些变迁屡见不鲜,如果采用静态设计,Schema 需要反复调整,对于使用SSH 框架进行开发的,每次调整带来的变动更多。JSON 类型使系统设计更能适合系统不断的演变进化。
将嵌套表放在 JSON 字段中,也避免了 JOIN 带来的性能损失。但有时需要从子表进行检索,如需要查询教育经历包含本科的所有人,这种场景还是应当使用子表,或 JSON 信息和子表同时使用,子表仅用于此类需要从子表出发的检索,这种数据冗余是值得的。
用途二:合并表间继承。表间继承关系通常采用“主从表同主键、从表主键外键到主表主键”实现,PG 数据库还有专门的表继承设计。引入 JSON 类型后,不少继承可以取消。例如,之前常用的组织机构与公司、部门、科室为继承关系,以往公司表、部门表、科室表都从组织机构表继承。引入 JSON 后子类表取消,合并到组织机构表,该表通过 TYPE 字段区分是何种类型的组织机构,对于不同类型的TYPE,其 INFO 字段(JSON) 拥有不同的结构。
这是由于 JSON 数据没有固定结构,每个 JSON 对象都是自说明的,都可以拥有自己的结构,不像静态语言的对象只能获得从类型定义规定的结构。
用途三:从功能角度进行更高级别的抽象。
13 年编写过一个 ETL 工具,在异构数据库中间同步数据。该工具需要将源数据库的数据采集到中心,再由中心分发到目标数据库,数据要在中心 进行存储。中心应该是中立于数据的,不应考虑传输的数据是服装信息、药品信息、还是人员信息,其只应具备传输保管能力,不应具备业务知识,如同 TCP 一样,不应理解传输的是视频还是 HTML,不能为传输HTML搞一个TCP,为传输视频另搞一个TCP。
站在 ETL 功能的视角,所传输的内容都可以理解为对象,据此,可将采集到的数据行不识别结构的全部压缩到一个名为 OBJECT 的 JSON 字段。另外在实际使用时还要考虑对象之间的主从依赖关系,在新增数据时,先新增主表行,再新增子表行,在删除数据时反之。因此,还需要记忆所属对象。最终这个转储中心数据表结构如下:
ID OBJECT TYPE PARENT_ID(FK:ID)
该表其它外围字段此处不赘述。
同样,设计流程系统可着眼于工作环节,将工作环节的其它信息,如地点等等压缩进 JSON 字段,根据这条原理我曾设计过一个万能的 task – actor 表结构,将之前若干貌似各不相干的业务合并为前后相续的 task。
activiti 如能用这种思路组织 task 等信息,当可达到更灵活便利的效果。
-----------
d2js 框架高度支持 json 类型数据,数据库的 json 取出即成为编程语言的对象,编程语言的对象也可直接存入数据库,不需要借助 ORM 映射方式,为开发带来了极大便利。
在没有使用 json 前,很多人担心 json 字段是一个整体无法检索。这个担心大可不必,json 字段存储的对象也可对其属性进行检索,并可建立索引。当然,也不是没有缺陷,作为一个整体,在更新时会一次性引发若干索引的更新。但相比得到的优势来说,优势更为明显。
另外,在实践中 pg 应使用 jsonb 字段类型,而不是 json 类型,jsonb 是 9.5 后推出的 binary 方式存储的 json 类型,类似 mongodb 的 bson,而 json 类型是字符串方式存储的,显然 jsonb 更节约空间且效率更高。
pg 提供了不少极有用的 json 操作符和函数,应一一试验做一个接触式了解。
PostgreSQL: Documentation: 9.6: JSON Functions and Operators
https://www.postgresql.org/docs/9.6/static/functions-json.html
PG 中 JSON 字段的应用的更多相关文章
- MySQL中JSON字段的使用技巧
mysql5.7.8之后开始原生支持json. 在类似mongodb这种nosql数据库中,json存储数据是非常自然的, 在mysql中合理的使用json,能够带来极大的便利 Json字段的使用场景 ...
- npm的package.json字段含义中文文档
简介 本文档有所有package.json中必要的配置.它必须是真正的json,而不是js对象. 本文档中描述的很多行为都受npm-config(7)的影响. 默认值 npm会根据包内容设置一些默认值 ...
- mysql中,通过json_insert函数向json字段插入键值?json_insert函数的使用?
需求描述: 通过json_insert向json字段中插入值,在此进行实验,记录下. 操作过程: 1.查看已经有的包含json数据类型的表 mysql> select * from tab_js ...
- mysql数据库中,如何对json数据类型的值进行修改?通过json_set函数对json字段值进行修改?
需求描述: 今天在看mysql中存放json数据类型的问题,对于json数据进行修改的操作, 在此记录下. 操作过程: 1.创建包含json数据类型的表,插入基础数据 mysql> create ...
- mysql中,创建包含json数据类型的表?创建json表时候的注意事项?查询json字段中某个key的值?
需求描述: 在mysql数据库中,创建包含json数据类型的表.记录下,在创建的过程中,需要注意的问题. 操作过程: 1.通过以下的语句,创建包含json数据类型的表 mysql> create ...
- Mysql中处理JSON字段
处理json字段,可以用json_extract函数: select * from (select json_extract(ext_value,'$.high')+0 highx,batch_id ...
- mysql 和mssql2016中的json字段相关操作
Mysql: mysql中有专门的Json字段,不是通用的varchar字段,可以保存key/value对,也可保存value集合. 可以增加.删除.修改Json中的某一字段,查询时可以为条件. 如果 ...
- ios中json解析出现的null问题
http://my.oschina.net/iq19900204/blog/408034 在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个 ...
- easyui datagrid中datetime字段的显示和增删改查问题
datagrid中datetime字段的异常显示: 使用过easyui datagrid的应该都知道,如果数据库中的字段是datetime类型,绑定在datagrid显式的时候会不正常显示,一般需要借 ...
随机推荐
- 图像处理中任意核卷积(matlab中conv2函数)的快速实现。
卷积其实是图像处理中最基本的操作,我们常见的一些算法比如:均值模糊.高斯模糊.锐化.Sobel.拉普拉斯.prewitt边缘检测等等一些和领域相关的算法,都可以通过卷积算法实现.只不过由于这些算法的卷 ...
- BZOJ 3529: [Sdoi2014]数表 [莫比乌斯反演 树状数组]
3529: [Sdoi2014]数表 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1399 Solved: 694[Submit][Status] ...
- 010商城项目:商品类目的选择——Dao,Service.Action层的分析
我们现在开始写商品类选择这个功能: 先看效果: 当我们点击"新增商品"---->"选择目录"然后从数据库中查出来数据并显示了. 我们分析数据库的那张表: ...
- linux 项目部署问题
1.ubuntu 安装 pillow 报错 缺少依赖包 pip install Pillow ValueError: zlib is required unless explicitly disabl ...
- Android/Linux下CGroup框架分析及其使用
1 cgroup介绍 CGroup是control group的简称,它为Linux kernel提供一种任务聚集和划分的机制,可以限制.记录.隔离进程组(process groups)所使用的资源( ...
- jQuery-DataTables相关的网址
DataTables 有没有觉得这张图的数据很熟悉,对,他们都是copy来的. 之前用了一个bootstrap的框架,写那个框架的老师,有点抠门,把很多js都合在了一起,不知道怎么去自定义自己的东西, ...
- QQ,微信第三方登陆
感觉越是大公司的SDK越不好用,其实我也是一直在想为什么他们拿那么高的工资却干着不相应的事儿. 下面说下QQ和微信第三方登陆的一点坑 首先 (QQ互联)自带的sdk中 一个文件工程没有调用产生关联错 ...
- Bzoj3041 水叮当的舞步
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 132 Solved: 75 Description 水叮当得到了一块五颜六色的格子形地毯作为生日礼物 ...
- lightbox使用
使用方法: 1.在页面头部包含 lightbox.js 文件并加载 lightbox.css 样式表文件 <script type="text/javascript" src ...
- 说说APP接口中的版本控制
引言 接口是APP的重要组成部分,数据是APP的核心,接口是连接APP和数据的纽带. 一般情况下,APP中会有大量的接口,再加上版本的变化,接口的升级,一个接口 可能会衍生出很多个稍有差异的接口,这个 ...