使用postgreSQL的json/jsonb特有操作符查询与传统字符串比较查询的对比

 

在日常数据库存储中有时会用到json格式,如果现在有在json数据中查询某个json中一个键值对的需求,就需要将整个json全部查询,然后在后台解析才能得到相应值,这在数据量特别庞大的情况下使用常规方式就会造成不小的资源浪费。

在PostgreSQL9.5中引入了新的JSONB功能,极大的增强了PG的NOSQL能力。使用其提供特别的特殊字符,能极大简化开发,以下是常规方式和jsonb方式的对比。

假设数据表"test"有以下数据 

id info
1 {"id": 4434, "des": "", "icon": "", "name": "model", "type": 5, "unit": null, "mtime": 1526522782397, "domain": null, "uitype": "Text", "caption": "型号", "defaultValue": null}
2 [{"id": "7404", "des": "执行结果成功与否", "icon": "", "name": "Result", "type": 1, "unit": null, "mtime": "1548231914408", "domain": null, "uitype": "Number", "caption": "执行结果", "defaultValue": null}]
3 [{"fid": 5435, "name": "osm_id", "value": "400767621"}, {"fid": 5436, "name": "code", "value": "5122"}, {"fid": 5437, "name": "fclass", "value": "residential"}, {"fid": 4113, "name": "name", "value": ""}, {"fid": -1, "name": "ref", "value": ""}, {"fid": -1, "name": "oneway", "value": "B"}, {"fid": -1, "name": "maxspeed", "value": "0"}, {"fid": -1, "name": "layer", "value": "0"}, {"fid": -1, "name": "bridge", "value": "F"}, {"fid": -1, "name": "tunnel", "value": "F"}]

如果要查询数据表id为3的info值中fid为5437的值

 

常规方式:

1.后台查询数据库 SELECT * FROM "test" WHERE ID = 3

2.解析json字符串(假如使用了fastjson):

public class TestService {
    public static void main(String[] args){
        String json = "[{\"fid\": 5435, \"name\": \"osm_id\", \"value\": \"400767621\"}, {\"fid\": 5436, \"name\": \"code\", \"value\": \"5122\"}, {\"fid\": 5437, \"name\": \"fclass\", \"value\": \"residential\"}, {\"fid\": 4113, \"name\": \"name\", \"value\": \"\"}, {\"fid\": -1, \"name\": \"ref\", \"value\": \"\"}, {\"fid\": -1, \"name\": \"oneway\", \"value\": \"B\"}, {\"fid\": -1, \"name\": \"maxspeed\", \"value\": \"0\"}, {\"fid\": -1, \"name\": \"layer\", \"value\": \"0\"}, {\"fid\": -1, \"name\": \"bridge\", \"value\": \"F\"}, {\"fid\": -1, \"name\": \"tunnel\", \"value\": \"F\"}]";
        dealJson(json);
    }

    public static void dealJson(String json){
        JSONArray objects = JSON.parseArray(json);
        objects.stream().forEach(obj ->{
            JSONObject jsonObject = JSON.parseObject(obj.toString());
            int fid = (int) jsonObject.get("fid");
            if (fid == 5437){
                System.out.println(obj.toString());
                return;
            }
        });
    }

得到的结果如下:{"fid":5437,"name":"fclass","value":"residential"}

 

 

postgresql的jsonb方式:

查询数据库:SELECT * FROM (SELECT t.* FROM test, jsonb_to_recordset(info) AS t(fid BIGINT, name text,value text) WHERE test.id=3) x WHERE fid = 5437;

这样就能直接查到相应的值。

 

postgreSQL中使用json/jsonb字段还能做到其他数据库做不到的一些操作

如果现在有一个需求:由于目标对象数据量非常庞大,存储在一个数据表中显得非常臃肿,并且如果要对其属性进行选择性查询就需要将其属性分解至其他数据表中与主表做关联,由于其他属性表中数据拥有的属性不是固定的,只能用json格式存储。现要对目标对象的其中一个属性的json信息中其中一个键值对进行查询获得该目标对象的信息;

如果使用常规手段------在数据设计的时候只能将需要查询的字段与json数据分隔开来单独成列,但这就造成了建库不规范的现象,如果将字段存储在json中而且数据量比较庞大,那将是一件非常耗时的事(需要将所有json数据查出遍历所有数据并筛选)。

 

 

你可能感兴趣的:(使用postgreSQL的json/jsonb特有操作符查询与传统字符串比较查询的对比)