CodeGym /Các khóa học /SQL SELF /Chọn kiểu dữ liệu phù hợp cho các nhiệm vụ khác nhau

Chọn kiểu dữ liệu phù hợp cho các nhiệm vụ khác nhau

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

Chọn kiểu dữ liệu cũng giống như chọn công cụ để làm việc. Bạn đâu có dùng tua vít để đóng đinh đâu (hy vọng thế). Trong database cũng vậy: chọn đúng kiểu dữ liệu ảnh hưởng rất nhiều đến hiệu năng, tiết kiệm bộ nhớ và dễ quản lý dữ liệu. Ví dụ, nếu lưu tiền bằng REAL thì có thể gặp vấn đề về độ chính xác, còn dùng TEXT thay vì VARCHAR cho chuỗi ngắn sẽ làm database tốn nhiều bộ nhớ hơn.

Khi chọn kiểu dữ liệu, nhớ cân nhắc mấy yếu tố sau:

Tính chất dữ liệu
Xác định xem dữ liệu thuộc loại nào: số, chuỗi, giá trị logic, ngày tháng hay thứ gì phức tạp hơn như cấu trúc JSON chẳng hạn.

Dung lượng dữ liệu
Bạn định lưu bao nhiêu dữ liệu? Ví dụ, cho text tối đa 50 ký tự thì nên chọn VARCHAR(50) thay vì TEXT.

Độ chính xác và phạm vi
Có cần độ chính xác cao không (ví dụ cho tính toán tài chính)? Có muốn giới hạn phạm vi giá trị không?

Tần suất và kiểu truy vấn
Bạn sẽ truy cập dữ liệu thường xuyên không? Lưu ý là kiểu phức tạp như JSONB sẽ tốn nhiều tài nguyên xử lý hơn.

Ví dụ chọn kiểu dữ liệu

Dữ liệu khác nhau thì nhiệm vụ cũng khác nhau. Có chỗ cần chính xác từng đồng, có chỗ chỉ cần lưu cho đủ. Dưới đây là ví dụ chọn kiểu dữ liệu phù hợp cho từng tình huống cụ thể.

Dữ liệu tài chính

Khi lưu tiền, giống như kế toán, sai số là không chấp nhận được. Vì vậy, chọn tốt nhất là kiểu NUMERIC để đảm bảo độ chính xác cao. Ví dụ mình muốn tạo bảng với các cột như sau:

Tên cột Kiểu dữ liệu Ghi chú
id SERIAL Khóa chính
amount NUMERIC(10, 2) Mười chữ số, trong đó hai số sau dấu phẩy
currency_code CHAR(3) Mã tiền tệ ISO, ví dụ "USD", "EUR"
transaction_date TIMESTAMP Thời gian giao dịch, mặc định là thời gian hiện tại

Tại sao không dùng REAL? Vì số thực có thể bị mất chính xác, mà với tài chính thì chuyện này rất nguy hiểm.

Dữ liệu chuỗi

Nếu bạn lưu tên user, địa chỉ hay bất kỳ chuỗi nào, luôn đặt giới hạn độ dài tối đa nếu có thể. Ví dụ, VARCHAR(50) thay vì TEXT. Như vậy sẽ tránh lỗi và tối ưu bộ nhớ.

Tên cột Kiểu dữ liệu Ghi chú
id SERIAL Khóa chính
username VARCHAR(50) Login của user, duy nhất và bắt buộc
email VARCHAR(255) Email
bio TEXT Tiểu sử, cho phép text dài

Nếu độ dài chuỗi cố định (ví dụ mã quốc gia hai ký tự), dùng CHAR:

Tên cột Kiểu dữ liệu Ghi chú
code CHAR(2) Mã quốc gia ISO (ví dụ "US"), khóa chính
name VARCHAR(100) Tên quốc gia, bắt buộc nhập

Dữ liệu thời gian

Để lưu thời gian sự kiện hoặc lịch trình, thường dùng TIMESTAMP vì nó chứa cả ngày và giờ.

Tên cột Kiểu dữ liệu Ghi chú
id SERIAL Khóa chính
event_name VARCHAR(100) Tên sự kiện
start_time TIMESTAMP Thời gian bắt đầu sự kiện, bắt buộc
end_time TIMESTAMP Thời gian kết thúc sự kiện, bắt buộc

Nếu chỉ cần giờ mà không cần ngày thì dùng TIME, còn chỉ cần ngày mà không cần giờ thì dùng DATE.

Định danh duy nhất

Khi cần tạo định danh mà đảm bảo duy nhất trên toàn cầu, hãy dùng UUID. Ví dụ, để tạo định danh giao dịch duy nhất:

Tên cột Kiểu dữ liệu Ghi chú
request_id UUID Định danh duy nhất của request, mặc định tạo bằng gen_random_uuid()
endpoint VARCHAR(255) Địa chỉ API endpoint được gọi
timestamp TIMESTAMP Thời gian request, mặc định là thời gian hiện tại

JSONB: cấu trúc phức tạp

Khi cần lưu dữ liệu mà cấu trúc có thể thay đổi hoặc phức tạp, ví dụ cài đặt user hoặc metadata, hãy dùng JSONB.

Tên cột Kiểu dữ liệu Ghi chú
user_id SERIAL Khóa chính (ID user)
preferences JSONB Cài đặt user ở dạng JSON

Dùng JSONB rất tiện, nhưng nhớ là nếu insert/update nhiều thì có thể làm giảm hiệu năng.

Mảng

Mảng phù hợp khi cần lưu danh sách dữ liệu cùng loại. Ví dụ, danh sách tag:

Tên cột Kiểu dữ liệu Ghi chú
id SERIAL Khóa chính
title VARCHAR(255) Tiêu đề bài viết
tags TEXT[] Mảng tag

Tổng quan kiểu dữ liệu theo nhiệm vụ

Loại nhiệm vụ Kiểu dữ liệu khuyên dùng Ví dụ
Định danh bản ghi SERIAL, BIGSERIAL, UUID id SERIAL PRIMARY KEY
Số lượng, số nguyên INTEGER, BIGINT quantity INTEGER
Tính toán tài chính NUMERIC price NUMERIC(10, 2)
Lưu trữ chuỗi VARCHAR(n), TEXT username VARCHAR(50)
Chuỗi ngắn cố định CHAR(n) status CHAR(1)
Ngày và giờ DATE, TIME, TIMESTAMP created_at TIMESTAMP DEFAULT NOW()
Định danh duy nhất UUID id UUID PRIMARY KEY DEFAULT gen_random_uuid()
Cấu trúc phức tạp (JSON) JSONB metadata JSONB
Danh sách giá trị ARRAY tags TEXT[]
Giá trị logic BOOLEAN is_active BOOLEAN

Chắc bạn đã quen với tất cả các kiểu trừ SERIAL. Thực ra SERIAL là INTEGER dùng làm định danh dòng trong bảng.

Nó tự động tăng thêm 1 mỗi khi thêm dòng mới vào bảng. Ví dụ thêm 10 dòng thì dòng đầu id là 1, dòng hai là 2, v.v. Chi tiết về cái này sẽ nói ở bài sau nhé :)

2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Chuyển đổi giá trị tiền tệ sang NUMERIC
Chuyển đổi giá trị tiền tệ sang NUMERIC
2
Nhiệm vụ
SQL SELF, mức độ, bài học
Đã khóa
Trích xuất năm từ ngày dạng text
Trích xuất năm từ ngày dạng text
1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Các kiểu dữ liệu đặc biệt
Các kiểu dữ liệu đặc biệt
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION