搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

朋友們,我們都知道關係型數據庫和NoSQL數據庫的最大區別,在於數據的存儲和處理方式不同,關係型數據庫使用行列二維表存儲數據、NoSQL數據庫則通過對象存儲數據,這個所謂的對象,主要就是指JSON類型的數據。

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

支持JSON已成為數據庫的發展大方向

數據庫技術發展到當下,主要有關係型數據庫(Relational Database Management System,簡稱RDBMS)、NoSQL非關係型數據庫、以及綜合二者優點的NewSQL數據庫

關係型數據庫的代表包括PostgreSQL、MySQL、MariaDB、SQLite、Oracle、SQLServer等,關係型數據庫技術發展非常成熟,也是當前應用的主流。目前在國內MySQL、SQLServer、Oracle用的比較多。

NoSQL數據庫的代表主要包括Redis(鍵值型數據庫)、MongoDB、CouchDB(文檔型數據庫)、Cassandra(列式存儲)、Neo4j(圖形數據庫)等。

關係型數據庫的優點是技術成熟、結構簡單、原子性和事務支持好等、支持非常豐富的SQL標準語法,缺點是數據存儲格式簡單、速度不佳;NoSQL的優點是支持json非標準化數據格式、充分使用內存速度快等,缺點是缺乏統一的SQL標準、對查詢的支持有限、對事務的支持不好。NewSQL則是結合二者優點的產物。

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

NewSQL數據庫的代表主要包括TiDB等。TiDB是一顆冉冉升起的新星,這可是咱中國人自己的團隊開發的、而且是完全開源的,在Github可以直接Git所有的源代碼。TiDB支持的語法格式基本兼容MySQL。TiDB不僅具有NoSQL對海量數據的存儲管理能力,還保持了關係型數據庫支持ACID和標準SQL等特性。TiDB是中國國產數據庫的一面旗幟,我們真應該多瞭解她、呵護她、應用她。

NewSQL是未來發展的方向,包括現在看似如火如荼的MongoDB、Redis等,都在逐步的向NewSQL技術靠攏。我們能看明白,那些老牌的關係型數據庫心裡也像明鏡一樣。比如PostgreSQL,早早的開始全面支持Json,Oracle和SQLServer也在跟進。並不是說這些數據庫支持Json就成了NewSQL,這是一個漸進的過程,根據筆者的觀察,在未來數年內,當前主流的關係型數據庫,都會一步步漸進到NewSQL數據庫領域

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

當前對Json支持最好的主流關係型數據庫非PostgreSQL莫屬,PostgreSQL號稱“世界最先進的開源數據庫”,其不但從字段級別支持Json,更提供了大量的Json處理接口函數。雖然PostgreSQL在國內被MySQL壓制著應用不夠廣泛,但中國人有個特點,一旦認識到好東西,就會一窩蜂的叮上去,只是不知道PostgreSQL會不會這麼榮幸了。


SQLServer對Json的支持也很不錯,筆者曾經寫過《將數據庫SQL查詢結果直接轉為JSON》、《當關系型數據庫遭遇JSON——判斷篇》、《取值篇》、《對象篇》、《操縱篇》、《行集篇》六文詳細闡述MSSQL對JSON的支持。因為內容比較分散,理解起來相對有些凌亂。本文嘗試全面闡述MSSQL的JSON支持,希望您能一文玩通之。

如何在MSSQL中存儲JSON數據?

說出來您可能不信,MSSQL並不直接支持JSON類型字段,這點確實比不過PostgreSQL來的徹底。在MSSQL中,JSON是作為字符串看待的,所以所有支持字符串的數據類型都可以存儲JSON,這似乎是廢話。當然,沒有JSON類型字段並不代表MSSQL對JSON的支持就不強大。微軟官方推薦使用nvarchar(max)或varchar(max)來存放JSON串

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

如果您的JSON數據是存放在文件中,要加載到表字段中時,需要使用表值函數OPENROWSET(BULK),如果 SQL Server 對本地驅動器或網絡中的任一文件擁有讀取訪問權限,則該函數可從該文件中讀取數據。 該函數返回包含單個列的表,該列包含文件的內容。具體可參看下面的示例腳本:

declare @data table(
FID bigint primary key identity,
FLog nvarchar(max)
);
insert into @data(FLog)
select BulkColumn from
openrowset (bulk 'c:\file.json', single_clob) as t;

如上例所示,通過表值函數openrowset,使用bulk修飾符,single_clob表示將整個文件作為json文本,BulkColumn返回json文本。

如何將查詢結果輸入為JSON?

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

SQL Server的select子句for json關鍵字,可將查詢結果直接轉為JSON文本。for json子句有三種用法:

  • for json auto子句根據select結構自動將查詢結果轉為JSON;
  • for json path子句實現輸出格式控制,可以創建包裝對象並嵌套複雜屬性;
  • 以上兩種結合root選項,可給輸出結果增加頂層節點。
搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

您可以參看《將數據庫SQL查詢結果直接轉為JSON》做更深一步瞭解。

如何判斷字符串是否JSON格式?

判斷字符串表達式是否是JSON類型,可使用ISJSON函數。ISJSON語法格式如下:

ISJSON ( expression )

如果字符串表達式包含有效JSON,則返回1;否則,返回0。如果expression為NULL,則返回 NULL。

我們先定義一段JSON,作為例子展開說明:

declare @json nvarchar(max)=N'{
"銷售數據": [
{
"FName": "張三",
"FDistrict": "北京",
"FAmount": 20000
},
{
"FName": "李四",
"FDistrict": "深圳",
"FAmount": 40000
}
]
}';

判斷的方法很簡單,直接如下調用

select isjson(@json)

此時返回值就是1。具體參考下圖:

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

如何讀取和解析JSON串?

對JSON字符串的解析,SQL Server提供了json_value、json_query兩個解析函數,這兩個函數的作用是不同的。

json_value的語法格式為:

JSON_VALUE(expression,path) 

expression為包含JSON的表達式,path為JSON的鍵路徑。path的語法格式非常簡單,使用$標識根目錄,根據層級使用.號隔開鍵名稱,比如“$."銷售數據"[1].FName”,表示的是第一組“銷售數據”下面的FName鍵,如果鍵名稱包含Unicode,則需要使用雙引號引起來標識其整體性。

json_value返回的是具體的標量值。

比如針對前例的@json進行解析,下面是正確的寫法:

select json_value(@json,'$."銷售數據"[0].FName');
搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

而下面的寫法是錯誤的:

select json_value(@json,'$."銷售數據"[0]');
select json_value(@json,'$."銷售數據"');

為何?因為鍵路徑對應的不是標量值,而是對象或者數組。

您可以參看《當關系型數據庫遭遇JSON——取值篇》做更深一步瞭解。

json_query的語法格式為:

JSON_QUERY (expression[,path])

expression為包含JSON的表達式,path為JSON的鍵路徑。

json_query返回的不是具體的標量值,而是JSON的子對象或數組。還用上面的例子,使用json_value錯的情況換作json_query恰恰是正確的:

select json_query(@json,'$."銷售數據"[0]');
select json_query(@json,'$."銷售數據"');

前者返回的是對象,後者返回的是數組,如下圖所示:

搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

您可以參看《當關系型數據庫遭遇JSON——對象篇》做更深一步瞭解。

如何修改JSON鍵值?

SQL Server提供了json_modify函數修改JSON標量值。其語法格式為:

JSON_MODIFY(expression,path,newValue) 

expression為JSON表達式,path為鍵路徑,newValue為要修改的新值。

返回值為修改後的JSON。

還用前面的@JSON串做例子,比如我們要修改“張三”的銷售額:

set @json=json_modify(@json,'$."銷售數據"[0].FAmount',60000);
搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

path參數支持append修飾符,指定將新值追加到通過<json path>引用的數組的可選修飾符。

您可以參看《當關系型數據庫遭遇JSON——操縱篇》做更深一步瞭解。

如何將JSON轉換為行集?

openjson為行集函數,可將JSON拉平成二維表格。openjson支持默認架構和顯示架構兩種方式。

默認架構的語法格式為:

select * from openjson(expression,path)

顯示架構是帶有with子句的行集調用,with用來定義明確的輸出表結構,語法格式為:

select * from openjson(expression,path)
with(field1 path1,...)

還是上面的JSON串為例,如下腳本就把數組中的鍵拉平成二維表:

select * from openjson(@json,'$."銷售數據"')
with(
FName nvarchar(20),
FDistrict nvarchar(20),
FAmount decimal(28,10)
);
搞數據庫的還沒大量應用JSON,那您就快要OUT啦!

您可以參看《當關系型數據庫遭遇JSON——行集篇》做更深一步瞭解。


相信通過上述分析,您對SQL Server的JSON支持已經基本掌握了。