Câu lệnh CREATE TABLE trong MySQL được sử dụng để tạo bảng mới trong cơ sở dữ liệu. Việc hiểu rõ cú pháp và cách sử dụng câu lệnh này rất quan trọng khi bạn muốn thiết kế cơ sở dữ liệu. Chúng ta sẽ bắt đầu từ ví dụ cơ bản và dần đến các tình huống nâng cao hơn.

1. Cú pháp cơ bản của câu lệnh CREATE TABLE

CREATE TABLE table_name (
    column1 datatype constraints,
    column2 datatype constraints,
    ...
);

Trong đó:

  • table_name: Tên của bảng.
  • column1, column2: Tên các cột trong bảng.
  • datatype: Kiểu dữ liệu của cột (như INT, VARCHAR, DATE, v.v.).
  • constraints: Các ràng buộc như PRIMARY KEY, NOT NULL, UNIQUE, v.v.

Ví dụ cơ bản:

Tạo bảng employees với các cột id, name, age, và salary:

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    age INT,
    salary DECIMAL(10, 2)
);
  • id: Cột kiểu INT, là khóa chính (PRIMARY KEY), và tự động tăng giá trị (AUTO_INCREMENT).
  • name: Cột kiểu VARCHAR với độ dài tối đa 100 ký tự, không cho phép giá trị NULL.
  • age: Cột kiểu INT, lưu trữ độ tuổi của nhân viên.
  • salary: Cột kiểu DECIMAL lưu trữ lương của nhân viên với tối đa 10 chữ số, trong đó có 2 chữ số thập phân.

2. Thêm các ràng buộc (Constraints)

a. Khóa chính (PRIMARY KEY)

Khóa chính là một ràng buộc giúp xác định duy nhất mỗi bản ghi trong bảng.

CREATE TABLE departments (
    id INT PRIMARY KEY AUTO_INCREMENT,
    department_name VARCHAR(100) NOT NULL
);

Trong ví dụ trên, id là khóa chính, mỗi phòng ban sẽ có một mã số duy nhất.

b. Khóa ngoại (FOREIGN KEY)

Khóa ngoại liên kết hai bảng với nhau, giúp duy trì tính toàn vẹn dữ liệu.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    department_id INT,
    FOREIGN KEY (department_id) REFERENCES departments(id)
);

Cột department_id trong bảng employees là khóa ngoại, liên kết với cột id của bảng departments. Điều này đảm bảo rằng mỗi nhân viên thuộc một phòng ban có tồn tại trong bảng departments.

c. Ràng buộc NOT NULL

Ràng buộc NOT NULL không cho phép giá trị rỗng trong một cột.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    age INT NOT NULL
);

Trong bảng này, cột nameage không được phép để trống.

d. Ràng buộc UNIQUE

Ràng buộc UNIQUE đảm bảo rằng tất cả các giá trị trong cột đó là duy nhất.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(100) UNIQUE
);

Cột email chỉ có thể chứa các giá trị không trùng lặp.

e. Ràng buộc DEFAULT

Ràng buộc DEFAULT thiết lập giá trị mặc định cho một cột khi không có giá trị được cung cấp.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    age INT DEFAULT 30
);

Nếu không nhập tuổi cho nhân viên khi thêm dữ liệu, giá trị mặc định sẽ là 30.


3. Các kiểu dữ liệu trong MySQL

Trong MySQL, có nhiều loại kiểu dữ liệu mà bạn có thể sử dụng cho các cột trong bảng:

  • Kiểu số: INT, DECIMAL, FLOAT, DOUBLE, BIGINT, v.v.
  • Kiểu chuỗi: VARCHAR, CHAR, TEXT, BLOB, v.v.
  • Kiểu ngày tháng: DATE, DATETIME, TIMESTAMP, TIME, YEAR.

Ví dụ sử dụng kiểu dữ liệu:

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    salary DECIMAL(10, 2),
    hire_date DATE
);
  • salary: Kiểu DECIMAL(10, 2) lưu trữ các số có tối đa 10 chữ số, trong đó có 2 chữ số thập phân.
  • hire_date: Kiểu DATE lưu trữ ngày.

4. Tạo bảng với chỉ mục (INDEX)

Chỉ mục (INDEX) giúp tăng tốc độ truy vấn dữ liệu, đặc biệt với các bảng lớn.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    salary DECIMAL(10, 2),
    INDEX (name)
);

Trong bảng này, cột name được tạo chỉ mục, giúp cải thiện hiệu năng truy vấn trên cột này.


5. Tạo bảng với bảng TEMPORARY

Bảng tạm thời (TEMPORARY) chỉ tồn tại trong phiên làm việc hiện tại. Khi phiên làm việc kết thúc hoặc bảng bị xóa, nó sẽ không còn tồn tại.

CREATE TEMPORARY TABLE temp_employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100)
);

Bảng này sẽ bị xóa tự động khi phiên làm việc kết thúc hoặc người dùng thoát khỏi cơ sở dữ liệu.


6. Tạo bảng với phân vùng (PARTITION)

Phân vùng giúp chia nhỏ dữ liệu trong bảng để quản lý và truy vấn hiệu quả hơn.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    salary DECIMAL(10, 2)
)
PARTITION BY RANGE (salary) (
    PARTITION p0 VALUES LESS THAN (3000),
    PARTITION p1 VALUES LESS THAN (6000),
    PARTITION p2 VALUES LESS THAN MAXVALUE
);

Trong bảng này, dữ liệu được phân chia theo khoảng lương (salary), giúp tối ưu hóa việc truy vấn trên dữ liệu lớn.


7. Tạo bảng với mối quan hệ một-nhiều

Ví dụ tạo hai bảng categoriesproducts với mối quan hệ một-nhiều (một danh mục có thể chứa nhiều sản phẩm):

CREATE TABLE categories (
    id INT PRIMARY KEY AUTO_INCREMENT,
    category_name VARCHAR(100) NOT NULL
);

CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    product_name VARCHAR(100) NOT NULL,
    category_id INT,
    FOREIGN KEY (category_id) REFERENCES categories(id)
);

Bảng products chứa khóa ngoại category_id để liên kết với bảng categories, tạo mối quan hệ một danh mục nhiều sản phẩm.


8. Tạo bảng với AUTO_INCREMENT bắt đầu từ giá trị tùy chỉnh

Bạn có thể chỉ định giá trị bắt đầu cho cột AUTO_INCREMENT.

CREATE TABLE orders (
    order_id INT AUTO_INCREMENT PRIMARY KEY,
    product_name VARCHAR(100),
    quantity INT
) AUTO_INCREMENT = 1000;

Trong bảng orders, cột order_id sẽ bắt đầu từ giá trị 1000 thay vì 1.


9. Tạo bảng kết hợp với ràng buộc CHECK

Ràng buộc CHECK giới hạn các giá trị mà cột có thể nhận.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    age INT CHECK (age >= 18)
);

Ràng buộc CHECK trong bảng employees đảm bảo rằng giá trị của age phải lớn hơn hoặc bằng 18.


10. Sử dụng IF NOT EXISTS để tránh lỗi khi bảng đã tồn tại

Khi tạo bảng, bạn có thể sử dụng mệnh đề IF NOT EXISTS để tránh lỗi nếu bảng đã tồn tại.

CREATE TABLE IF NOT EXISTS employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    salary DECIMAL(10, 2)
);

Nếu bảng employees đã tồn tại, câu lệnh này sẽ không gây ra lỗi.


Kết luận:

Câu lệnh CREATE TABLE trong MySQL là nền tảng của việc thiết kế và tạo cơ sở dữ liệu. Việc hiểu rõ cú pháp và sử dụng các ràng buộc như PRIMARY KEY, FOREIGN KEY, NOT NULL, UNIQUE, CHECK sẽ giúp bạn thiết kế cơ sở dữ liệu chặt chẽ và tối ưu hóa hiệu năng truy vấn. Hơn nữa, việc sử dụng các tính năng nâng cao như phân vùng (PARTITION), chỉ mục (INDEX), và bảng tạm thời (TEMPORARY) giúp bạn quản lý dữ liệu hiệu quả hơn trong các tình huống phức tạp.

Các ví dụ nâng cao khác về CREATE TABLE

Dưới đây là một số ví dụ nâng cao về câu lệnh CREATE TABLE trong MySQL, tập trung vào các tình huống phức tạp hơn để bạn có thể ứng dụng trong các dự án thực tế hoặc khi làm việc với cơ sở dữ liệu lớn.


1. Tạo bảng với phân vùng theo HASH

Phân vùng bảng theo HASH giúp phân chia dữ liệu theo các nhóm giá trị hash của cột. Điều này đặc biệt hữu ích khi dữ liệu không có tính tuần tự rõ ràng.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    department_id INT
)
PARTITION BY HASH(department_id)
PARTITIONS 4;

Bảng này sẽ được chia thành 4 phân vùng dựa trên giá trị hash của cột department_id. Khi bạn thêm một bản ghi mới, MySQL sẽ tính toán giá trị hash của department_id và tự động phân loại vào một trong các phân vùng.


2. Tạo bảng với phân vùng theo LIST

Phân vùng theo LIST giúp chia bảng dựa trên danh sách các giá trị cụ thể.

CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    order_date DATE,
    status VARCHAR(50)
)
PARTITION BY LIST COLUMNS(status) (
    PARTITION p_pending VALUES IN ('Pending', 'Awaiting Payment'),
    PARTITION p_processed VALUES IN ('Processed', 'Shipped'),
    PARTITION p_completed VALUES IN ('Completed', 'Delivered')
);

Bảng orders được phân chia theo trạng thái đơn hàng (status). Các đơn hàng có trạng thái PendingAwaiting Payment sẽ được lưu vào phân vùng p_pending, tương tự cho các phân vùng còn lại.


3. Tạo bảng với ràng buộc nhiều khóa ngoại (FOREIGN KEY)

Trong các ứng dụng lớn, bảng có thể liên kết với nhiều bảng khác thông qua nhiều khóa ngoại.

CREATE TABLE order_items (
    order_item_id INT PRIMARY KEY AUTO_INCREMENT,
    order_id INT,
    product_id INT,
    quantity INT,
    FOREIGN KEY (order_id) REFERENCES orders(order_id),
    FOREIGN KEY (product_id) REFERENCES products(product_id)
);

Bảng order_items liên kết với bảng ordersproducts thông qua các cột order_idproduct_id. Điều này tạo ra một mối quan hệ nhiều-nhiều giữa các đơn hàng và sản phẩm, cho phép một đơn hàng có nhiều sản phẩm và một sản phẩm xuất hiện trong nhiều đơn hàng.


4. Tạo bảng với các kiểu dữ liệu JSON

MySQL hỗ trợ kiểu dữ liệu JSON, cho phép lưu trữ các đối tượng JSON phức tạp trực tiếp trong cột của bảng.

CREATE TABLE products (
    product_id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    attributes JSON
);

Trong bảng này, cột attributes có thể lưu trữ các thông tin đặc biệt về sản phẩm dưới dạng JSON, ví dụ như kích thước, màu sắc, và các thuộc tính khác. Ví dụ:

INSERT INTO products (name, attributes) 
VALUES ('Laptop', '{"brand": "Dell", "color": "Black", "specs": {"ram": "16GB", "storage": "512GB SSD"}}');

Lệnh này lưu trữ dữ liệu về một laptop Dell với các thuộc tính đặc biệt trong định dạng JSON.


5. Tạo bảng với khóa ngoại có hành vi ON DELETE CASCADE

Hành vi ON DELETE CASCADE được sử dụng để tự động xóa tất cả các bản ghi liên quan khi một bản ghi trong bảng cha bị xóa.

CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id) 
    ON DELETE CASCADE
);

Khi một khách hàng trong bảng customers bị xóa, tất cả các đơn hàng liên quan trong bảng orders sẽ bị xóa theo.


6. Tạo bảng với cột VIRTUAL hoặc STORED

MySQL hỗ trợ các cột ảo (VIRTUAL) hoặc cột lưu trữ (STORED) để tính toán giá trị dựa trên các cột khác trong bảng. Các cột này giúp bạn không cần phải tính toán lại các giá trị mỗi lần truy vấn.

  • Cột VIRTUAL: Giá trị của cột này được tính toán động mỗi khi truy vấn.
  • Cột STORED: Giá trị được tính toán một lần và lưu trữ trong cơ sở dữ liệu.
CREATE TABLE products (
    product_id INT PRIMARY KEY AUTO_INCREMENT,
    price DECIMAL(10, 2),
    discount DECIMAL(10, 2),
    final_price DECIMAL(10, 2) GENERATED ALWAYS AS (price - discount) VIRTUAL
);

Trong bảng này, final_price được tính tự động bằng công thức price - discount mà không cần phải lưu trữ trực tiếp trong cơ sở dữ liệu.


7. Tạo bảng với chỉ mục không duy nhất (INDEX)

Chỉ mục không duy nhất (INDEX) giúp cải thiện tốc độ truy vấn nhưng không bắt buộc giá trị trong cột đó phải duy nhất.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    department_id INT,
    INDEX (department_id)
);

Ở đây, chỉ mục được tạo trên cột department_id để tăng tốc độ truy vấn dữ liệu mà không bắt buộc giá trị phải duy nhất.


8. Tạo bảng với chỉ mục duy nhất (UNIQUE INDEX)

Chỉ mục duy nhất (UNIQUE INDEX) đảm bảo rằng các giá trị trong một cột phải duy nhất nhưng không phải là khóa chính.

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    email VARCHAR(100),
    UNIQUE INDEX (email)
);

Chỉ mục UNIQUE trên cột email đảm bảo rằng không có hai nhân viên nào có cùng địa chỉ email.


9. Tạo bảng với kiểu dữ liệu không gian (SPATIAL)

MySQL hỗ trợ các loại dữ liệu không gian như POINT, LINESTRING, và POLYGON để lưu trữ thông tin địa lý.

CREATE TABLE locations (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    coordinates POINT,
    SPATIAL INDEX (coordinates)
);

Trong bảng này, cột coordinates lưu trữ các tọa độ địa lý dưới dạng POINT. Chỉ mục không gian (SPATIAL INDEX) giúp tăng tốc độ truy vấn các dữ liệu không gian.


10. Tạo bảng với phân vùng kết hợp (SUBPARTITION)

Bạn có thể kết hợp nhiều loại phân vùng, ví dụ như phân vùng RANGE kết hợp với phân vùng HASH.

CREATE TABLE sales (
    sale_id INT PRIMARY KEY AUTO_INCREMENT,
    sale_date DATE,
    total DECIMAL(10, 2)
)
PARTITION BY RANGE (YEAR(sale_date)) 
SUBPARTITION BY HASH(MONTH(sale_date)) 
SUBPARTITIONS 4 (
    PARTITION p0 VALUES LESS THAN (2010),
    PARTITION p1 VALUES LESS THAN (2020),
    PARTITION p2 VALUES LESS THAN MAXVALUE
);

Trong bảng này:

  • Dữ liệu được phân vùng dựa trên năm (RANGE theo YEAR(sale_date)).
  • Sau đó, mỗi phân vùng lại được chia nhỏ thành 4 phân vùng con dựa trên tháng (HASH theo MONTH(sale_date)).

Điều này giúp quản lý dữ liệu doanh số theo năm và tháng một cách hiệu quả.


11. Tạo bảng với bảng kế thừa (InnoDB vs MyISAM)

MySQL hỗ trợ nhiều loại storage engine, trong đó phổ biến nhất là InnoDBMyISAM. Bạn có thể chỉ định storage engine khi tạo bảng:

CREATE TABLE blog_posts (
    post_id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(255),
    content TEXT
) ENGINE=MyISAM;

Trong ví dụ này, bảng blog_posts được lưu trữ dưới dạng MyISAM. InnoDB thường được sử dụng với các bảng có nhiều khóa ngoại và giao dịch (transaction), còn MyISAM thường được sử dụng cho các bảng không cần giao dịch hoặc quan hệ khóa ngoại.


12. Tạo bảng sử dụng kiểu dữ liệu SET và ENUM

MySQL hỗ trợ các kiểu dữ liệu SETENUM để lưu trữ các tập giá trị cố định.

  • Kiểu dữ liệu ENUM: Lưu trữ một giá trị duy nhất trong danh sách cố định.
CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    gender ENUM('Male', 'Female', 'Other')
);

Cột gender chỉ có thể nhận một trong các giá trị: 'Male', 'Female', hoặc 'Other'.

  • Kiểu dữ liệu SET: Lưu trữ một hoặc nhiều giá trị từ một danh sách cố định.
CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100),
    skills SET('PHP', 'JavaScript', 'Python', 'Java')
);

Cột skills có thể lưu trữ nhiều kỹ năng cho một nhân viên, ví dụ: PHP, JavaScript.


Những ví dụ trên bao quát nhiều tình huống sử dụng nâng cao cho câu lệnh CREATE TABLE trong MySQL, giúp tối ưu hóa hiệu suất, quản lý dữ liệu hiệu quả và phù hợp với các yêu cầu cụ thể trong các hệ thống phức tạp.