postgreSQLを使用したjson/jsonb固有オペレータクエリと従来の文字列比較クエリの比較

4038 ワード


日常のデータベースストレージではjsonフォーマットが使用される場合があります.jsonデータでjsonのキー値ペアをクエリーする必要がある場合は、json全体をクエリーし、バックグラウンドで解析して対応する値を得る必要があります.これは、データ量が特に膨大な場合に通常の方法を使用すると、リソースの浪費が少なくありません.
PostgreSQL 9.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]:[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フィールドを使用すると、他のデータベースではできない操作もできます.
ターゲット・オブジェクトのデータ量が非常に膨大であるため、1つのデータ・テーブルに格納されると非常に肥大化し、その属性を選択的にクエリーするには、他のデータ・テーブルに分解してプライマリ・テーブルに関連付ける必要があります.他の属性テーブルのデータが持つ属性は固定されていないため、json形式で格納するしかありません.次に、ターゲットオブジェクトの1つの属性のjson情報のうちの1つのキー値ペアをクエリーして、ターゲットオブジェクトの情報を取得します.
従来の手段では、データ設計時にクエリーが必要なフィールドとjsonデータを別々に列に区切るしかないが、これはライブラリの構築が規範化されていない現象をもたらし、フィールドをjsonに格納し、データ量が膨大であれば、非常に時間がかかる(すべてのjsonデータを検出し、フィルタリングする必要がある).