Study Web

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)

TypeBytesRange (Signed)Ghi chú
TINYINT1-128 đến 127Dùng cho cờ boolean
SMALLINT2-32,768 đến 32,767Số lượng nhỏ
MEDIUMINT3-8,388,608 đến 8,388,607
INT4-2,147,483,648 đến 2,147,483,647Phổ biến nhất
BIGINT8±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)

TypeMô 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ẩyDECIMAL(8,2) → 123456.78
FLOATSố thực dấu phẩy động (4 bytes), không chính xác tuyệt đốiKhoa 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)

TypeFormatPhạm vi
DATEYYYY-MM-DD1000-01-01 đến 9999-12-31
TIMEHH:MM:SS-838:59:59 đến 838:59:59
DATETIMEYYYY-MM-DD HH:MM:SS1000-01-01 đến 9999-12-31
TIMESTAMPYYYY-MM-DD HH:MM:SS1970-01-01 đến 2038 (Unix epoch)
YEARYYYY1901 đế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)

TypeGiới hạnDùng cho
TEXT65,535 bytes (~64KB)Văn bản ngắn-trung bình
MEDIUMTEXT16,777,215 bytes (~16MB)Bài viết, tài liệu
LONGTEXT4,294,967,295 bytes (~4GB)Sách, nội dung lớn
BLOB65,535 bytesDữ liệu nhị phân (ảnh nhỏ)
MEDIUMBLOB~16MBẢnh, audio ngắn
LONGBLOB~4GBVideo, file lớn

6. Kiểu nhị phân (Binary Types)

BINARY(n)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"

NULL không phải là:
  • Số 0
  • Chuỗi rỗng ''
  • Khoảng trắng ' '
NULL là "unknown value" — giá trị chưa xác định.

MySQL sử dụng ternary logic (logic ba giá trị) với NULL:

Biểu thứcKết quảGiải thích
NULL = NULLNULL (không phải TRUE)Không biết = không biết → không thể so sánh
NULL = 0NULLKhông biết có bằng 0 không → không biết
NULL + 5NULLTí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)
);