refactor: re-organise file structure

This commit is contained in:
2026-05-23 07:55:18 +08:00
parent 54ecd30a98
commit 453f20c902
50 changed files with 7 additions and 10 deletions
+89
View File
@@ -0,0 +1,89 @@
---
title: Using JSON in MySQL
tags:
- mysql
- json
- database
author:
name: Zihlu Wang
email: real@zihluwang.me
---
MySQL (since version 5.7) **does not directly support a data type called `jsonb`**. `jsonb` is a data type specific to PostgreSQL, which stores JSON data in a binary format with pre-parsing for faster access and manipulation during queries.
However, MySQL's `JSON` data type is functionally and internally similar to PostgreSQL's `jsonb` in many respects, particularly when it comes to querying data.
The `JSON` data type in MySQL was introduced in MySQL 5.7 and has the following characteristics:
1. **Binary Storage**: Like PostgreSQL's `jsonb`, MySQL's `JSON` type data is stored in an **internal binary format** rather than as a plain text string. This makes reading and manipulating JSON data more efficient, as the database does not need to parse text-format JSON strings on every query.
2. **Automatic Validation**: When you insert or update a `JSON` column, MySQL automatically validates that its content is a valid JSON document. If not, it throws an error.
3. **Optimised Storage**: The binary format is also space-optimised, typically more compact than storing JSON in raw text format.
MySQL provides a powerful set of functions and operators for querying and manipulating `JSON` data, very similar to what you'd expect from `jsonb`:
1. **`->` (JSON Extract Operator)**: Extracts a value from a JSON document. It returns a JSON value.
```sql
SELECT my_json_column->'$.key' FROM my_table;
-- Example: extract the name property of a user object
-- Assuming my_json_column stores {'user': {'name': 'Alice'}}
SELECT json_data->'$.user.name' FROM my_table;
```
2. **`->>` (JSON Unquote Operator)**: Extracts a value from a JSON document and **automatically unquotes it**, typically returning a scalar value (e.g., string, number). This is equivalent to `JSON_UNQUOTE(JSON_EXTRACT(...))`.
```sql
SELECT my_json_column->>'$.key' FROM my_table;
-- Example: extract the name property of a user object (returns the string 'Alice' directly)
SELECT json_data->>'$.user.name' FROM my_table;
```
3. **`JSON_EXTRACT(json_doc, path, ...)`**: Explicitly extracts data from a JSON document.
```sql
SELECT JSON_EXTRACT(my_json_column, '$.key') FROM my_table;
```
4. **`JSON_CONTAINS(json_doc, candidate, path)`**: Checks whether a JSON document contains a specified value.
```sql
-- Check whether the tags array contains 'backend'
-- Assuming my_json_column stores {'tags': ['frontend', 'backend']}
SELECT * FROM my_table WHERE JSON_CONTAINS(json_data->'$.tags', '"backend"');
```
5. **`JSON_SEARCH(json_doc, one_or_all, search_str, escape_char, path, ...)`**: Returns the path to a specified string within a JSON document.
```sql
-- Find the path to a value of 'test'
SELECT JSON_SEARCH(my_json_column, 'one', 'test') FROM my_table;
```
6. **`JSON_TABLE(json_doc, path COLUMNS ... )` (MySQL 8.0 and later)**: A very powerful function that "expands" JSON data into relational rows and columns, ideal for complex queries and reporting.
```sql
-- Assuming json_data stores {'items': [{'id': 1, 'name': 'A'}, {'id': 2, 'name': 'B'}]}
SELECT *
FROM my_table,
JSON_TABLE(json_data, '$.items[*]' COLUMNS(
itemId INT PATH '$.id',
itemName VARCHAR(50) PATH '$.name'
)) AS jt;
```
Like PostgreSQL's `jsonb`, efficient querying on JSON fields typically requires indexing. Since the content of JSON fields is dynamic, MySQL does not directly support creating traditional B-tree indexes on a specific internal path of a JSON field. However, you can achieve this through **Virtual Generated Columns**:
1. **Create a Virtual Column**: Define a virtual column whose value is extracted from a specific path in the JSON field.
```sql
ALTER TABLE my_table
ADD COLUMN user_name VARCHAR(255) AS (json_data->>'$.user.name') VIRTUAL;
```
2. **Create an Index on the Virtual Column**: This way, when you query `WHERE json_data->>'$.user.name' = 'Alice'`, the MySQL optimiser can use the `idx_user_name` index, significantly improving query performance.
```sql
CREATE INDEX idx_user_name ON my_table (user_name);
```
Although MySQL does not have the exact name `jsonb`, its `JSON` data type provides highly similar functionality: binary storage optimisation, automatic validation, and rich query operators and functions. By combining virtual columns with indexes, MySQL can deliver query performance and flexibility comparable to PostgreSQL's `jsonb` when working with JSON data.