半結構化數據的定義
我們在設計一個信息系統時必然涉及到數據的存儲,而數據存儲用得最多的就是關系數據庫。通常我們會將數據按業務分類,并設計相應的表,然后將對應的信息保存到相應的表中。比如一個企業信息管理系統,我們需要保存員工基本信息:工號、姓名、性別、出生日期等等;我們就會建立一個對應的員工(staff)表。像通過關系型數據庫的二維表結構(行和列)來邏輯表示數據結構,并且數據結構變化不會經常性發生,我們稱之為結構化數據。相比之下,比如員工的聲音,圖像等數據,因為不同員工之間可能存在很大的差異,我們很難用某種特定邏輯結構來進行描述,因此稱之為非結構化數據。在關系數據庫中通常使用blob(二進制編碼)來進行進行非結構化數據。
半結構化數據,是介于結構化和非結構化之間的數據。它是結構化的數據,但是結構變化很大。因為我們要了解數據的細節所以不能將數據簡單的組織成一個文件按照非結構化數據處理,由于結構變化很大也不能夠簡單的建立一個表和它對應。
比如員工的簡歷,它不像員工基本信息那樣一致,每個員工的簡歷大不相同。有的員工的簡歷很簡單,比如只包括教育情況;有的員工的簡歷卻很復雜,比如包括工作情況、婚姻情況、出入境情況、戶口遷移情況、黨籍情況、技術技能等等。還有可能有一些我們沒有預料的信息。通常我們要完整的保存這些信息并不是很容易的,因為我們不會希望系統中的表的結構在系統的運行期間進行變更。
隨著互聯網技術(尤其是移動互聯網,物聯網)的飛快發展,使得數據的差異性變大,因此非結構化數據的數量日趨增大。這時,主要用于管理結構化數據的關系數據庫的局限性暴露地越來越明顯。因而,數據庫技術相應地進入了“后關系數據庫時代”,發展進入基于網絡應用的非結構化數據庫時代。所謂非結構化數據庫, 是指數據庫的變長紀錄由若干不可重復和可重復的字段組成,而每個字段又可由若干不可重復和可重復的子字段組成。簡單地說,非結構化數據庫就是字段可變的數 據庫。比如NoSQL數據庫MongoDB,全文搜索數據看Elastic Search等。
半結構化數據的特征
半結構化數據中結構模式附著或相融于數據本身,數據自身就描述了其相應結構模式。具體來說,半結構化數據具有下述特征:
(1)數據結構自描述性。結構與數據相交融,在研究和應用中不需要區分“元數據”和“一般數據”(兩者合二為一)。
(2)數據結構描述的復雜性。結構難以納入現有的各種描述框架,實際應用中不易進行清晰的理解與把握。
(3)數據結構描述的動態性。數據變化通常會導致結構模式變化,整體上具有動態的結構模式。
常規的數據模型例如E-R模型、關系模型和對象模型恰恰與上述特點相反,因此可以成為結構化數據模型。而相對于結構化數據,半結構化數據的構成更為復雜和不確定,從而也具有更高的靈活性,能夠適應更為廣泛的應用需求。
半結構化數據的存儲方式
化解為結構化數據
這種方法通常是對現有的信息進行粗略的統計整理,總結出信息所有的類別同時考慮系統真正關心的信息。對每一類別建立一個子表。比如上面提到員工簡歷我們可以建立教育情況子表、工作情況子表、黨籍情況子表等等,并在主表中加入一個備注字段,將其它系統不關心的信息和一開始沒有考慮到的信息保存在備注中。
優點:查詢統計比較方便。
缺點:不能適應數據的擴展,不能對擴展的信息進行檢索,對項目設計階段沒有考慮到的同時又是系統關心的信息的存儲不能很好的處理。
用XML格式來組織并保存到CLOB字段中
XML很適合存儲半結構化的數據,只需要將不同類別的信息保存在XML的不同的節點中就可以了。
優點:能夠靈活的進行擴展,信息進行擴展時只要更改對應的DTD或者XSD。
缺點:查詢效率比較低,要借助XPATH來完成查詢統計。
用JSON格式來組織并保存到CLOB字段中
JSON非常適合存儲半結構化的數據,只需要將不同類別的信息保存在JSON的不同的節點中就可以了。
優點:能夠靈活的進行擴展,信息進行擴展時只要在應用程序來控制JSON對應的Schema。
缺點:查詢效率比較低,要通過數據庫本身提供的JSON處理方法來完成查詢統計。
Elastic Search如何處理半結構化數據
Elastic Search可以用來保存json類型的半結構化的數據,并提供更具json的schema定義的字段進行信息查詢。
它首先定義了一個通用的文檔格式(包含_index,_type,_id, _version,_score,_source等),然后我們可以根據業務需要來定義自己的schema,把數據保存到_source字段。
比如:
{
"_index": "deltadata_v1", ---- common fields
"_type": "_doc", ---- common fields
"_id": "share_issued_and_asset_raised-F00001468C-20200730", ---- common fields
"_version": 1, ---- common fields
"_score": null, ---- common fields
"_source": { ----- 根據需要自定義自己的數據格式,在自己的schema中,也可以根據不同的數據類型,來動態的設置data字段的schema
"kafkaWorkflow": "share_issued_and_asset_raised",
"instrumentId": "F00001468C",
"asOfDate": 20200730,
"updatedOn": 1596182547005,
"kafkaTimestamp": 1596182540033,
"data": {
"PreferredAssetRaised": null,
"ShareOutstanding": 3704772.13,
"SharePubliclyTraded": null,
"AssetRaised": null,
"NumberOfShareHolder": null,
"CommonShareOutstanding": null,
"IPOValue": "0",
"ShareAuthorized": null,
"CommonAssetRaised": null
}
}
}
數據保存到數據庫之后,我們可以根據自己定義的json schema進行內容檢索,例如
GET /deltadata/_doc/_search?pretty&version=true
{
"query": {
"bool": {
"must": [
{ "match": { "kafkaWorkflow": "share_issued_and_asset_raised" }
}
]
}
},
"sort": {"updatedOn": { "order": "desc" }}
}