Kiểu dữ liệu nào thích hợp để lưu tiền tệ trong MySQL

Có một bạn đặt câu hỏi cho team FastCloud chúng mình rằng muốn lưu nhiều bản ghi chứa giá trị tiền tệ trong cơ sở dữ liệu MySQL thì dùng kiểu dữ liệu nào là thích hợp? Vì bạn ấy cũng không biết sẽ có bao nhiêu chữ số được nhập vào cho mỗi giá trị. VARCHAR, INT hay các kiểu dữ liệu số khác?

Đây là một câu hỏi theo chúng mình thấy cũng khá là thú vị, câu hỏi thoạt có vẻ đơn giản nhưng suy nghĩ sâu xa một chút thì đúng là cần phải cân nhắc kiểu dữ liệu cho thao tác lưu trữ giá trị tiền tệ này. Trong MySQL kiểu dữ liệu thích hợp để lưu tiền tệ phụ thuộc vào yêu cầu về độ chính xác và hiệu suất.

Một số kiểu dữ liệu MySQL phù hợp để lưu giá trị tiền tệ

1. DECIMAL (hoặc NUMERIC) (khuyến nghị anh em kiểu này)

Cú pháp: DECIMAL(M, D). Trong đó:

M: Tổng số chữ số (cả phần nguyên và phần thập phân).

D: Số chữ số sau dấu thập phân.

Ví dụ: DECIMAL(15,2) (lưu số có tối đa 10 chữ số, trong đó 2 chữ số là phần thập phân).

Ưu điểm:

  • Độ chính xác cao, không bị lỗi làm tròn như kiểu FLOAT hoặc DOUBLE.
  • Phù hợp cho các ứng dụng tài chính và kế toán.

Nhược điểm: Tốn bộ nhớ hơn so với FLOAT hoặc DOUBLE.

Đọc thêm về Sự cố Y2038 về MySQL khá thú vị nè bạn.

2. BIGINT – Nếu lưu tiền dưới dạng đơn vị nhỏ nhất (khuyến nghị)

Lưu tiền theo đơn vị nhỏ nhất (ví dụ: xu, đồng lẻ).

Ví dụ: Lưu giá trị tiền tệ bằng VND thì thay vì lưu 15000.75, ta lưu 1500075 (tính theo đơn vị 1 xu).

Ưu điểm:

  • Tăng hiệu suất vì là số nguyên.
  • Tránh các lỗi làm tròn.

Nhược điểm: Cần chuyển đổi khi hiển thị hoặc tính toán.

3. FLOAT/DOUBLE (chỉ giới thiệu)

Kiểu FLOAT và DOUBLE sử dụng dấu chấm động nên có thể xảy ra sai số khi tính toán. Không phù hợp cho các ứng dụng tài chính.

Kết luận

Như vậy là chúng mình đã giới thiệu tới các bạn những kiểu dữ liệu tốt nhất của MySQL để lưu trữ giá trị tiền tệ của bạn. Tất nhiên là kiểu nào cũng có ưu nhược điểm của nó, tùy vào mục đích sử dụng của bạn mà chúng ta chọn một kiểu phù hợp nhé.

  • Nếu cần độ chính xác cao → Dùng DECIMAL(15,2).
  • Nếu lưu theo đơn vị nhỏ nhất (xu, cents) → Dùng BIGINT.

Chi tiết trao đổi anh em theo dõi trên StackOverflow nhé. Chúc các bạn thành công!