MySQL làm tròn số DECIMAL khi độ chính xác (precision) và thang đo (scale) không đủ lớn để chứa giá trị. Giải pháp: định nghĩa DECIMAL(M,D) với M, D đủ lớn.
Vấn đề: Làm tròn không mong muốn
Tạo bảng DECIMAL(7) — mặc định scale = 0:
mysql> CREATE TABLE stopRoundingDemo (
-> Amount DECIMAL(7)
-> );
Query OK, 0 rows affected (0.67 sec)
mysql> INSERT INTO stopRoundingDemo VALUES (7836.783), (1737.67), (110.50);
Cảnh báo: 1 warning mỗi hàng do làm tròn
Kết quả (đã làm tròn thành số nguyên):
mysql> SELECT * FROM stopRoundingDemo;
+--------+ | Amount | +--------+ | 7837 | | 1738 | | 111 | +--------+
Giải pháp: Định nghĩa DECIMAL(precision, scale)
Tạo bảng mới với scale = 4:
mysql> CREATE TABLE stopRoundingDemo2 (
-> Amount DECIMAL(10,4)
-> );
Query OK, 0 rows affected (0.81 sec)
mysql> INSERT INTO stopRoundingDemo2 VALUES (7836.783), (1737.67), (110.50);
Kết quả (giữ nguyên 4 chữ số thập phân):
mysql> SELECT * FROM stopRoundingDemo2;
+-----------+ | Amount | +-----------+ | 7836.7830 | | 1737.6700 | | 110.5000 | +-----------+
Giải thích DECIMAL(M,D)
| Tham số | Ý nghĩa | Ví dụ DECIMAL(10,4) | |
|---|---|---|---|
| M (Precision) | Tổng số chữ số tối đa (trước + sau dấu phẩy) | 10 chữ số | |
| D (Scale) | Số chữ số sau dấu phẩy | 4 chữ số |
| Kiểu | Lưu trữ | Độ chính xác | Dùng cho |
|---|---|---|---|
| FLOAT | 4 byte | ~7 chữ số | Khoa học, gần đúng |
| DOUBLE | 8 byte | ~15 chữ số | Khoa học, gần đúng |
| DECIMAL(M,D) | M+2 byte | Chính xác tuyệt đối | Tiền tệ, tài chính, đo lường |
Khuyến nghị
- Luôn chỉ định scale (D) cho DECIMAL:
DECIMAL(19,4)cho tiền tệ,DECIMAL(10,2)cho giá thường - Không dùng FLOAT/DOUBLE cho tiền tệ
- Kiểm tra warning:
SHOW WARNINGS;sau INSERT