Databend JSON 復(fù)雜數(shù)據(jù)類型的設(shè)計(jì)與使用 | Databend 特性系列
引言
JSON 是一種常用的半結(jié)構(gòu)化數(shù)據(jù),通過自描述的 Schema 結(jié)構(gòu),可以表示任何類型的數(shù)據(jù),包括多層嵌套的數(shù)據(jù)類型,例如 Array、Object 等。與必須嚴(yán)格遵循表結(jié)構(gòu)字段的結(jié)構(gòu)化數(shù)據(jù)相比,具有靈活性高,易于動(dòng)態(tài)擴(kuò)展的優(yōu)點(diǎn)。近年來,隨著各平臺(tái)數(shù)據(jù)量的迅速增加,JSON 等半結(jié)構(gòu)化數(shù)據(jù)的使用越來越流行,例如,平臺(tái)通過開放接口對(duì)外提供 JSON 格式的數(shù)據(jù),以 JSON 格式存儲(chǔ)公開的數(shù)據(jù)集,采用 JSON 格式存儲(chǔ)應(yīng)用日志等。對(duì)這些數(shù)據(jù)進(jìn)行分析可以獲得很多非常有價(jià)值的信息。因此,Databend 在支持結(jié)構(gòu)化數(shù)據(jù)處理的同時(shí),也提供了對(duì) JSON 數(shù)據(jù)的支持。本文將詳細(xì)介紹 JSON 數(shù)據(jù)的設(shè)計(jì)和使用。
JSON 數(shù)據(jù)類型
Databend 使用?VARIANT?類型來存儲(chǔ)半結(jié)構(gòu)化數(shù)據(jù),通常也可以使用?JSON?作為別名。例如,可以使用如下的 SQL 創(chuàng)建包含 JSON 數(shù)據(jù)的表:
JSON 類型的數(shù)據(jù)需要通過調(diào)用?parse_json?或?try_parse_json?函數(shù)生成,函數(shù)輸入的字符串為標(biāo)準(zhǔn)的 JSON 格式,包括 Null、Boolean、Number、String、Array、Object 6 種類型的數(shù)據(jù)。如果字符串不合法導(dǎo)致解析失敗,parse_json?會(huì)返回解析錯(cuò)誤,而?try_parse_json?會(huì)返回 Null 值。
例如:
JSON 通常用來存儲(chǔ) Array 或 Object 類型的數(shù)據(jù),由于存在嵌套層級(jí)結(jié)構(gòu),需要通過?JSON PATH?對(duì)內(nèi)部元素進(jìn)行訪問。有三種形式的語(yǔ)法作為分隔符:
1.冒號(hào)?:
?用于按 key 獲取 Object 中的元素
2.點(diǎn)號(hào)?.
?用于按 key 獲取 Object 中的元素,為了與表名和列名直接的分隔符區(qū)分,不能作為第一個(gè)分隔符
3.括號(hào)?[]
?用于按 key 獲取 Object 或按 index 獲取 Array 中的元素
這三種類型的分隔符可以混合使用。例如:
通過?JSON?PATH?提取的出的內(nèi)部元素也是 JSON 類型的,這些數(shù)據(jù)可以通過?cast?函數(shù)或轉(zhuǎn)化操作符??::??轉(zhuǎn)化為基本類型。
例如:
分析 Github 的 JSON 數(shù)據(jù)
很多公開的數(shù)據(jù)集是用 JSON 格式存儲(chǔ)的,我們可以將這些數(shù)據(jù)導(dǎo)入到 Databend 進(jìn)行分析,下面以 Github 的公開事件數(shù)據(jù)為例進(jìn)行介紹。
GH Archive?提供了 Github 數(shù)據(jù)的下載,事件記錄具有如下的 JSON 格式:
其中,actor,repo,payload,org 字段具有嵌套結(jié)構(gòu),適合存儲(chǔ)為 JSON,其它字段不是嵌套結(jié)構(gòu)且類型固定,可以使用基本類型進(jìn)行存儲(chǔ)。創(chuàng)建如下的表結(jié)構(gòu):
使用 COPY 命令導(dǎo)入 2022-09-10-10 的 github 數(shù)據(jù)
查詢提交次數(shù)最多的 10 個(gè)項(xiàng)目
統(tǒng)計(jì) fork 次數(shù)最多的 10 個(gè)用戶
性能優(yōu)化
目前的實(shí)現(xiàn)將 JSON 數(shù)據(jù)按純文本格式進(jìn)行保存,在每次讀取數(shù)據(jù)時(shí)都需要進(jìn)行解析并生成 serde_json::Value 的枚舉值,不僅解析速度慢,而且占用較多的內(nèi)存空間,導(dǎo)致其性能與其它基本類型的數(shù)據(jù)相差較大。為了提高 JSON 數(shù)據(jù)的讀取性能,我們采用如下的方式進(jìn)行優(yōu)化:
數(shù)據(jù)存儲(chǔ)為二進(jìn)制格式的?JSONB。通過內(nèi)置的?j_entry?結(jié)構(gòu)存儲(chǔ)各個(gè)元素的類型和偏移位置,可以加快解析速度,減少內(nèi)存占用。
使用虛擬列加快查詢速度。利用 JSON 數(shù)據(jù)通常有相似結(jié)構(gòu)的特點(diǎn),將用戶經(jīng)常查詢并且數(shù)據(jù)類型相同的字段抽取出來存儲(chǔ)為單獨(dú)的虛擬列,在查詢的時(shí)候直接從虛擬列進(jìn)行讀取,這樣可以獲得與其他數(shù)據(jù)類型相同的查詢性能。
關(guān)于性能優(yōu)化的詳細(xì)設(shè)計(jì),我們將會(huì)在后續(xù)的文章中進(jìn)行介紹。
關(guān)于 Databend
Databend 是一款開源、彈性、低成本,基于對(duì)象存儲(chǔ)也可以做實(shí)時(shí)分析的新式數(shù)倉(cāng)。期待您的關(guān)注,一起探索云原生數(shù)倉(cāng)解決方案,打造新一代開源 Data Cloud。
Databend 文檔:https://databend.rs/
Twitter:https://twitter.com/Datafuse_Labs
Slack:https://datafusecloud.slack.com/
Wechat:Databend
GitHub :https://github.com/datafuselabs/databend
