CodeGym /Các khóa học /SQL SELF /Những lỗi thường gặp khi làm việc với mảng và cách phòng ...

Những lỗi thường gặp khi làm việc với mảng và cách phòng tránh

SQL SELF
Mức độ , Bài học
Có sẵn

Hôm nay tụi mình sẽ kết thúc chuyến phiêu lưu thú vị về làm việc với mảng trong PostgreSQL. Chủ đề hôm nay là những lỗi thường gặp mà bạn có thể đụng phải, và quan trọng nhất là làm sao để né chúng. Nếu bạn từng nghĩ kiểu "cái mảng này lại làm trò gì kỳ cục nữa rồi", thì bài này dành cho bạn đó. Cùng tìm hiểu nha.

Lỗi khi tạo mảng: vấn đề với kiểu dữ liệu bên trong mảng

Khi bạn tạo mảng trong PostgreSQL, nhớ là tất cả phần tử trong mảng phải cùng kiểu dữ liệu. Ví dụ nè:

SELECT ARRAY[1, 2, 'ba'];
-- Lỗi: trong mảng các phần tử phải cùng kiểu

PostgreSQL sẽ không cho phép bạn trộn số và chuỗi trong cùng một mảng đâu. Nếu bạn thật sự cần như vậy, hãy dùng chuyển đổi kiểu:

SELECT ARRAY[1::TEXT, 2::TEXT, 'ba'];
-- Giờ mảng toàn là chuỗi

Lỗi khi dùng ARRAY[] với các kiểu dữ liệu khác nhau

Mặc định PostgreSQL sẽ cố đoán kiểu mảng dựa trên nội dung của nó. Nếu bạn đưa vào dữ liệu không rõ ràng, chuẩn bị tinh thần gặp lỗi nha:

SELECT ARRAY[1, NULL];
-- Lỗi: PostgreSQL không biết phải hiểu NULL kiểu gì

Để giải quyết, hãy chỉ rõ kiểu dữ liệu luôn:

SELECT ARRAY[1, NULL]::INTEGER[];
-- Mọi thứ chạy ngon lành

Lỗi khi truy xuất dữ liệu: vấn đề với chỉ số mảng

Nếu bạn quen code Python hay JavaScript, nơi chỉ số mảng bắt đầu từ 0, thì PostgreSQL sẽ làm bạn bất ngờ đó. Ở đây, mảng được đánh chỉ số bắt đầu từ 1 nha.

SELECT ARRAY[10, 20, 30][0];
-- Lỗi: chỉ số phải bắt đầu từ 1

Truy vấn đúng nè:

SELECT ARRAY[10, 20, 30][1];
-- Kết quả: 10

Lỗi khi dùng hàm để truy xuất

Các hàm như unnest() có thể gây rối nếu bạn không để ý là nó sẽ "bung" mảng ra thành từng dòng:

CREATE TEMP TABLE example (
    id SERIAL PRIMARY KEY,
    tags TEXT[]
);

INSERT INTO example (tags) VALUES (ARRAY['tag1', 'tag2']), (ARRAY['tag3']);

SELECT unnest(tags) FROM example;
-- Kết quả:
-- tag1
-- tag2
-- tag3

Nếu bạn cần giữ lại ngữ cảnh dòng (ví dụ id), hãy thêm nó vào truy vấn luôn:

SELECT id, unnest(tags) AS tag FROM example;
-- Kết quả:
-- id | tag
--  1 | tag1
--  1 | tag2
--  2 | tag3

Lỗi khi lọc và so sánh mảng

  1. Dùng sai các toán tử @>, <@, &&

Những toán tử này dùng cho các mục đích riêng biệt:

  • @> kiểm tra xem mảng này có chứa mảng kia không.
  • <@ kiểm tra xem mảng này có nằm trong mảng khác không.
  • && kiểm tra hai mảng có giao nhau không.

Lỗi sẽ xảy ra nếu bạn dùng sai mục đích:

SELECT ARRAY[1, 2, 3] @> 2;
-- Lỗi: toán tử @> chỉ dùng cho mảng

Làm đúng nè:

SELECT ARRAY[1, 2, 3] @> ARRAY[2];
-- Kết quả: true
  1. Vấn đề hiệu năng khi không có index

Nếu bạn dùng các toán tử cho mảng nhiều mà thấy truy vấn chậm, khả năng cao là bạn quên tạo index rồi. Đây là ví dụ tạo index cho mảng:

CREATE INDEX idx_tags ON example USING GIN (tags);

Giờ các truy vấn với @>&& sẽ chạy nhanh hơn nhiều.

Lỗi khi sửa đổi mảng

  1. Xoá và thêm giá trị

Các hàm array_remove()array_append() không thay đổi mảng "tại chỗ", mà trả về mảng mới. Nếu bạn nghĩ mảng gốc sẽ thay đổi thì nhầm rồi nha:

UPDATE example
SET tags = array_remove(tags, 'tag1');
-- Giờ mảng đã được cập nhật

Nếu bạn quên không ghi SET tags =, SQL vẫn chạy nhưng mảng không đổi đâu.

  1. Bị trùng dữ liệu khi dùng array_append()

Hàm array_append() không kiểm tra phần tử đã có chưa. Điều này có thể làm bị trùng:

SELECT array_append(ARRAY['tag1', 'tag2'], 'tag1');
-- Kết quả: {tag1, tag2, tag1}

Nếu muốn tránh trùng, hãy lọc trước:

SELECT array_remove(array_append(ARRAY['tag1', 'tag2'], 'tag1'), 'tag1') || 'tag1';
-- Kết quả: {tag1, tag2}

Mẹo để tránh lỗi

Để tránh các lỗi trên khi làm việc với mảng:

  1. Kiểm tra kiểu dữ liệu. Luôn chỉ rõ kiểu mảng nếu có gì không rõ ràng.
  2. Cẩn thận với chỉ số. Nhớ là mảng trong PostgreSQL bắt đầu từ 1 nha.
  3. Tối ưu truy vấn với mảng. Dùng index để tăng tốc so sánh và lọc.
  4. Test với dữ liệu nhỏ. Nếu truy vấn mảng chạy chậm, thử với ít dữ liệu để tìm chỗ nghẽn.
  5. Tránh trùng lặp. Kiểm tra kỹ khi thêm phần tử vào mảng nếu không muốn bị lặp.

Mảng trong PostgreSQL, giống như vũ khí mạnh, cần được tôn trọng và dùng cẩn thận. Làm theo mấy mẹo này thì mảng sẽ không còn làm bạn mất ngủ nữa đâu (gần như vậy thôi). Chúc bạn thiết kế và tối ưu database thành công nha!

1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
So sánh và lọc mảng
So sánh và lọc mảng
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION