Mysql JSON數據類型


簡介

在MySQL5.7.8之后開始支持一種可高效獲取JSON文本中數據的原生JSON類型,該類型具有以下優點:

  • JSON數據有效性檢查:BLOB等類型無法在數據庫層做這樣的約束性檢查,
    • 保證了JSON數據類型的強校驗,JSON數據列會自動校驗存入此列的內容是否符合JSON格式,非正常格式則報錯,而varchar類型和text等類型本身是不存在這種機制的。
  • 查詢性能的提升:查詢不需要遍歷所有字符串才能找到數據
  • 支持索引:通過虛擬列的功能可以對JSON中的部分數據進行索引

另外,系統對JSON格式做了一些限制:

  • JSON文本的最大長度取決有系統常量:max_allowed_packet。該值僅在服務器進行存儲的時候進行限制,在內存中進行計算的時候是允許超過該值的。
  • JSON列不可有默認值(聲明時"DEFAULT NULL")。
  • JSON列與其他二進制類型列一樣是無法創建索引。但是可以從JSON列中所存儲的文本中某些表列值進行創建索引。MySQL最優控制器同樣在通過JSON表達創建的索引中進行查詢。
  • 可以基於JSON格式的特征支持修改特定的鍵值。(即不需要把整條內容拿出來放到程序中遍歷然后尋找替換再塞回去,MySQL內置的函數允許你通過一條SQL語句就能搞定)。

如何使用

1. 創建表

create table `test`(
    `id` INT AUTO_INCREMENT PRIMARY KEY,
    `content` JSON
) CHARSET = utf8;

2. 插入兩條數據

INSERT INTO test (content) VALUES ('{"name": "baidu","host": "www.baidu.com"}');
    
INSERT INTO test (content) VALUES ('{"name": "alibaba","host": "www.alibaba.com"}');

注意:

JSON列存儲的必須是JSON格式數據,否則會報錯。ERROR 3140 (22032): Invalid JSON text: "Invalid value." at position 0 in value for column 'test.content'.

3. 查詢

這里主要將關於JSON的查詢。

對於表中JSON數據的查詢,可以根據JSON中的key值進行查詢,看下面SQL語句

select JSON_EXTRACT(content,'$.name'),JSON_EXTRACT(content,'$.host') from test;

select JSON_EXTRACT(content,'$.name'),JSON_EXTRACT(content,'$.host') from test where JSON_EXTRACT(content,'$.name') = "baidu";

JSON函數支持

https://dev.mysql.com/doc/refman/5.7/en/json-function-reference.html

JSON中虛擬列的使用

對於索引,JSON字段無法對其中的一個key值進行索引,但是虛擬列可以,我們可以建立一個虛擬列和JSON中key值建立聯系。

1. 增加虛擬列v_name,v_host

注意:養成加前綴的好習慣, 例如這里使用"v_"來標記該字段是一個虛擬字段,在團隊開發時,共同遵守一個約定, 相互配合起來會非常順利。

ALTER TABLE test ADD COLUMN v_name CHAR(10) AS (content->'$.name');

ALTER TABLE test ADD COLUMN v_host CHAR(30) AS (content->'$.host');

下面對虛擬列建立索引

alter table test add index virtual_index(v_name);

然后查看基於v_name的查找的執行計划:

explain select content from test where v_name = "baidu";

從結果來看,查找已經走索引了。

上表中字段信息解釋:

字段名 解釋
id 選擇標識符
select_type 查詢的類型
table 輸出結果的表,也就是被查詢的表
partions 表示匹配的分區
type 表示表的連接類型
possible_keys 表示查詢時,可能使用的索引
key 表示實際使用的索引
key_len 表示字段的長度
ref 列與索引的比較
rows 掃描出的行數(估算的行數)
filtered 按查詢條件過濾的行百分比
Extra 執行情況的描述和說明

對虛擬列的簡介

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

注意:

在更新和插入數據時,不要給虛擬列設定值,否則會引發錯誤

ERROR 3105 (HY000): The value specified for generated column 'v_name' in table 'test' is not allowed.

Mybatis-plus處理json格式數據

在表映射實體類加上@TableName(autoResultMap = true);

在JSON字段映射的屬性加上@TableField(typeHandler = FastjsonTypeHandler.class);或 FastjsonTypeHandler.class

注:選擇對應的 JSON 處理器也必須存在對應依賴包

示例圖:

說明:

@TableName(value ="tablename",autoResultMap = true)
public class DictData{

}

屬性含義
value : 表名
autoResultMap :是否自動構建 resultMap 並使用(如果設置 resultMap 則不會進行 resultMap 的自動構建並注入)(@since 3.1.2)

在對應實體的屬性值上添加:

@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String,Object> otherInfoObj;

該注解對應了XML 中的寫法

<result column="xx"  property="實體屬性名" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />

<result property="workPlan" column="work_plan" javaType="com.xx.module.xx.dto.ReportWorkPlanDto" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/> <result property="reportObject" column="report_object" javaType="java.util.ArrayList" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/> <result property="copyObject" column="copy_object" javaType="java.util.ArrayList" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>

 

 

 

參考文章:https://www.cnblogs.com/youpeng/p/12409390.html


免責聲明!

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



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