1. Khái niệm về khóa ngoại (Foreign Key)

Khóa ngoại (Foreign Key) là một ràng buộc dùng để tạo liên kết giữa hai bảng trong cơ sở dữ liệu. Khóa ngoại là một cột hoặc một tập hợp các cột trong bảng mà giá trị của chúng phải khớp với giá trị của khóa chính (Primary Key) ở bảng khác. Điều này giúp đảm bảo tính toàn vẹn dữ liệu, ngăn chặn việc thêm các bản ghi con mà không có bản ghi cha tương ứng.

2. Cấu trúc khóa ngoại

Một khóa ngoại được định nghĩa khi tạo bảng mới hoặc có thể được thêm vào bảng hiện có. Cấu trúc chung:

CONSTRAINT constraint_name FOREIGN KEY (local_column) REFERENCES foreign_table (foreign_column)
ON DELETE action
ON UPDATE action;
  • constraint_name: Tên của ràng buộc khóa ngoại.
  • local_column: Cột trong bảng hiện tại đóng vai trò là khóa ngoại.
  • foreign_table: Bảng chứa khóa chính mà khóa ngoại tham chiếu.
  • foreign_column: Cột khóa chính trong bảng được tham chiếu.
  • ON DELETE: Hành động khi bản ghi trong bảng tham chiếu bị xóa (có thể là CASCADE, SET NULL, RESTRICT,…).
  • ON UPDATE: Hành động khi bản ghi trong bảng tham chiếu bị cập nhật.

3. Ví dụ sử dụng khóa ngoại trong MySQL

a. Tạo bảng với khóa ngoại

Giả sử bạn có hai bảng: orderscustomers. Mỗi đơn hàng trong bảng orders sẽ chứa một cột customer_id tham chiếu đến cột id của bảng customers.

CREATE TABLE customers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50)
);

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

Trong ví dụ trên:

  • Bảng orders có khóa ngoại customer_id tham chiếu đến cột id của bảng customers.
  • ON DELETE CASCADE: Nếu một khách hàng bị xóa khỏi bảng customers, tất cả các đơn hàng tương ứng trong bảng orders cũng sẽ bị xóa.
  • ON UPDATE CASCADE: Nếu id của khách hàng bị thay đổi, customer_id trong bảng orders cũng sẽ được cập nhật tương ứng.
b. Thêm khóa ngoại vào bảng đã tồn tại

Nếu bảng đã tồn tại và bạn muốn thêm khóa ngoại, bạn có thể sử dụng câu lệnh ALTER TABLE.

Ví dụ: Thêm khóa ngoại vào bảng orders đã tồn tại.

ALTER TABLE orders
ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customers(id)
ON DELETE CASCADE
ON UPDATE CASCADE;
c. Xóa khóa ngoại khỏi bảng

Bạn có thể xóa khóa ngoại bằng cách sử dụng câu lệnh ALTER TABLE với tùy chọn DROP FOREIGN KEY.

Ví dụ: Xóa khóa ngoại fk_customer khỏi bảng orders.

ALTER TABLE orders
DROP FOREIGN KEY fk_customer;

4. Các hành động ON DELETEON UPDATE

Khi tạo khóa ngoại, bạn có thể chỉ định hành động sẽ được thực hiện khi một hàng trong bảng tham chiếu bị xóa hoặc cập nhật. Các hành động phổ biến bao gồm:

  • CASCADE: Xóa hoặc cập nhật tất cả các hàng liên quan.
  • SET NULL: Đặt giá trị khóa ngoại thành NULL khi hàng tham chiếu bị xóa hoặc cập nhật.
  • RESTRICT: Ngăn không cho xóa hoặc cập nhật hàng nếu có hàng liên quan.
  • NO ACTION: Tương tự như RESTRICT, nhưng hành động sẽ diễn ra sau khi các trigger được xử lý.

Ví dụ các hành động:

  • ON DELETE CASCADE: Xóa các hàng trong bảng con khi hàng trong bảng cha bị xóa.
  • ON UPDATE SET NULL: Khi giá trị trong bảng cha được cập nhật, các khóa ngoại tương ứng trong bảng con sẽ được đặt thành NULL.
CREATE TABLE orders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    order_date DATE,
    customer_id INT,
    CONSTRAINT fk_customer FOREIGN KEY (customer_id) REFERENCES customers(id)
    ON DELETE SET NULL
    ON UPDATE CASCADE
);

Trong ví dụ này:

  • Khi một khách hàng bị xóa khỏi bảng customers, giá trị customer_id trong bảng orders sẽ được đặt thành NULL.
  • Nếu id của khách hàng được cập nhật trong bảng customers, các hàng trong bảng orders sẽ tự động cập nhật theo.

5. Kiểm tra khóa ngoại trong bảng

Để kiểm tra các khóa ngoại đã tồn tại trong bảng, bạn có thể sử dụng câu lệnh sau:

SHOW CREATE TABLE orders;

Lệnh này sẽ hiển thị toàn bộ cấu trúc của bảng, bao gồm cả các ràng buộc khóa ngoại.

6. Kết luận

Việc sử dụng khóa ngoại trong MySQL giúp đảm bảo tính toàn vẹn của dữ liệu giữa các bảng liên quan. Bằng cách tạo các ràng buộc khóa ngoại, bạn có thể ngăn chặn việc thêm các bản ghi con mà không có bản ghi cha tương ứng, và xử lý tự động các thay đổi khi dữ liệu trong bảng cha thay đổi.