Cách Xử Lý Dữ Liệu Mảng trong MySQL bằng JSON (Hướng Dẫn Toàn Diện kèm Ví Dụ)

目次

1. Giới thiệu

Nhu cầu xử lý dữ liệu dạng mảng trong MySQL

Cơ sở dữ liệu thường lưu trữ dữ liệu dựa trên các nguyên tắc thiết kế quan hệ. Tuy nhiên, tùy thuộc vào yêu cầu của ứng dụng, có những trường hợp bạn muốn lưu nhiều giá trị trong một cột duy nhất. Trong những tình huống này, một cấu trúc dữ liệu giống “mảng” trở nên hữu ích.

Ví dụ, hãy xem các kịch bản sau:

  • Lưu nhiều thẻ được người dùng chọn.
  • Lưu nhiều URL hình ảnh cho một sản phẩm.
  • Kết hợp lịch sử hoặc log vào một trường duy nhất.

Lợi ích của việc sử dụng kiểu dữ liệu JSON

MySQL không cung cấp một “kiểu mảng” trực tiếp, nhưng bằng cách sử dụng kiểu dữ liệu JSON, bạn có thể xử lý các cấu trúc dữ liệu dạng mảng. Kiểu JSON rất linh hoạt và mang lại các ưu điểm sau:

  • Hỗ trợ cấu trúc dữ liệu lồng nhau.
  • Cho phép thao tác dữ liệu dễ dàng trong các truy vấn.
  • Cho phép quản lý nhiều định dạng dữ liệu trong một trường duy nhất.

Trong bài viết này, chúng tôi sẽ giới thiệu cách xử lý dữ liệu dạng mảng trong MySQL một cách hiệu quả bằng kiểu dữ liệu JSON.

2. Kiến thức cơ bản về xử lý mảng với MySQL JSON

Kiểu dữ liệu JSON là gì?

JSON (JavaScript Object Notation) là một định dạng trao đổi dữ liệu nhẹ và đơn giản. Trong MySQL, hỗ trợ JSON bản địa đã được giới thiệu từ phiên bản 5.7 trở lên, cho phép bạn lưu trữ và thao tác dữ liệu định dạng JSON trực tiếp trong cơ sở dữ liệu.

Ví dụ: Dưới đây là một ví dụ về dữ liệu có thể được lưu trong cột JSON.

{
  "tags": ["PHP", "MySQL", "JSON"],
  "status": "published"
}

Ưu điểm và các trường hợp sử dụng của kiểu dữ liệu JSON

Các lợi ích chính của việc sử dụng kiểu JSON như sau:

  1. Cấu trúc dữ liệu linh hoạt : Bạn có thể xử lý dữ liệu có độ dài biến đổi mà không cần thay đổi schema quan hệ.
  2. Thao tác dữ liệu hiệu quả : Bạn có thể dễ dàng thao tác dữ liệu bằng các hàm chuyên dụng của MySQL (ví dụ, JSON_EXTRACT, JSON_ARRAY).
  3. Thiết kế không có schema : Không cần thường xuyên thay đổi schema khi yêu cầu ứng dụng thay đổi.

Các trường hợp sử dụng ví dụ:

  • Gán nhiều danh mục cho thông tin sản phẩm.
  • Lưu cài đặt tùy chỉnh của người dùng.
  • Sử dụng dữ liệu JSON lồng nhau trong các ứng dụng web.

3. Các thao tác cơ bản với mảng JSON

Tạo một mảng JSON

Trong MySQL, bạn có thể dễ dàng tạo một mảng JSON bằng hàm JSON_ARRAY. Mảng hữu ích khi lưu nhiều giá trị trong một cột duy nhất.

Ví dụ

Truy vấn sau tạo một mảng JSON có tên tags.

SELECT JSON_ARRAY('PHP', 'MySQL', 'JavaScript') AS tags;

Kết quả:

["PHP", "MySQL", "JavaScript"]

Ví dụ thực tế

Ví dụ dưới đây cho thấy cách lưu một mảng JSON vào cơ sở dữ liệu bằng câu lệnh INSERT.

CREATE TABLE articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    tags JSON
);

INSERT INTO articles (tags) 
VALUES (JSON_ARRAY('PHP', 'MySQL', 'JavaScript'));

Trích xuất dữ liệu từ một mảng JSON

Để lấy dữ liệu được lưu trong một mảng JSON, sử dụng hàm JSON_EXTRACT. Hàm này cho phép bạn dễ dàng trích xuất các phần tử cụ thể từ mảng.

Ví dụ

Ví dụ sau lấy phần tử thứ hai trong mảng (chỉ số bắt đầu từ 0).

SELECT JSON_EXTRACT('["PHP", "MySQL", "JavaScript"]', '$[1]') AS second_tag;

Kết quả:

"MySQL"

Truy xuất nhiều phần tử cùng lúc

Bạn cũng có thể truy xuất nhiều phần tử một lúc.

SELECT JSON_EXTRACT('["PHP", "MySQL", "JavaScript"]', '$[0]', '$[2]') AS extracted_values;

Thêm, cập nhật và xóa dữ liệu

Thêm dữ liệu vào mảng

Bạn có thể dùng hàm JSON_ARRAY_APPEND để thêm dữ liệu mới vào một mảng đã tồn tại.

SET @tags = '["PHP", "MySQL"]';
SELECT JSON_ARRAY_APPEND(@tags, '$', 'JavaScript') AS updated_tags;

Kết quả:

["PHP", "MySQL", "JavaScript"]

Cập nhật dữ liệu trong mảng

Bạn có thể cập nhật một phần tử cụ thể trong mảng bằng hàm JSON_SET.

SET @tags = '["PHP", "MySQL", "JavaScript"]';
SELECT JSON_SET(@tags, '$[1]', 'Python') AS updated_tags;

Kết quả:

["PHP", "Python", "JavaScript"]

Xóa Dữ liệu khỏi Mảng

Bạn có thể xóa một phần tử cụ thể khỏi mảng bằng cách sử dụng hàm JSON_REMOVE.

SET @tags = '["PHP", "MySQL", "JavaScript"]';
SELECT JSON_REMOVE(@tags, '$[1]') AS updated_tags;

Kết quả:

["PHP", "JavaScript"]

4. Tìm kiếm và Lọc Mảng JSON

Tìm kiếm các Mảng Chứa Dữ liệu Cụ thể

Để kiểm tra xem một mảng JSON có chứa dữ liệu cụ thể hay không, sử dụng hàm JSON_CONTAINS. Hàm này xác định xem một giá trị nhất định có tồn tại trong mảng JSON hay không.

Ví dụ

Ví dụ sau kiểm tra xem mảng JSON có chứa “MySQL” hay không.

SELECT JSON_CONTAINS('["PHP", "MySQL", "JavaScript"]', '"MySQL"') AS is_present;

Kết quả:

1  (if present)
0  (if not present)

Ví dụ Thực tế: Tìm kiếm Có Điều kiện

Để tìm các hàng chứa một giá trị cụ thể trong một mảng JSON trong bảng cơ sở dữ liệu, sử dụng JSON_CONTAINS trong mệnh đề WHERE.

SELECT * 
FROM articles
WHERE JSON_CONTAINS(tags, '"MySQL"');

Truy vấn này lấy các hàng mà cột tags chứa “MySQL”.

Lấy Độ Dài của Mảng

Để lấy số phần tử trong một mảng JSON, sử dụng hàm JSON_LENGTH. Hàm này trả về số phần tử trong mảng và hữu ích cho việc phân tích dữ liệu và logic có điều kiện.

Ví dụ

Ví dụ sau lấy số phần tử trong mảng.

SELECT JSON_LENGTH('["PHP", "MySQL", "JavaScript"]') AS array_length;

Kết quả:

3

Ví dụ Thực tế: Trích xuất Các Hàng Thỏa Mãn Điều Kiện Cụ Thể

Để trích xuất các hàng mà số phần tử lớn hơn hoặc bằng một giá trị cụ thể, sử dụng JSON_LENGTH trong mệnh đề WHERE.

SELECT * 
FROM articles
WHERE JSON_LENGTH(tags) >= 2;

Truy vấn này lấy các hàng mà cột tags chứa hai hoặc nhiều hơn các phần tử.

Ví dụ Truy vấn Có Điều kiện Nâng cao

Bạn có thể kết hợp nhiều điều kiện cho các tìm kiếm nâng cao hơn. Truy vấn sau tìm các hàng mà mảng tags chứa “JavaScript” và có ba hoặc nhiều hơn các phần tử.

SELECT * 
FROM articles
WHERE JSON_CONTAINS(tags, '"JavaScript"') 
  AND JSON_LENGTH(tags) >= 3;

5. Ví dụ Thực tế: Sử dụng Mảng JSON trong Các Trường hợp Thực tế

Cách Lưu Danh Mục Sản Phẩm dưới dạng Mảng JSON

Trong các trang thương mại điện tử và các hệ thống tương tự, một sản phẩm có thể thuộc nhiều danh mục. Trong những trường hợp này, bạn có thể lưu trữ thông tin danh mục một cách hiệu quả bằng mảng JSON.

Ví dụ: Lưu Dữ liệu Danh Mục Sản Phẩm

Dưới đây là một ví dụ về việc tạo một cột JSON có tên categories trong bảng sản phẩm và lưu trữ nhiều danh mục.

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    categories JSON
);

INSERT INTO products (name, categories) 
VALUES ('Laptop', JSON_ARRAY('Electronics', 'Computers')),
       ('Smartphone', JSON_ARRAY('Electronics', 'Mobile Devices'));

Cấu trúc này giữ dữ liệu ngắn gọn ngay cả khi một sản phẩm thuộc nhiều danh mục.

Truy vấn để Lấy Sản phẩm trong Một Danh mục Cụ thể

Bằng cách tận dụng kiểu dữ liệu JSON, bạn có thể dễ dàng tìm kiếm các sản phẩm thuộc một danh mục cụ thể.

Ví dụ Truy vấn

Truy vấn sau lấy tất cả các sản phẩm trong danh mục “Electronics”.

SELECT name 
FROM products
WHERE JSON_CONTAINS(categories, '"Electronics"');

Kết quả:

Laptop
Smartphone

Truy vấn này giúp dễ dàng lấy danh sách sản phẩm theo danh mục một cách linh hoạt.

Ví dụ: Lọc theo Khoảng Giá

Hãy xem cách lưu trữ dữ liệu JSON bao gồm thông tin giá và sau đó tìm kiếm các sản phẩm dựa trên khoảng giá.

Dữ liệu Ví dụ

Ví dụ sau lưu trữ thông tin giá cho từng sản phẩm bằng cách sử dụng kiểu JSON.

CREATE TABLE products_with_prices (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    details JSON
);

INSERT INTO products_with_prices (name, details)
VALUES ('Laptop', '{"price": 150000, "categories": ["Electronics", "Computers"]}'),
       ('Smartphone', '{"price": 80000, "categories": ["Electronics", "Mobile Devices"]}');

Ví dụ Truy vấn

Để tìm kiếm các sản phẩm có giá 100.000 trở lên, sử dụng hàm JSON_EXTRACT.

SELECT name 
FROM products_with_prices
WHERE JSON_EXTRACT(details, '$.price') >= 100000;

Kết quả:

Laptop

Mở rộng JSON với JSON_TABLE và Ví dụ Truy vấn

Nếu bạn muốn truy vấn dữ liệu JSON ở định dạng quan hệ, hàm JSON_TABLE rất hữu ích. Hàm này cho phép bạn mở rộng một mảng JSON thành một bảng ảo.

Ví dụ

Ví dụ sau mở rộng một mảng JSON và hiển thị từng danh mục dưới dạng một hàng riêng biệt.

SELECT * 
FROM JSON_TABLE(
    '["Electronics", "Computers", "Mobile Devices"]',
    '$[*]' COLUMNS(
        category_name VARCHAR(100) PATH '$'
    )
) AS categories_table;

Kết quả:

category_name
--------------
Electronics
Computers
Mobile Devices

6. Những Lưu Ý Quan Trọng Khi Sử Dụng Kiểu Dữ Liệu JSON

Mẹo Tối Ưu Hóa Hiệu Suất

Mặc dù kiểu JSON linh hoạt, nhưng thiết kế kém có thể ảnh hưởng tiêu cực đến hiệu suất cơ sở dữ liệu. Dưới đây là các điểm tối ưu hóa chính.

1. Sử Dụng Chỉ Mục

Trong MySQL, bạn không thể tạo chỉ mục trực tiếp trên cột JSON, nhưng bạn có thể tạo một cột được tạo và chỉ mục một khóa cụ thể.

Ví dụ: Tạo Chỉ Mục Sử Dụng Cột Được Tạo

Trong ví dụ sau, khóa price bên trong dữ liệu JSON được sử dụng làm mục tiêu chỉ mục.

ALTER TABLE products_with_prices
ADD COLUMN price INT AS (JSON_EXTRACT(details, '$.price')) STORED,
ADD INDEX idx_price (price);

Bằng cách sử dụng cột được tạo, bạn có thể cải thiện đáng kể hiệu suất tìm kiếm trên dữ liệu JSON.

2. Tránh Cấu Trúc JSON Quá Phức Tạp

Cấu trúc JSON lồng ghép sâu có thể làm giảm khả năng đọc và hiệu suất truy vấn. Khi thiết kế dữ liệu, hãy chọn cấu trúc JSON đơn giản nhất có thể.

Ví dụ tốt:

{
  "categories": ["Electronics", "Computers"],
  "price": 150000
}

Ví dụ nên tránh:

{
  "product": {
    "details": {
      "price": 150000,
      "categories": ["Electronics", "Computers"]
    }
  }
}

Cách Tận Dụng Chỉ Mục

Khi chỉ mục sử dụng cột được tạo, hãy lưu ý các điểm sau:

  1. Cột được tạo phải là STORED .
  2. Sử dụng hàm JSON_EXTRACT để trích xuất một khóa cụ thể làm cột được tạo.

Ví dụ, để trích xuất phần tử đầu tiên của khóa categories và tạo chỉ mục, hãy làm như sau.

ALTER TABLE products
ADD COLUMN main_category VARCHAR(255) AS (JSON_EXTRACT(categories, '$[0]')) STORED,
ADD INDEX idx_main_category (main_category);

Tầm Quan Trọng Của Việc Xác Thực Dữ Liệu

Vì dữ liệu JSON linh hoạt, nên cũng dễ dàng lưu trữ dữ liệu ở định dạng sai. Để duy trì tính toàn vẹn dữ liệu, hãy sử dụng các cách tiếp cận sau.

1. Sử Dụng Ràng Buộc CHECK

Trong MySQL 8.0 trở lên, bạn có thể xác thực cấu trúc và nội dung JSON bằng ràng buộc CHECK.

ALTER TABLE products_with_prices
ADD CONSTRAINT check_price CHECK (JSON_EXTRACT(details, '$.price') >= 0);

2. Xác Thực Ở Mức Ứng Dụng

Khi chèn dữ liệu, khuyến nghị xác thực định dạng JSON ở phía ứng dụng. Các ngôn ngữ lập trình như PHP và Python có thể xác thực JSON bằng thư viện chuẩn của chúng.

7. Các Câu Hỏi Thường Gặp Về Việc Sử Dụng Mảng Trong MySQL

C1: MySQL có kiểu dữ liệu mảng không?

A1: MySQL không có kiểu dữ liệu “mảng” trực tiếp. Tuy nhiên, bằng cách sử dụng kiểu JSON, bạn có thể xử lý các cấu trúc dữ liệu giống mảng. Với kiểu JSON, bạn có thể lưu nhiều giá trị trong một cột và thao tác chúng qua các truy vấn.

Example:

SELECT JSON_ARRAY('Value 1', 'Value 2', 'Value 3') AS array_example;

Result:

["Value 1", "Value 2", "Value 3"]

Q2: Bạn có thể tạo chỉ mục trên dữ liệu JSON không?

A2: Bạn không thể tạo chỉ mục trực tiếp trên kiểu JSON. Tuy nhiên, bạn có thể trích xuất một khóa hoặc giá trị cụ thể vào một cột sinh ra và tạo chỉ mục trên cột sinh ra đó.

Example:

ALTER TABLE products_with_prices
ADD COLUMN price INT AS (JSON_EXTRACT(details, '$.price')) STORED,
ADD INDEX idx_price (price);

This allows you to efficiently search values inside JSON data.

Q3: Có giới hạn kích thước cho dữ liệu JSON không?

A3: Kiểu JSON của MySQL có thể lưu tới 4GB dữ liệu. Tuy nhiên, việc sử dụng các tài liệu JSON cực lớn có thể làm giảm hiệu năng, vì vậy bạn nên thiết kế dữ liệu một cách cẩn thận.

Khuyến nghị:

  • Chỉ lưu trữ dữ liệu tối thiểu cần thiết.
  • Tránh các cấu trúc JSON lồng nhau sâu.

Q4: Làm thế nào để cập nhật một phần tử cụ thể trong mảng JSON?

A4: Bạn có thể cập nhật một phần tử cụ thể trong mảng bằng cách sử dụng hàm JSON_SET.

Example:

SET @tags = '["PHP", "MySQL", "JavaScript"]';
SELECT JSON_SET(@tags, '$[1]', 'Python') AS updated_tags;

Result:

["PHP", "Python", "JavaScript"]

Q5: So sánh Kiểu JSON với Thiết kế Bảng Thông thường

A5: Mặc dù kiểu JSON rất linh hoạt, nó có những đặc điểm khác so với thiết kế cơ sở dữ liệu quan hệ truyền thống.

ItemJSON TypeTraditional Table Design
FlexibilityHigh (no schema changes needed)Fixed (schema changes required)
PerformanceInferior for some operationsOptimized
Query ComplexityRequires JSON functionsSimple
IndexingPartially supported via generated columnsFully supported

8. Tóm tắt

Lợi ích của việc sử dụng Kiểu dữ liệu JSON cho các thao tác mảng trong MySQL

Trong bài viết này, chúng tôi đã giải thích về kiểu dữ liệu JSON, hữu ích khi làm việc với dữ liệu dạng mảng trong MySQL. Dưới đây là tóm tắt các điểm chính đã được đề cập:

  1. Tại sao nên sử dụng Kiểu JSON MySQL không có kiểu mảng trực tiếp, nhưng bằng cách sử dụng kiểu JSON, bạn có thể lưu nhiều giá trị trong một cột và thực hiện việc thao tác dữ liệu linh hoạt.

Các thao tác JSON cơ bản

  • Chúng tôi đã đề cập cách tạo mảng JSON, trích xuất dữ liệu, cập nhật dữ liệu và xóa dữ liệu.
  • Bằng cách sử dụng các hàm tiện lợi như JSON_ARRAY, JSON_EXTRACTJSON_SET, bạn có thể thao tác dữ liệu mảng một cách hiệu quả.
  1. Tìm kiếm và Lọc
  • Cách tìm kiếm dữ liệu chứa các giá trị cụ thể bằng JSON_CONTAINS.
  • Cách lấy số lượng phần tử bằng JSON_LENGTH và thực hiện lọc có điều kiện.
  1. Ví dụ thực tế Thông qua các trường hợp thực tế như quản lý danh mục sản phẩm và lọc theo giá, chúng tôi đã học các cách cụ thể để áp dụng mảng JSON trong ứng dụng.

  2. Cân nhắc và Tối ưu hoá

  • Chúng tôi đã giải thích cách thiết lập chỉ mục bằng cột sinh ra và nhấn mạnh tầm quan trọng của việc xác thực dữ liệu JSON.

Các bước tiếp theo khi sử dụng Kiểu dữ liệu JSON

Bằng cách sử dụng kiểu JSON trong MySQL, bạn có thể quản lý dữ liệu linh hoạt hơn so với các thiết kế cơ sở dữ liệu quan hệ truyền thống. Tuy nhiên, việc thiết kế tốt và cân nhắc hiệu năng là rất cần thiết.

Các chủ đề cần học tiếp:

  • Sử dụng chỉ mục tổng hợp Thiết kế chỉ mục kết hợp dữ liệu JSON với các cột thông thường.
  • Sử dụng các hàm JSON nâng cao Thực hiện các thao tác phức tạp hơn với các hàm như JSON_MERGEJSON_OBJECT.
  • Xử lý dữ liệu ở mức ứng dụng Cách thao tác dữ liệu JSON MySQL một cách hiệu quả bằng PHP hoặc Python.

Tóm tắt

Thông qua bài viết này, bạn giờ đã hiểu cách xử lý hiệu quả dữ liệu dạng mảng bằng kiểu dữ liệu JSON của MySQL. Bằng cách áp dụng kiến thức này, bạn có thể thiết kế các cơ sở dữ liệu linh hoạt và mở rộng hơn.