Khi nói về việc xử lý dữ liệu văn bản trong PostgreSQL, tụi mình có ba nhân vật chính: CHAR, VARCHAR và TEXT. Mỗi loại đều có đặc điểm, ưu điểm và những lưu ý riêng. Cùng nhau tìm hiểu từng cái nhé.
CHAR(n)
CHAR, hay còn gọi là character, là một chuỗi có độ dài cố định n. Nếu chuỗi dữ liệu ngắn hơn số ký tự quy định, nó sẽ tự động được thêm dấu cách cho đủ độ dài.
Ví dụ:
| id | code - CHAR(5) |
|---|---|
| 1 | ''ABC'' |
Kiểu này rất tiện khi tất cả các chuỗi cần phải có cùng độ dài (ví dụ như mã code, mã vạch hoặc định danh có độ dài cố định).
Nhưng nếu làm việc với văn bản có độ dài thay đổi thì mấy dấu cách dư này chỉ làm tốn chỗ trong database thôi.
VARCHAR(n)
VARCHAR, hay còn gọi là variable character, dùng để lưu chuỗi có độ dài thay đổi nhưng có giới hạn tối đa là n ký tự.
Ví dụ:
| id | username - VARCHAR(10) |
|---|---|
| 1 | ''Alice'' |
Kiểu này dùng bộ nhớ hiệu quả vì chỉ lưu đúng phần text thực tế. Nhược điểm là phải chỉ định giới hạn độ dài. Nếu chuỗi vượt quá giới hạn này, database sẽ báo lỗi liền.
TEXT
TEXT là kiểu dữ liệu chuỗi không giới hạn độ dài. Thường dùng khi bạn không chắc text sẽ dài tới mức nào.
Ví dụ:
| id | content - TEXT |
|---|---|
| 1 | ''Đây là một đoạn văn bản dài. Không giới hạn!'' |
Ưu điểm: có thể lưu text dài bao nhiêu cũng được, khỏi lo giới hạn.
Nhược điểm: không có giới hạn nên nếu text phình to quá thì database sẽ bị "nặng" và kém hiệu quả.
So sánh các kiểu dữ liệu văn bản
Khi làm việc với text, quan trọng là phải biết kiểu dữ liệu nào phù hợp cho từng trường hợp. Đây là những điểm khác biệt chính giữa CHAR, VARCHAR và TEXT:
| Kiểu dữ liệu | Độ dài | Hiệu năng | Khi nào dùng? |
|---|---|---|---|
CHAR(n) |
Cố định | Nhanh hơn cho chuỗi có độ dài cố định | Dùng cho mã code có độ dài cố định (ví dụ ISO) |
VARCHAR(n) |
Độ dài tối đa n |
Nhanh hơn TEXT nếu có giới hạn độ dài |
Dùng cho chuỗi có độ dài thay đổi nhưng biết trước giới hạn |
TEXT |
Không giới hạn | Linh hoạt nhất | Dùng cho văn bản dài, không đoán trước được độ dài |
Ví dụ thực tế khi sử dụng
Ok, cùng xem thử cách dùng các kiểu dữ liệu này trong thực tế nha.
Ví dụ 1: Dùng CHAR cho mã code có độ dài cố định
Giả sử bạn làm việc với database cần lưu mã thành phố theo chuẩn ISO 3166-1 alpha-3. Mỗi mã phải đúng 3 ký tự.
| city_id | city_name - VARCHAR(50) | iso_code - CHAR(3) |
|---|---|---|
| 1 | New York | NYC |
| 2 | Los Angeles | LAX |
| 3 | Chicago | CHI |
Ở đây CHAR(3) là chuẩn luôn, vì mỗi mã ISO của thành phố đều cố định 3 ký tự.
Ví dụ 2: Dùng VARCHAR cho tên người dùng
Tên người dùng là ứng dụng điển hình cho VARCHAR. Thường thì tên sẽ có độ dài khác nhau, nhưng chắc chắn không vượt quá 50 ký tự.
| user_id | username - VARCHAR(50) | email - VARCHAR(50) |
|---|---|---|
| 1 | Alice | alice@example.com |
| 2 | Bob | bob@example.net |
VARCHAR trong trường hợp này giúp tiết kiệm bộ nhớ vì độ dài thực tế của chuỗi thường nhỏ hơn 50 ký tự.
Ví dụ 3: Dùng TEXT để lưu mô tả
Giả sử bạn có một blog, mỗi bài post cần lưu mô tả dài. Lúc này TEXT là lựa chọn tối ưu.
| post_id | title - VARCHAR(100) | content - TEXT |
|---|---|---|
| 1 | Post 1 | Đây là nội dung bài blog rất dài, kéo dài mãi không hết... |
Nếu bạn không biết trước độ dài text sẽ là bao nhiêu, TEXT là chuẩn luôn.
4. Một số lưu ý và cạm bẫy
Khi làm việc với các kiểu dữ liệu văn bản, có vài điểm cần chú ý để tránh lỗi thường gặp.
Vấn đề: CHAR tự động thêm dấu cách
Nếu bạn so sánh chuỗi trong trường kiểu CHAR mà không để ý dấu cách thêm vào, có thể kết quả sẽ không như mong đợi.
SELECT * FROM cities WHERE iso_code = 'NYC';
-- Không trả về gì nếu không loại bỏ dấu cách
Cách khắc phục: Dùng hàm TRIM() để xóa dấu cách.
SELECT * FROM cities WHERE TRIM(iso_code) = 'NYC';
Vấn đề: Giới hạn độ dài trong VARCHAR có thể gây lỗi
Nếu bạn cố chèn chuỗi dài hơn giới hạn vào trường kiểu VARCHAR, database sẽ báo lỗi ngay.
INSERT INTO users (username, email) VALUES ('A_username_that_is_too_long_for_field', 'test@example.com');
-- Lỗi
Cách khắc phục: Đảm bảo giới hạn độ dài (n) phù hợp với nhu cầu thực tế. Hoặc dùng TEXT để khỏi lo giới hạn.
Vấn đề: TEXT có thể làm database phình to
TEXT lưu dữ liệu không giới hạn, nên nếu text quá nhiều thì bảng sẽ phình to và việc tạo index sẽ khó khăn hơn.
Cách tránh: Nếu bạn định index cột kiểu TEXT nhiều, hãy cân nhắc dùng VARCHAR có giới hạn.
GO TO FULL VERSION