Json數據的簡化存儲

Json是一種非常流行的跨平台的數據交換格式,具有容易閱讀和修改的優點。

與XML相比,Json格式比較簡單,更加輕量級,易於使用。

Json數據簡化思路

我們先通過一個實例來體會Json數據格式的特點(JSON Data Set Sample)。其中包括了Json最重要的兩種數據類型:對象和數組。

{n "id": "0001",n "type": "donut",n "name": "Cake",n "ppu": 0.55,n "batters":n {n "batter":n [n { "id": "1001", "type": "Regular" },n { "id": "1002", "type": "Chocolate" },n { "id": "1003", "type": "Blueberry" },n { "id": "1004", "type": "Devils Food" }n ]n },n "topping":n [n { "id": "5001", "type": "None" },n { "id": "5002", "type": "Glazed" },n { "id": "5005", "type": "Sugar" },n { "id": "5007", "type": "Powdered Sugar" },n { "id": "5006", "type": "Chocolate with Sprinkles" },n { "id": "5003", "type": "Chocolate" },n { "id": "5004", "type": "Maple" }n ]n}n

我們可以看到Json將數據按照Key-Value的方式組織起來。這是Json具有可讀性,且易於修改的關鍵。

但是Json數據中有較多的為了可讀性帶來的額外存儲開銷:Key數據和"{}[],:"等分隔符和格式數據。如果有大量的Json數據,格式類似,那麼這些為了可讀性而在每個Json數據中都存儲的額外數據其實是可以簡化的。比如上述的"id"/"type"這樣的key在一個消息中重複了很多次。格式相同的消息,格式數據同樣會一遍遍重複。

其實,我們可以把描述格式的數據,即元數據,單獨存起來,附在數據開頭。由於數據格式大多數情況下是穩定的,所以格式數據甚至可以事先約定,數據傳輸過程中只需要在數據頭填上一個事先約定好的格式序列號。

簡化後的數據格式

在上述思想指導下,我們對上一節中Json數據示例做了如下改寫:

{"id", "type", "name", "ppu", "batters", "topping"},n"batters" : {"batter"},n"batter" : [{"id", "type"}],n"topping" : [{"id", "type"}]n

"0001", "donut", "Cake", 0.55,n4,n "1001", "Regular",n "1002", "Chocolate",n "1003", "Blueberry",n "1004", "Devils Food",n7,n "5001", "None",n "5002", "Glazed",n "5005", "Sugar",n "5007", "Powdered Sugar",n "5006", "Chocolate with Sprinkles",n "5003", "Chocolate",n "5004", "Maple"n

改寫後的數據分為兩段:第一段是數據的格式,稱為元數據;第二段是上層應用生成的有效數據,稱為簡化數據。元數據包括了Json簡化數據的類型和Key等結構化信息,使用Json原定的格式字元和分隔符描述。實際傳輸的簡化數據不包含格式信息,只包含數據和數據分隔符。

在實際應用中,元數據用於重建數據的層次關係。簡化數據起始處需要指定格式信息,即元數據。大多數情況下,元數據類型有限,雙方使用同一格式集合,那麼元數據本身都不需要分發,只需要發送一個ID信息即可。通過將元數據和簡化數據分開維護,實際傳輸或存儲的數據得到了明顯的簡化。

簡化後的Json消息和原Json消息是等價的。簡化數據的數據域的順序和元數據相關Key的順序是一一對應的。但是通過簡化數據和元數據完全可以還原為原Json消息。

簡化Json消息的解析與原Json消息的解析也是類似的。下圖是根據元數據生成的一顆解析樹。而遍歷簡化數據的過程,就是前序遍歷這顆解析樹的過程。

Json簡化數據的解析過程

討論

1)解析樹

生成或讀取json簡化數據時,並不需要每次都讀取元數據並生成解析樹。在初始化階段,消息類型通常可以知道,所以只需要生成一次解析樹。即使消息類型可以動態變化,也很容易做到對解析樹的動態調整。

2)解析樹與C/C++對象類型

雖然在序列化和反序列化時,C/C++中使用的相應對象類型和解析樹可能不完全一致。但是將解析樹簡單對應到C/C++中的對象類型可以帶來額外的便利。

我們可以借鑒Protobuf,類似proto文件,生成C/C++適用的對象類型,進一步簡化序列化和反序列化過程。

3)數據兼容性問題

簡化後的Json消息和原Json消息是等價的。所以原Json格式所提供的數據兼容能力,簡化後也是具備的。

我們甚至可以對元數據做擴充,提供原Json格式不具備的表達能力。


推薦閱讀:

TAG:供应链 | 供应链管理 | 供应商管理 | 中醫 | 中藥 | 中藥材 | 心灵哲学 | 心灵鸡汤 | 信贷 | 南七道 | 生态学 | 生态环境 | 科研 | 家庭影院 | 私人影院 | 装修 | Python | 編程 | 應聘 | 社會 | 工作 | 服装行业 | 时尚管理 | 艺术留学 | Dubstep | 身障人士残疾人 | 功能性饮料 | 手术 | 一個勺子電影 | 铁人三项 | 公路车 | 马拉松 | | 冷兵器 | 冷兵器時代 | 中國歷史 | 葬禮 | 中國習俗 | 金骏眉 | 茶叶选购 | | JSON | 游戏开发 | 跨平台 |