Make writing a habit together! This is the second day of my participation in the “Gold Digging Day New Plan · April More text challenge”. Click here for more details.
MySQL 5.7.8 and above provides a new json field format, and provides a number of functions to manipulate JSON-type data, so that MySQL can also store document data like Mongo. Let’s take a look at how we can apply this type.
1. Create a document table
First, we create a table to save the document, specifying the primary key, the document name, the document content, where the document content field we can set to JSON format, so that we can use this field to save json format data, just like Mongo.
Before the JSON format was available, the creation might be stored in BLOB, TEXT, or VARCHAR, and converted to the corresponding object in the project using deserialization.
CREATE TABLE `document` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'primary key'.`name` varchar(255) DEFAULT NULL COMMENT 'Document name'.`content` json DEFAULT NULL COMMENT 'Document contents',
PRIMARY KEY (`id`))ENGINE=InnoDB DEFAULT CHARSET=utf8;
Copy the code
Note: JSON columns cannot have non-null defaults and take up roughly the same space as LONGBLOB or LONGTEXT.
** Trivia: ** What are the advantages of using JSON format storage over using string sequences?
- Automatic validation of JSON document format, error format cannot be inserted.
- Optimized storage format. Json documents stored in JSON-formatted columns will be stored in BLOB format and transferred directly in binary format without being converted to document format for presentation.
2. Initialize document table data
We add several pieces of data to the document table, select the data with representative type, including value is an array, value is an object, and confirm whether they can be added.
insert into `document` VALUES(1.'log'.'{" IP ":" 127.0.0.1 "and" port ":" 8080 ", "thread" : "thread01"}');
insert into `document` VALUES(2.'log'.'{" IP ":" 127.0.0.1 "and" port ":" 8080 ", "thread" : "thread02"}');
insert into `document` VALUES(3.'log'.'{" IP ":" 127.0.0.1 "and" port ":" 8080 ", "thread" : "thread03"}');
insert into `document` VALUES(4.'log_thread_arr'.'{" IP ":" 127.0.0.1 "and" port ":" 8080 ", "threadGroup" : [" thread01 ", "thread02"]}');
insert into `document` VALUES(5.'log_thread_info'.'{" IP ":" 127.0.0.1 "and" port ":" 8080 ", "threadInfo" : {" threadNo ":" 01 ", "threadName" : "thread01"}}');
Copy the code
Add successfully, as shown in the following figure:
Let’s try adding a piece of data that doesn’t fit the JSON format to make sure it can be saved.
insert into `document` VALUES(3.'log'.'{" IP ":" 127.0.0.1 "and" port ":" 8080 ", "thread" : "t');
Copy the code
Data that does not conform to the format cannot be saved, with the following error message:
Invalid JSON text: “Missing a closing quotation mark in string.” at position 51 in value for column ‘document.content’.
3. Json related functions
The following are some common json functions, and there are many more in the system besides the ones listed below.
You can also use the following functions for columns that are not in JSON format.
3.1 JSON_EXTRACT
JSON_EXTRACT(json_doc, path[, path] …) If the value is not present in json, it will return Null. We can also write it after WHERE as a criterion, but we do not write it this way. We usually write WHERE as 3.3
-- Query a value in JSONSELECT JSON_EXTRACT(document.content, '$.ip') FROM document;
SELECT JSON_EXTRACT(document.content, '$.thread') FROM document; -- can be used as WHERE after the conditionSELECT
JSON_EXTRACT( document.content, '$.thread' )
FROM
document
WHERE
JSON_EXTRACT( document.content, '$.thread' ) IS NOT NULL; -- Query json information at the next levelSELECT JSON_EXTRACT(document.content, '$.threadInfo.threadNo') FROM document;
Copy the code
Query result:
3.2 – >
-> JSON column return value; The equivalent of JSON_EXTRACT ()
SELECT * from document WHERE document.content->'$.thread' IS NOT NULL;
Copy the code
Query result:
3.3 JSON_SET
JSON_SET(json_doc, path, val[, path, val] …) Insert the data into the JSON document
UPDATE document SET document.content = JSON_SET(document.content, '$.ip'.'0.0.0.0') WHERE id = 3;
Copy the code
3.4 JSON_CONTAINS, JSON_CONTAINS_PATH
JSON_CONTAINS(target, candidate[, path]) contains a specific object
JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] …) Whether to contain corresponding fields
-- Whether to include a specific object
SELECT * from document WHERE JSON_CONTAINS(document.content,JSON_OBJECT("thread"."thread01"));
-- Whether to include fields
SELECT * from document WHERE
JSON_CONTAINS_PATH(document.content, 'one'.'$.thread');
Copy the code
Query result:
3.5 JSON_OBJECT, JSON_ARRAY
JSON_OBJECT([key, val[, key, val] …] ) is to convert a key-value pair into a JSON object, as in 3.4
JSON_ARRAY([val[, val] …] Convert a group value to a JSON array
SELECT * from document WHERE JSON_CONTAINS(document.content->'$.threadGroup', JSON_ARRAY("thread01"));
Copy the code
Query result:
3.6 JSON_INSERT
JSON_INSERT(json_doc, path, val[, path, val] …) Insert the fields
UPDATE document set document.content=JSON_INSERT(document.content, '$.id'.'1'.'$.name'.'log01')
WHERE id=1
Copy the code
3.7 JSON_REPLACE
JSON_REPLACE(json_doc, path, val[, path, val] …)
UPDATE document SET document.content = JSON_REPLACE(document.content, '$.ip'.'0.0.0.0') WHERE id = 1;
Copy the code
3.8 JSON_REMOVE
JSON_REMOVE(json_doc, path[, path] …) Delete data from a JSON document
UPDATE document SET document.content = JSON_REMOVE(document.content, '$.name') WHERE id = 1;
Copy the code
3.9 JSON_TYPE
JSON_TYPE(json_val) Queries the attribute type of a CERTAIN JSON field
SELECT JSON_TYPE(document.content->'$.ip') from document ;
Copy the code
The general types are INTEGER, STRING, ARRAY, and OBJECT
3.10 JSON_KEYS
JSON_KEYS(json_doc[, path]) returns an array of all the keys in the document
SELECT JSON_KEYS(document.content) from document ;
Copy the code
Query result:
3.11 JSON_UNQUOTE
JSON_UNQUOTE(json_val) dereferences and extracts the data directly to string
3.12 JSON_LENGTH
JSON_LENGTH(json_doc[, path]) The outermost layer of JSON or the length of the specified path. The scalar length is 1. The length of an array is the number of array elements, and the length of an object is the number of object members.
4. How to optimize the retrieval efficiency of JSON text
If we store data in JSON format, search performance drops dramatically when there is a large amount of data, so how can we optimize?
In JSON format, indexes cannot be created directly. We need to construct virtual generated columns for fields commonly used for query in JSON and add indexes to virtual generated columns to optimize query performance.
There are two types of generated columns: stored generated columns and virtual generated columns.
-
Store build column
Storage Generated columns are similar to common columns. The values of these columns are automatically calculated and stored when data is inserted or updated, occupying storage space.
-
Virtual generated column
Virtually generated columns take no storage space and are only evaluated when read (similar to views).
Virtual columns support NOT NULL, UNIQUE, primary key, CHECK, and foreign key constraints in addition to indexes, but do NOT support the DEFAULT value.
Grammar - GENERATED column col_name data_type [GENERATED ALWAYS] AS (expr) [VIRTUAL | STORED] [NOT NULL | NULL] [UNIQUE [KEY]] [[PRIMARY] KEY] [COMMENT'string'] -- generate virtual columnsALTER TABLE document ADD COLUMN
v_log_id VARCHAR(32)
GENERATED ALWAYS
AS (JSON_UNQUOTE(JSON_EXTRACT(document.content, '$.id'))) VIRTUAL NULL; Add an index to the generated columnCREATE INDEX idx_v_log_id ON document(v_log_id); SELECT * FROM document WHERE v_log_id = SELECT * FROM document WHERE v_log_id ='01'
Copy the code
Query result:
5. To summarize
When we have json document storage requirements and it is not necessary to introduce MongoDB into the project, we can consider using the JSON format of MySQL. Its built-in functions are powerful enough to support our daily use. When the query bottleneck occurs, we can also increase the index by using MySQL to virtually generate columns to optimize the query efficiency. In addition, since it is very inconvenient to extend fields in the production environment, jSON-formatted fields are very extensible, so it is very suitable for use in extended fields, so that some of our less important but needed data can be put into extended fields.
Thank you for reading, if you feel helpful, please click a thumbs-up, thanks a million!!