數倉的兩種輕量級數據交換格式:json與jsonb

来源:https://www.cnblogs.com/huaweiyun/p/18145941
-Advertisement-
Play Games

JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,常用於將數據從伺服器發送到Web應用程式。 ...


本文分享自華為雲社區《GaussDB(DWS)——探究JSON,JSONB》,作者:yd_283975606。

1. 前言

  • 適用版本:【8.1.1(及以上)】

JSON(JavaScript Object Notation)是一種輕量級的數據交換格式,常用於將數據從伺服器發送到Web應用程式。它採用人類易讀和機器易解析的文本格式,基於鍵值對的集合,用於表示結構。

2. json/jsonb簡介

json演進歷程

版本

 

8.1.1

支持JSON數據類型

8.1.2

支持JSONB高級特性、索引

9.1.0

支持JSON列存、向量化,JSONB支持索引

2.1 json/jsonb簡介

參考DWS產品文檔,JSON數據類型可以用來存儲JSON(JavaScript Object Notation)數據。

可以是單獨的一個標量,也可以是一個數組,也可以是一個鍵值對象,其中數組和對象可以統稱容器(container):

標量(scalar):單一的數字、bool、string、null都可以叫做標量。
  • 數組(array):[]結構,裡面存放的元素可以是任意類型的JSON,並且不要求數組內所有元素都是同一類型。
  • 對象(object):{}結構,存儲key:value的鍵值對,其鍵只能是用“”包裹起來的字元串,值可以是任意類型的JSON,對於重覆的鍵,按最後一個鍵值對為準。

2.2 json與jsonb的區別

存儲方式

json是輸入字元串的完整拷貝,使用時再去解析,所以它會保留輸入的空格,重覆鍵以及順序等;

jsonb解析後存儲,刪除語義無關的細節和重覆的鍵,對鍵值也會進行排序,使用時不用再次解析。

性能差別

json由於精確拷貝,因此插入時性能較好,但是其在處理函數時,必須在每個執行上重新解析,因此其查詢性能一般;

jsonb 數據以分解的二進位格式存儲, 這使得它由於添加了轉換機制而在輸入上稍微慢些。但是其由於插入後即預設有序排列,因此可以更好地支持的額外操作(如bool關係的比較,頂層元素存在的判斷)。並且,其在處理函數時, 不需要重新解析,查詢性能較好。同時,jsonb支持創建btree、gist和gin索引。

3. json/jsonb輸入格式

1.標量(scalar):輸入為數字、布爾類型時,使用單引號 ’ '聲明,輸入為字元串時必須加 " "聲明

json_database=# SELECT '[1, 2, "foo", null, [[]], {}]'::jsonb;
             jsonb
-------------------------------
 [1, 2, "foo", null, [[]], {}]
(1 row)

2.數組(array):使用中括弧[]包裹,滿足數組書寫條件。數組內元素類型可以是任意合法的JSON,且不要求類型一致。

json_database=# SELECT '[1, 2, "foo", null, [[]], {}]'::jsonb;
             jsonb
-------------------------------
 [1, 2, "foo", null, [[]], {}]
(1 row)

3.對象(object):使用大括弧{}包裹,鍵必須是滿足JSON字元串規則的字元串,值可以是任意合法的JSON。

json_database=# SELECT '{"a": 1, "b": {"a": 2,  "b": null}}'::json;
                json
-------------------------------------
 {"a": 1, "b": {"a": 2,  "b": null}}
(1 row)

4.嵌套數組和對象:數組array中可以是任意合法的json元素,對象object則嚴格遵循了key:value的格式,兩者結合可以方便地有序查找json值。

json_database=# SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::jsonb;
                        jsonb
-----------------------------------------------------
 {"foo": [true, "bar"], "tags": {"a": 1, "b": null}}
(1 row)

4. DWS的json與jsonb能力

當前DWS支持創建列存json、jsonb。

4.1 常用的json/jsonb函數及操作符(jsonb為例,json同理)

1.jsonb_object_field(jsonb, text)

描述:輸入的json類型為json-object,返回指定鍵對應的值(可能為json-object或json-array)

對應操作符:->

返回類型:jsonb

json_database=# SELECT jsonb_object_field('{"a": {"b":"foo"}}','a');
 jsonb_object_field
--------------------
 {"b": "foo"}
(1 row)

json_database=# SELECT '{"a":{"b":"foo"}}'::jsonb->'a';
  ?column?
-------------
 {"b":"foo"}
(1 row)

2.jsonb_array_element(array-jsonb, integer)

描述:輸入的json類型為json-array,返回數組中指定下標的元素(為任意合法的JSON)

對應操作符:->

返回類型:jsonb

json_database=# SELECT jsonb_array_element('[1,true,[1,[2,3]],null]',2);
 jsonb_array_element
---------------------
 [1, [2, 3]]
(1 row)

json_database=# SELECT '[1,true,[1,[2,3]],null]'::jsonb->2;
  ?column?
-------------
 [1, [2, 3]]
(1 row)

3.jsonb_extract_path((jsonb, VARIADIC text[])

描述:輸入為json-object或json-array,返回$2所指路徑的值。$2中可以為json-object對應的鍵值(字元串類型),也可以為json-array對應的下標(整數類型)

對應操作符:#>

註意:GaussDB(DWS)對象標識符支持以符號"#“結尾,為避免a#>b解析過程出現歧義,因此操作符”#>"前後需要增加空格,否則解析報錯。

返回類型:jsonb

json_database=# SELECT jsonb_extract_path('{"f2":{"f3":1},"f4":{"f5":99,"f6":["stringy",1,true]}}', 'f4','f6',2);
 jsonb_extract_path
--------------------
 true
(1 row)

json_database=# SELECT '{"f2":{"f3":1},"f4":{"f5":99,"f6":["stringy",1,true]}}'::jsonb #> '{f4,f6,2}';
 ?column?
----------
 true
(1 row)

4.2 jsonb高級特性

1.jsonb會丟棄空格等語義無關的細節

json_database=# select '   [1, " a ", {"a"   :1    }]  '::jsonb;
        jsonb
----------------------
 [1, " a ", {"a": 1}]
(1 row)

2.jsonb會預設對輸入鍵值的重新排序

json_database=# insert into test_json values('{"C":1,"B":2,"A":false}','{"C":1,"B":2,"A":false}');
INSERT 0 1
json_database=# select *from test_json;
           jj            |              jb
-------------------------+------------------------------
 {"C":1,"B":2,"A":false} | {"A": false, "B": 2, "C": 1}
(1 row)

比較規則如下:

首先比較類型:object-jsonb > array-jsonb > bool-jsonb > num-jsonb > str-jsonb > null-jsonb

同類型則比較內容:

  • str-json類型:依據text比較的方法,使用資料庫預設排序規則進行比較,返回值正數代表大於,負數代表小於,0表示相等。
  • num-json類型:數值比較
  • bool-json類型:true > false
  • array-jsonb類型:長度長的 > 長度短的,長度相等則依次比較每個元素。
  • object-jsonb類型:長度長的 > 長度短的,長度相等則依次比較每個鍵值對,先比較鍵,再比較值。

5.總結

DWS的JSON能力總結

目前,DWS的JSON/JSONB的功能基本完善。主要體現在函數、操作符、索引功能的支持。但目前來說,JSON列存仍然採用的是直接存儲JSON數據,即將原始的JSON數據存成單獨的一列,以完整的JSON值作為最小的粒度在磁碟上,具體如下:

json_data

{“user_id”:1001, “user_name”: “Adam”, “gender”: “Male”, “age”: 16}

{“user_id”:1002, “user_name”: “Bob”, “gender”: “Male”, “age”: 41}

{“user_id”:1003, “user_name”: “Clair”, “gender”: “Female”, “age”: 21}

優點是:JSON則天然支持Schema Evoluation,上游業務的變更,只需要在JSON列數據中進行增刪相應的欄位,無需對數倉中的表做任何DDL就能完成,也能對中間的ETL作業做到透明,最大程度地保留了半結構化數據的易用性和靈活性,能大大降低維護和管理表結構的成本。

缺點是:應用端查詢時需要選擇合適的處理函數和方法,才能解析到需要的數據,開發較為複雜,如果JSON較複雜,同時查詢性能會有退化,因為每次JSON列的數據參與計算的時候,都需要對JSON數據完整的解析一遍,比如需要抽取出整個JSON中某個欄位,那麼查詢引擎執行的時候就要讀出每一行JSON,解析一遍,取出需要的欄位再返回。這中間會涉及大量的IO和計算,而需要的可能只是JSON數據成百上千欄位當中的一個欄位,這中間的大量IO和計算都是浪費的。

另外,當前雲原生分支上JSON的向量化支持仍然是沿用的通用的向量化框架,沒有定製化的向量化函數。通用的向量化函數框架本質上來說仍然為行存的調用,並不是完全意義上的向量化。

後續演進路線

如上所述,後續想要提升JSON/JSONB的查詢性能,首先必須提升JSON的存儲方式,即在解析前端將JSON拍平成寬表,真正意義上發揮JSON半結構化數據的優勢。

user_id

user_name

gender

age

1001

Adam

Male

16

1002

Bob

Male

41

1003

Clair

Female

21

這種做法的優點是:寫入DWS時,因為是普通列寫入,所以寫入性能會更好,同時在查詢側,不需要對JSON數據進行解析,查詢性能也會更好。

缺點是:每當上游的數據格式有變更時,比如變更數據類型、增刪欄位、執行DDL進行加列或者刪列,中間的實時數據ETL作業也需要進行適配改動並重新上線,使用非常不靈活,也會額外增加運維和開發負擔。並且當JSON的每一個鍵值都為一列,若出現異常數據,可能導致列數的急速膨脹,進而影響性能。

當前Hologres的方案類似,但其對特殊的列採用單獨列(屬性為JSON)存儲那些同質化不強的json鍵值(極少數出現的json鍵值)

另外,當前列存JSON的性能當前瓶頸點在於向量化的性能,一方面需要提升通用當前DWS的向量化能力,另一方面也可以考慮對json函數做出優化。

 

點擊關註,第一時間瞭解華為雲新鮮技術~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • /******************************************************************************************************** * * 提高可移植性 Copyright (c) 2023-2024 cececlmx@ ...
  • 為什麼要使用操作系統 使用操作系統的主要原因是為了實現 CPU 多進程分時復用以及記憶體隔離 如果沒有操作系統,應用程式會直接與硬體進行交互,這時應用程式會直接使用 CPU,比如假設只有一個 CPU 核,一個應用程式在這個 CPU 核上運行,但是同時其他程式也需要運行,因為沒有操作系統來幫助切換,就需 ...
  • 系統函數: 1、簡單示例: 點擊查看代碼 #!/bin/bash filename="$1"_log_$(datename +%S) echo $filename basename: 基本語法: basename [string/pathname] [suffix] (功能描述:basename命令 ...
  • 在剛剛過去的2024春季發佈會上,袋鼠雲帶來了數棧產品V6.2版本的全新發佈。其中,EasyMR 作為數棧V6.2中的一項關鍵能力,代表了袋鼠雲對大數據生態的深入理解和持續創新。 EasyMR(後文統稱EMR)是袋鼠雲基於 Hadoop、Hive、Spark、Flink、HBase 等開源組件,構建 ...
  • 1.環境說明 1.1源端SQLSserver 版本 IP 埠 Microsoft SQL Server 2017 192.168.140.160 1433 1.2目標端GreatSQL 版本 IP 埠 GreatSQL-8.0.32 192.168.139.86 3308 2.安裝環境 2.1安 ...
  • 目錄一、什麼是redis Cluster集群二、集群架構圖三、redis Cluster部署架構1、測試環境2、生產環境四、原生命令手動部署Redis Cluster1、環境準備2、為所有節點啟用redis集群支持3、執行meet操作實現互相通信在任意一節點上和其它所有節點進行meet通信,以m1為 ...
  • 項目背景 數字金融是數字經濟的重要支撐和驅動力。近年來,我國針對數字金融的發展政策頻頻出台,《金融科技發展規劃 (2022-2025年)》、《“十四五”數字經濟發展規劃》、《關於銀行業保險業數字化轉型的指導意見》、《金融標準化“十 四五”發展規劃》等相繼發佈,頂層設計逐步完善。 2024年,政府工作 ...
  • DB2是IBM的一款關係型資料庫管理系統,JDBC DB2 Source Connector是一個用於通過JDBC讀取外部數據源數據的連接器。Apache SeaTunnel如何支持JDBC DB2 Sink Connector?請參考本文檔。 支持引擎 Spark Flink SeaTunnel ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...