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 字段的应用的更多相关文章

  1. MySQL中JSON字段的使用技巧

    mysql5.7.8之后开始原生支持json. 在类似mongodb这种nosql数据库中,json存储数据是非常自然的, 在mysql中合理的使用json,能够带来极大的便利 Json字段的使用场景 ...

  2. npm的package.json字段含义中文文档

    简介 本文档有所有package.json中必要的配置.它必须是真正的json,而不是js对象. 本文档中描述的很多行为都受npm-config(7)的影响. 默认值 npm会根据包内容设置一些默认值 ...

  3. mysql中,通过json_insert函数向json字段插入键值?json_insert函数的使用?

    需求描述: 通过json_insert向json字段中插入值,在此进行实验,记录下. 操作过程: 1.查看已经有的包含json数据类型的表 mysql> select * from tab_js ...

  4. mysql数据库中,如何对json数据类型的值进行修改?通过json_set函数对json字段值进行修改?

    需求描述: 今天在看mysql中存放json数据类型的问题,对于json数据进行修改的操作, 在此记录下. 操作过程: 1.创建包含json数据类型的表,插入基础数据 mysql> create ...

  5. mysql中,创建包含json数据类型的表?创建json表时候的注意事项?查询json字段中某个key的值?

    需求描述: 在mysql数据库中,创建包含json数据类型的表.记录下,在创建的过程中,需要注意的问题. 操作过程: 1.通过以下的语句,创建包含json数据类型的表 mysql> create ...

  6. Mysql中处理JSON字段

    处理json字段,可以用json_extract函数: select * from (select json_extract(ext_value,'$.high')+0 highx,batch_id ...

  7. mysql 和mssql2016中的json字段相关操作

    Mysql: mysql中有专门的Json字段,不是通用的varchar字段,可以保存key/value对,也可保存value集合. 可以增加.删除.修改Json中的某一字段,查询时可以为条件. 如果 ...

  8. ios中json解析出现的null问题

    http://my.oschina.net/iq19900204/blog/408034 在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式. 问题现象 但是几个 ...

  9. easyui datagrid中datetime字段的显示和增删改查问题

    datagrid中datetime字段的异常显示: 使用过easyui datagrid的应该都知道,如果数据库中的字段是datetime类型,绑定在datagrid显式的时候会不正常显示,一般需要借 ...

随机推荐

  1. List集合的removeAll(Collection<E> col) 和clear方法的区别

    //removeAll()方法private static void testList(){ List<String> list = new ArrayList<String> ...

  2. 【原】为什么选择iPhone5的分辨率作为H5视觉稿尺寸

    [20160105更新:可以用iPhone6分辨率为视觉稿尺寸啦] 又是一年的520网络情人节,深圳这边却下了大雨,这雨只能是单身汉的泪,而对于我来说这一天具有特别的意义,一来怀念父亲,二来对我这种结 ...

  3. AC日记——滑动窗口 洛谷 P1886

    题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...

  4. JQuery中$.ajax()方法参数详解 及 async属性说明

    url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...

  5. xml解析

    config.xml <?xml version="1.0" encoding="UTF-8"?> <prize> <gift&g ...

  6. jquery.mobiscroll仿Iphone ActionSheet省市区联动

    1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="u ...

  7. Paxos

    Paxos算法原理与推导   Paxos算法在分布式领域具有非常重要的地位.但是Paxos算法有两个比较明显的缺点:1.难以理解 2.工程实现更难. 网上有很多讲解Paxos算法的文章,但是质量参差不 ...

  8. c#线程带参数

    c#线程带参数 ThreadStart threadStart = delegate { LoadPicture(ds.Tables[0]); }; Thread thread = new Threa ...

  9. 【前端积累】常用事件的js公用方法

    var eventUtil={ // 添加句柄 addHandler:function(element,type,handler){ if(element.addEventListener){ ele ...

  10. Cookie的应用

    作用:在浏览器当中用cookie来保存参数,比如实现登录功能时用来保存账号 <%@ page language="java" import="java.util.* ...