Physical Implementation in MySQL
Tổng quan về MySQL Data Types
Toàn bộ các kiểu dữ liệu MySQL: Integer, Decimal, Date/Time, String (CHAR vs VARCHAR), LOBs, Binary, cùng với NULL và ràng buộc DEFAULT, ENUM.
Tổng quan về MySQL Data Types
Khi tạo bảng trong MySQL, mỗi cột phải được gán một kiểu dữ liệu (data type) xác định loại giá trị nào được phép lưu trữ. Chọn đúng kiểu dữ liệu giúp tối ưu bộ nhớ và đảm bảo tính toàn vẹn dữ liệu.
1. Kiểu số nguyên (Integer Types)
| Type | Bytes | Range (Signed) | Ghi chú |
|---|---|---|---|
| TINYINT | 1 | -128 đến 127 | Dùng cho cờ boolean |
| SMALLINT | 2 | -32,768 đến 32,767 | Số lượng nhỏ |
| MEDIUMINT | 3 | -8,388,608 đến 8,388,607 | |
| INT | 4 | -2,147,483,648 đến 2,147,483,647 | Phổ biến nhất |
| BIGINT | 8 | ±9.2 × 10¹⁸ | Số rất lớn |
Thêm UNSIGNED để bắt đầu từ 0 (không âm), ví dụ: INT UNSIGNED cho phạm vi 0 đến 4,294,967,295.
2. Kiểu số thực (Decimal/Float Types)
| Type | Mô tả | Ví dụ |
|---|---|---|
| DECIMAL(p,s) | Số thập phân chính xác. p = tổng chữ số, s = chữ số sau dấu phẩy | DECIMAL(8,2) → 123456.78 |
| FLOAT | Số thực dấu phẩy động (4 bytes), không chính xác tuyệt đối | Khoa học, đo lường |
| DOUBLE | Độ chính xác kép (8 bytes) | Tính toán khoa học |
Lưu ý quan trọng: Dùng DECIMAL cho tiền tệ và dữ liệu tài chính vì không bị lỗi làm tròn như FLOAT.
3. Kiểu ngày giờ (Date/Time Types)
| Type | Format | Phạm vi |
|---|---|---|
| DATE | YYYY-MM-DD | 1000-01-01 đến 9999-12-31 |
| TIME | HH:MM:SS | -838:59:59 đến 838:59:59 |
| DATETIME | YYYY-MM-DD HH:MM:SS | 1000-01-01 đến 9999-12-31 |
| TIMESTAMP | YYYY-MM-DD HH:MM:SS | 1970-01-01 đến 2038 (Unix epoch) |
| YEAR | YYYY | 1901 đến 2155 |
4. Kiểu chuỗi (String Types): CHAR vs VARCHAR
Đây là sự khác biệt quan trọng nhất trong kiểu chuỗi:
CHAR(n)
Fixed-length: Luôn sử dụng đúng n ký tự, bất kể nội dung.
Ví dụ: CHAR(15) lưu 'Hello':
H|e|l|l|o|_|_|_|_|_|_|_|_|_|_
(5 ký tự + 10 khoảng trắng padding)
✅ Nhanh hơn khi cột có độ dài cố định (mã bưu chính, mã quốc gia)
VARCHAR(n)
Variable-length: Chỉ sử dụng đúng số byte cần thiết + 1-2 byte lưu độ dài.
Ví dụ: VARCHAR(15) lưu 'Hello':
H|e|l|l|o
(5 ký tự, không có padding)
✅ Tiết kiệm bộ nhớ khi độ dài biến đổi (tên người, địa chỉ)
Khi nào dùng CHAR? Khi dữ liệu luôn có độ dài cố định: mã bưu chính (4 ký tự), mã quốc gia (2 ký tự), số điện thoại định dạng cố định.
Khi nào dùng VARCHAR? Khi độ dài thay đổi: tên người, địa chỉ email, mô tả sản phẩm.
5. Kiểu LOB (Large Object)
| Type | Giới hạn | Dùng cho |
|---|---|---|
| TEXT | 65,535 bytes (~64KB) | Văn bản ngắn-trung bình |
| MEDIUMTEXT | 16,777,215 bytes (~16MB) | Bài viết, tài liệu |
| LONGTEXT | 4,294,967,295 bytes (~4GB) | Sách, nội dung lớn |
| BLOB | 65,535 bytes | Dữ liệu nhị phân (ảnh nhỏ) |
| MEDIUMBLOB | ~16MB | Ảnh, audio ngắn |
| LONGBLOB | ~4GB | Video, file lớn |
6. Kiểu nhị phân (Binary Types)
BINARY(n) và VARBINARY(n) tương tự CHAR và VARCHAR nhưng lưu byte thô (không phải text). Dùng cho dữ liệu mã hóa, hash, UUID dạng binary.
7. NULL — Giá trị "không biết"
- Số 0
- Chuỗi rỗng ''
- Khoảng trắng ' '
MySQL sử dụng ternary logic (logic ba giá trị) với NULL:
| Biểu thức | Kết quả | Giải thích |
|---|---|---|
NULL = NULL | NULL (không phải TRUE) | Không biết = không biết → không thể so sánh |
NULL = 0 | NULL | Không biết có bằng 0 không → không biết |
NULL + 5 | NULL | Tính toán với unknown → unknown |
Cách kiểm tra NULL đúng: Dùng IS NULL hoặc IS NOT NULL, không bao giờ dùng = NULL.
SELECT * FROM Student WHERE PhoneNumber IS NULL; SELECT * FROM Student WHERE PhoneNumber IS NOT NULL;
Khai báo cột không cho phép NULL:
name VARCHAR(100) NOT NULL
8. Ràng buộc DEFAULT
DEFAULT đặt giá trị mặc định khi INSERT không cung cấp giá trị cho cột đó:
CREATE TABLE Staff (
StaffID INT NOT NULL,
StaffName VARCHAR(100) NOT NULL,
Gender ENUM('M','F','Other') DEFAULT 'Other',
IsActive TINYINT DEFAULT 1,
JoinDate DATE DEFAULT (CURRENT_DATE)
);
Khi INSERT không cung cấp Gender → tự động lưu 'Other'. Khi INSERT không cung cấp IsActive → tự động lưu 1.
9. Kiểu ENUM
ENUM giới hạn cột chỉ nhận một trong các giá trị liệt kê sẵn:
Gender ENUM('M', 'F', 'Other') DEFAULT 'Other'
Ưu điểm: Đảm bảo dữ liệu hợp lệ (không thể nhập 'Male', 'Female' hay giá trị không có trong danh sách). MySQL lưu nội bộ bằng số nguyên (1, 2, 3...) nên rất nhỏ gọn.
Ví dụ thực tế từ bài giảng — bảng Staff với đầy đủ ràng buộc:
CREATE TABLE Staff (
StaffID INT NOT NULL,
StaffName VARCHAR(100) NOT NULL,
Gender ENUM('M','F','Other') DEFAULT 'Other',
BranchID INT NOT NULL,
PRIMARY KEY (StaffID),
FOREIGN KEY (BranchID) REFERENCES Branch(BranchID)
);
Ví dụ bảng PropertyInspection từ case study 3NF:
CREATE TABLE PropertyInspection (
InspectionID INT NOT NULL AUTO_INCREMENT,
PropertyID INT NOT NULL,
StaffID INT NOT NULL,
InspDate DATE NOT NULL,
InspTime TIME,
Comments TEXT,
PRIMARY KEY (InspectionID),
FOREIGN KEY (PropertyID) REFERENCES Property(PropertyID),
FOREIGN KEY (StaffID) REFERENCES Staff(StaffID)
);