mysql與Json學習總結


mysql在2015年的5.7以后,InnoDB存儲引擎已經開始對json數據進行支持,對json支持有如下優勢:

  • JSON數據有效性檢查:BLOB類型無法在數據庫層做這樣的約束性檢查,如不合法會報錯:
  • 查詢性能的提升:查詢不需要遍歷所有字符串才能找到數據
  • 支持索引:通過虛擬列的功能可以對JSON中的部分數據進行索引
  • 存儲的容量大,近似於LongBlob與LongText(4G)

建表語句:

CREATE TABLE `employe` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(18) DEFAULT NULL,
  `sex` int DEFAULT NULL,
  `others` json DEFAULT NULL,
  `time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '錄入時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=42334 DEFAULT CHARSET=utf8mb4;

 獲取JSON中的某個字段的風格與alibaba中fastjson中的JSONPath類似,但是功能與之相差甚遠:

  • .    屬性訪問,例如$.name
  • $   根對象,即當前json
  • *   對象的所有屬性,如:$.* ,當為JSONArray時,$.* 無效

  

其中支持json的主要函數如下表:或見https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html

 簡單列一下常用操作,便於記憶:

  •  JSON_EXTRACT(column_name,'$.name')返回該json列column中的name中的值
  • JSON_SEARCH(others, 'one', "露露")   若該字段存在,返回路徑,若不存在返回null:select * from employe where JSON_SEARCH(others, 'one', "露露") is not null;//查找存在“露露”的記錄;該方法中的中間參數有“one”與“all”兩種,one返回該json中第一次找到的記錄路徑,all返回該json中所有找到的路徑,即若存在多個“露露”則返回多個露露的路徑
  • JSON_TYPE(others) 判斷alias的json類型(ARRAY或者OBJECT)
  • JSON_VALID(others) 判斷alias 是否是一個合法的json
  • JSON_CONTAINS(others, '露露', '$.alias');
  • mysql5.7.9開始增加了一種簡寫方式:column->path; select others->'$.address'  from employe   查詢json中的address列 類似:select JSON_EXTRACT(others, '$.address') from employe where id = 42332;
  • select json_contains('{"a":1,"b":4}','{"a":1}')  結果1

    select json_contains('{"a":2,"b":1}','{"a":1}')  結果0

    select json_contains('{"a":[1,2,3],"b":1}','[1,2]','$.a')  結果1。數組包含則需要所有元素都存在。

    select json_contains('{"a":[1,2,3],"b":1}','1','$.a')   

  • select json_contains(others, '\"露露\"','$.alias') from employe;         使用json_contains的時候,如果是字符串要用雙引號包括,如果去掉雙引號則報錯

虛擬列:虛擬列類似於視圖,將others字段中的address提取出來作為一個虛擬列address,當others字段中的address發生改變時,虛擬列會同時改變。

ALTER TABLE employe ADD address varchar(128) GENERATED ALWAYS AS (json_extract(others,'$.address')) VIRTUAL;

若去掉address列的引號可用replace替換:

ALTER TABLE employe ADD address varchar(128) GENERATED ALWAYS AS (REPLACE(json_extract(others,'$.address'),"\"",'')) VIRTUAL;

可對該虛擬字段進行查詢:

select * from employe where address="北京昌平";

 在MySQL 5.7中,支持兩種generated column,即virtual generated column和stored generated column,前者只將generated column保存在數據字典中(表的元數據),並不會將這一列數據持久化到磁盤上;后者會將generated column持久化到磁盤上,而不是每次讀取的時候計算所得。很明顯,后者存放了可以通過已有數據計算而得的數據,需要更多的磁盤空間,與virtual column相比並沒有優勢,因此,MySQL 5.7中,不指定generated column的類型,默認是virtual column。

 

 虛擬索引:虛擬列與普通列類似可創建索引,虛擬索引列也是通過傳統的B+樹索引即可實現對JSON格式部分屬性的快速查詢。使用方法是首先創建該虛擬列,然后在該虛擬列上創建索引:

alter table employe add INDEX add_index(address);

 在創建索引后執行語句select * from employe where address="北京昌平";如下圖,發現使用到了索引: 

 

效率問題:關於效率方面,使用json報錯或將json轉化為多表存儲的效率對比參考https://www.cnblogs.com/lkpnotice/p/6903187.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM