Primary Key vs Foreign Key (Khóa chính vs Khóa ngoại)
Bạn sẽ Học được gì
Kết thúc trang này, bạn sẽ có thể:
- Giải thích Khóa chính (Primary Key) là gì và tại sao mọi bảng đều cần một
- Giải thích Khóa ngoại (Foreign Key) là gì và cách nó thiết lập mối quan hệ giữa các bảng
- So sánh Khóa chính và Khóa ngoại — mục đích, ràng buộc (Constraint), và hành vi của chúng
- Hiểu Tính toàn vẹn tham chiếu (Referential Integrity) và cách Khóa ngoại thực thi nó
- Chọn giữa Khóa tự nhiên (Natural Key) và Khóa thay thế (Surrogate Key) với các đánh đổi
- Áp dụng các Best Practices khi định nghĩa khóa trong schema thực tế
Vấn đề: Nhận diện và Liên kết Dữ liệu
Hãy tưởng tượng một cơ sở dữ liệu cho nền tảng thương mại điện tử. Bạn có hàng triệu đơn hàng, hàng nghìn sản phẩm, và hàng nghìn người dùng. Hai câu hỏi cơ bản nảy sinh:
- Làm sao để nhận diện duy nhất mỗi dòng dữ liệu? — Không có một định danh đáng tin cậy, bạn không thể phân biệt đơn hàng này với đơn hàng khác, người dùng này với người dùng khác.
- Làm sao để liên kết dữ liệu liên quan giữa các bảng? — Một đơn hàng thuộc về một người dùng và chứa các sản phẩm. Không có mối quan hệ rõ ràng, dữ liệu bị đứt gãy và không đáng tin cậy.
Khóa chính (Primary Key) giải quyết vấn đề đầu tiên. Khóa ngoại (Foreign Key) giải quyết vấn đề thứ hai. Cùng nhau, chúng là xương sống của thiết kế cơ sở dữ liệu quan hệ.
Khóa chính (Primary Key)
Khóa chính (Primary Key) là một cột (hoặc tập hợp các cột) nhận diện duy nhất mỗi dòng trong một bảng. Mọi bảng trong cơ sở dữ liệu quan hệ nên có chính xác một khóa chính.
Thuộc tính
| Thuộc tính | Mô tả |
|---|---|
| Duy nhất (Unique) | Không có hai dòng nào có cùng giá trị khóa chính |
| Không NULL (Not NULL) | Các cột khóa chính không thể chứa giá trị NULL |
| Bất biến (Immutable) | Giá trị khóa chính không nên thay đổi theo thời gian |
| Chỉ một mỗi bảng | Một bảng chỉ có thể có một khóa chính (dù có thể là khóa tổng hợp - Composite Key) |
Tạo Khóa chính
-- Khóa chính một cột
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(100),
email VARCHAR(255)
);
-- Ràng buộc có tên (khuyến nghị cho production)
CREATE TABLE users (
id INT,
name VARCHAR(100),
email VARCHAR(255),
CONSTRAINT pk_users PRIMARY KEY (id)
);
-- Khóa chính tổng hợp (Composite Primary Key - nhiều cột)
CREATE TABLE order_items (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id)
);
Điều gì tạo nên một Khóa chính tốt?
| Tiêu chí | Tại sao quan trọng |
|---|---|
| Duy nhất (Unique) | Không bao giờ trùng lặp — đảm bảo mọi dòng đều có thể nhận diện |
| Không bao giờ NULL | NULL không thể so sánh, nên không thể dùng làm định danh đáng tin cậy |
| Bất biến (Immutable) | Thay đổi khóa chính yêu cầu cập nhật tất cả khóa ngoại tham chiếu đến nó |
| Đơn giản (Simple) | Ưu tiên một cột số nguyên thay vì khóa tổng hợp nhiều cột |
| Hiệu quả (Efficient) | Kiểu dữ liệu nhỏ (INT, BIGINT) đánh chỉ mục và nối (Join) nhanh hơn chuỗi hoặc UUID |
Khóa ngoại (Foreign Key)
Khóa ngoại (Foreign Key) l à một cột (hoặc tập hợp các cột) trong một bảng tham chiếu đến khóa chính của bảng khác. Nó thiết lập mối quan hệ giữa hai bảng và thực thi Tính toàn vẹn tham chiếu (Referential Integrity).
Thuộc tính
| Thuộc tính | Mô tả |
|---|---|
| Tham chiếu khóa chính | Khóa ngoại trỏ đến khóa chính (hoặc khóa duy nhất) trong bảng khác |
| Có thể NULL | Khóa ngoại có thể NULL, nghĩa là mối quan hệ là tùy chọn |
| Có thể trùng lặp | Nhiều dòng có thể tham chiếu đến cùng một dòng cha (Một-nhiều - One-to-Many) |
| Nhiều mỗi bảng | Một bảng có thể có nhiều khóa ngoại tham chiếu đến các bảng khác nhau |
Tạo Khóa ngoại
CREATE TABLE orders (
id INT PRIMARY KEY,
user_id INT,
order_date DATE,
status VARCHAR(20),
CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(id)
);
Tính toàn vẹn Tham chiếu (Referential Integrity)
Tính toàn vẹn tham chiếu đảm bảo rằng mọi giá trị khóa ngoại khớp với một khóa chính tồn tại trong bảng được tham chiếu — không có tham chiếu mồ côi (Orphaned Reference).
- Đơn hàng 101, 102, và 103 hợp lệ —
user_idtham chiếu đến người dùng thực.