Mảng trong PostgreSQL là một công cụ mạnh mẽ cho phép lưu trữ nhiều giá trị trong một cột duy nhất, giúp bạn dễ dàng quản lý dữ liệu phức tạp. Với các tính năng như truy vấn, cập nhật, và thao tác trên mảng, PostgreSQL mang lại sự linh hoạt trong việc xử lý các tập dữ liệu lớn. Trong bài viết này, chúng ta sẽ khám phá chi tiết cách khai báo, chèn, truy vấn và thao tác với mảng, bao gồm cả các ví dụ nâng cao để bạn có thể tận dụng tối đa khả năng của kiểu dữ liệu này trong cơ sở dữ liệu của mình.

1. Khai báo mảng

Khi tạo bảng, bạn có thể định nghĩa một cột lưu trữ kiểu mảng với các kiểu dữ liệu cơ bản như INTEGER, TEXT, VARCHAR, v.v. PostgreSQL hỗ trợ mảng một chiều và đa chiều.

Ví dụ:

CREATE TABLE projects (
    id SERIAL PRIMARY KEY,
    project_name VARCHAR(255),
    team_members TEXT[],          -- Mảng các chuỗi lưu tên thành viên nhóm
    deadlines DATE[],             -- Mảng các ngày hoàn thành nhiệm vụ
    budget_breakdown DECIMAL[]    -- Mảng các giá trị ngân sách
);

2. Chèn dữ liệu vào mảng

Bạn có thể chèn dữ liệu vào cột mảng bằng cú pháp ARRAY[], hoặc sử dụng định dạng chuỗi ('{val1, val2, ...}').

Ví dụ:

INSERT INTO projects (project_name, team_members, deadlines, budget_breakdown)
VALUES (
    'AI Development',
    ARRAY['Alice', 'Bob', 'Charlie'],          -- Mảng chuỗi
    ARRAY['2024-01-01', '2024-03-01', '2024-06-01'],  -- Mảng ngày
    ARRAY[10000.50, 20000.75, 15000.20]        -- Mảng số thập phân
);

Hoặc dùng định dạng chuỗi:

INSERT INTO projects (project_name, team_members, deadlines, budget_breakdown)
VALUES (
    'Mobile App Launch',
    '{"Jane", "Tom", "Jerry"}',
    '{"2024-02-15", "2024-04-20", "2024-08-10"}',
    '{5000, 10000, 8000}'
);

3. Truy vấn dữ liệu từ mảng

Lấy giá trị mảng theo chỉ mục Chỉ mục mảng trong PostgreSQL bắt đầu từ 1. Bạn có thể truy xuất giá trị của một phần tử cụ thể.

Ví dụ:

SELECT project_name, team_members[2] AS second_member FROM projects;

Kết quả sẽ trả về thành viên thứ hai trong danh sách team_members.

Lọc dựa trên giá trị mảng Để kiểm tra nếu một giá trị nằm trong mảng, sử dụng toán tử ANY.

Ví dụ:

SELECT * FROM projects WHERE 'Bob' = ANY(team_members);

Truy vấn này sẽ trả về tất cả các dự án có Bob là thành viên trong nhóm.

Lọc theo độ dài mảng Có thể kiểm tra kích thước mảng với hàm array_length.

Ví dụ:

SELECT project_name FROM projects WHERE array_length(team_members, 1) > 2;

Truy vấn này trả về các dự án có số lượng thành viên nhóm lớn hơn 2.

4. Cập nhật phần tử trong mảng

Bạn có thể cập nhật một phần tử cụ thể trong mảng dựa trên chỉ mục, hoặc cập nhật toàn bộ mảng.

Cập nhật giá trị phần tử tại một vị trí cụ thể:

UPDATE projects
SET team_members[1] = 'Eve'
WHERE project_name = 'AI Development';

Câu lệnh này sẽ thay thế thành viên đầu tiên trong team_members của dự án “AI Development” thành ‘Eve’.

Thêm phần tử vào mảng Sử dụng hàm array_append để thêm phần tử mới vào cuối mảng.

Ví dụ:

UPDATE projects
SET team_members = array_append(team_members, 'David')
WHERE project_name = 'AI Development';

Xóa phần tử khỏi mảng Sử dụng array_remove để loại bỏ một phần tử khỏi mảng.

Ví dụ:

UPDATE projects
SET team_members = array_remove(team_members, 'Bob')
WHERE project_name = 'AI Development';

5. Thao tác nâng cao với mảng

PostgreSQL cung cấp nhiều hàm và toán tử để thao tác với mảng. Dưới đây là một số ví dụ nâng cao:

a) Hàm unnest để tách phần tử mảng

Hàm unnest giúp bạn chuyển các phần tử trong mảng thành các hàng riêng biệt.

Ví dụ:

SELECT project_name, unnest(team_members) AS member FROM projects;

Kết quả sẽ hiển thị từng thành viên nhóm của từng dự án dưới dạng một hàng riêng biệt.

b) Sử dụng array_agg để tạo mảng từ nhiều hàng

array_agg giúp nhóm các hàng thành một mảng.

Ví dụ:

SELECT project_name, array_agg(member_name) AS team_members
FROM (
    SELECT 'AI Development' AS project_name, 'Alice' AS member_name
    UNION ALL
    SELECT 'AI Development', 'Bob'
    UNION ALL
    SELECT 'AI Development', 'Charlie'
) AS members
GROUP BY project_name;

c) Mảng nhiều chiều

PostgreSQL hỗ trợ mảng nhiều chiều, thường được sử dụng để lưu trữ dữ liệu dạng ma trận hoặc các cấu trúc phức tạp hơn.

Ví dụ:

CREATE TABLE matrix_table (
    id SERIAL PRIMARY KEY,
    matrix INTEGER[][]
);

INSERT INTO matrix_table (matrix)
VALUES (ARRAY[[1, 2, 3], [4, 5, 6], [7, 8, 9]]);

Để truy vấn một phần tử cụ thể trong mảng nhiều chiều:

SELECT matrix[2][3] FROM matrix_table; -- Lấy phần tử ở hàng 2, cột 3 (giá trị là 6)

d) Lọc dựa trên mảng con

Bạn có thể kiểm tra nếu một mảng là mảng con của một mảng khác bằng cách sử dụng toán tử @>.

Ví dụ:

SELECT * FROM projects WHERE ARRAY['Alice', 'Bob']

Truy vấn này trả về tất cả các dự án mà nhóm bao gồm cả ‘Alice’ và ‘Bob’.

6. Sử dụng mảng trong hàm

Bạn có thể truyền và trả về mảng từ các hàm tùy chỉnh trong PostgreSQL.

Ví dụ:

CREATE OR REPLACE FUNCTION get_team(project TEXT)
RETURNS TEXT[] AS $$
BEGIN
    RETURN (SELECT team_members FROM projects WHERE project_name = project);
END;
$$ LANGUAGE plpgsql;

-- Gọi hàm
SELECT get_team('AI Development');

Hàm này trả về mảng team_members của dự án được chỉ định.

7. Kết hợp mảng với các loại dữ liệu khác

Bạn có thể kết hợp kiểu dữ liệu mảng với JSON, JSONB để lưu trữ các cấu trúc dữ liệu phức tạp hơn.

Ví dụ:

CREATE TABLE project_details (
    id SERIAL PRIMARY KEY,
    project_info JSONB[],
    members TEXT[]
);

INSERT INTO project_details (project_info, members)
VALUES (
    ARRAY['{"budget": 10000, "deadline": "2024-01-01"}'::jsonb, '{"budget": 15000, "deadline": "2024-06-01"}'::jsonb],
    ARRAY['Alice', 'Bob']
);

Tổng kết

Kiểu dữ liệu mảng trong PostgreSQL mang lại tính linh hoạt trong việc lưu trữ và xử lý các tập hợp giá trị. Với khả năng kết hợp cùng các hàm mạnh mẽ như array_agg, unnest, và các toán tử, bạn có thể thực hiện các truy vấn phức tạp và tối ưu hóa hệ thống dữ liệu của mình.