Primary Key, Foreign Key và Index là gì? Tìm hiểu quan hệ dữ liệu trong Database Phần 1
Khi xây dựng một hệ thống phần mềm, website bán hàng, CRM, ERP, LMS, AI Chatbot hoặc bất kỳ ứng dụng nào có lưu trữ dữ liệu, việc thiết kế Database đúng ngay từ đầu là cực kỳ quan trọng.
Trong Database quan hệ, ba khái niệm mà lập trình viên, quản trị hệ thống và người làm phần mềm cần nắm chắc là Primary Key, Foreign Key và Index.
Nếu Primary Key giúp xác định duy nhất một dòng dữ liệu, Foreign Key giúp liên kết các bảng với nhau thì Index lại giúp tăng tốc truy vấn. Ba thành phần này là nền tảng để xây dựng một Database rõ ràng, dễ mở rộng, dễ bảo trì và có hiệu năng tốt.
- Database Relationship là gì?
- Vì sao cần quan hệ dữ liệu trong Database?
- Primary Key là gì?
- Đặc điểm của Primary Key
- Foreign Key là gì?
- Primary Key và Foreign Key khác nhau thế nào?
- Ví dụ thực tế về Primary Key và Foreign Key
- Thiết kế quan hệ dữ liệu đúng cách
- Index trong Database là gì?
- Clustered Index là gì?
- Non-Clustered Index là gì?
- Ví dụ Index trong Database
- Yêu cầu CPU/RAM/NVMe khi chạy Database nhiều Index
- CloudX hỗ trợ triển khai Database
- Tạm kết Phần 1
1. Database Relationship là gì?
Database Relationship là mối quan hệ giữa các bảng trong cơ sở dữ liệu. Trong hệ quản trị cơ sở dữ liệu quan hệ như MySQL, PostgreSQL, MariaDB, SQL Server hoặc Oracle, dữ liệu thường được chia thành nhiều bảng khác nhau thay vì gom tất cả vào một bảng khổng lồ.
Ví dụ một hệ thống bán hàng có thể có các bảng:
- customers - lưu thông tin khách hàng.
- products - lưu thông tin sản phẩm.
- orders - lưu thông tin đơn hàng.
- order_items - lưu chi tiết sản phẩm trong từng đơn hàng.
- payments - lưu thông tin thanh toán.
Các bảng này không tồn tại riêng lẻ. Chúng liên kết với nhau thông qua khóa chính và khóa ngoại.
customers
|
| customer_id
v
orders
|
| order_id
v
order_items
|
| product_id
v
products
2. Vì sao cần quan hệ dữ liệu trong Database?
Nếu không thiết kế quan hệ dữ liệu đúng, hệ thống có thể gặp rất nhiều vấn đề:
- Dữ liệu bị trùng lặp.
- Khó cập nhật thông tin.
- Dễ sai lệch dữ liệu.
- Khó truy vấn báo cáo.
- Khó mở rộng phần mềm.
- Hiệu năng giảm khi dữ liệu lớn.
Ví dụ nếu mỗi đơn hàng đều lưu lại toàn bộ thông tin khách hàng như tên, số điện thoại, email, địa chỉ, thay vì liên kết đến bảng khách hàng, thì khi khách hàng đổi số điện thoại, hệ thống phải cập nhật ở rất nhiều nơi.
Cách đúng hơn là:
- Bảng customers lưu thông tin khách hàng.
- Bảng orders chỉ lưu customer_id để liên kết đến khách hàng.
Nhờ đó dữ liệu gọn hơn, dễ quản lý hơn và ít sai sót hơn.
3. Primary Key là gì?
Primary Key, hay khóa chính, là cột hoặc tập hợp nhiều cột dùng để xác định duy nhất một dòng dữ liệu trong bảng.
Ví dụ bảng customers:
| customer_id | full_name | phone | |
|---|---|---|---|
| 1 | Nguyễn Văn A | [email protected] | 098xxxxxxx |
| 2 | Trần Thị B | [email protected] | 097xxxxxxx |
Trong bảng trên, customer_id có thể được dùng làm Primary Key vì mỗi khách hàng có một mã duy nhất.
Ví dụ tạo bảng có Primary Key:
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
full_name VARCHAR(255),
email VARCHAR(255),
phone VARCHAR(50)
);
4. Đặc điểm của Primary Key
Một Primary Key tốt thường có các đặc điểm:
- Không được trùng lặp.
- Không được NULL.
- Ổn định, ít thay đổi.
- Dễ dùng để liên kết với bảng khác.
- Được Database tự động tạo index.
Ví dụ không nên dùng số điện thoại làm Primary Key nếu người dùng có thể đổi số điện thoại. Không nên dùng email làm Primary Key nếu hệ thống cho phép đổi email.
Thông thường, nên dùng một cột ID tự tăng hoặc UUID:
CREATE TABLE products (
product_id BIGINT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(255),
price DECIMAL(12,2)
);
Với PostgreSQL:
CREATE TABLE products (
product_id BIGSERIAL PRIMARY KEY,
product_name VARCHAR(255),
price NUMERIC(12,2)
);
5. Foreign Key là gì?
Foreign Key, hay khóa ngoại, là cột trong một bảng dùng để tham chiếu đến Primary Key của bảng khác.
Foreign Key giúp Database đảm bảo mối quan hệ giữa các bảng luôn hợp lệ.
Ví dụ:
- Bảng customers có customer_id là Primary Key.
- Bảng orders có customer_id là Foreign Key tham chiếu đến customers.customer_id.
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY,
customer_id BIGINT,
order_date TIMESTAMP,
total_amount DECIMAL(12,2),
CONSTRAINT fk_orders_customers
FOREIGN KEY (customer_id)
REFERENCES customers(customer_id)
);
Nhờ Foreign Key, bạn không thể tạo đơn hàng cho một khách hàng không tồn tại.
6. Primary Key và Foreign Key khác nhau thế nào?
| Tiêu chí | Primary Key | Foreign Key |
|---|---|---|
| Vai trò | Xác định duy nhất một dòng trong bảng | Liên kết đến dòng dữ liệu ở bảng khác |
| Giá trị trùng lặp | Không được trùng | Có thể trùng |
| Giá trị NULL | Không được NULL | Có thể NULL tùy thiết kế |
| Số lượng trong bảng | Thường chỉ có một Primary Key | Có thể có nhiều Foreign Key |
| Index | Thường tự động có index | Nên tạo index để tăng hiệu năng join |
7. Ví dụ thực tế về Primary Key và Foreign Key
Ví dụ 1: Website bán hàng
Một website bán hàng cần quản lý khách hàng, đơn hàng và sản phẩm.
CREATE TABLE customers (
customer_id BIGINT PRIMARY KEY,
full_name VARCHAR(255),
email VARCHAR(255)
);
CREATE TABLE products (
product_id BIGINT PRIMARY KEY,
product_name VARCHAR(255),
price DECIMAL(12,2)
);
CREATE TABLE orders (
order_id BIGINT PRIMARY KEY,
customer_id BIGINT,
order_date TIMESTAMP,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
CREATE TABLE order_items (
order_item_id BIGINT PRIMARY KEY,
order_id BIGINT,
product_id BIGINT,
quantity INT,
price DECIMAL(12,2),
FOREIGN KEY (order_id) REFERENCES orders(order_id),
FOREIGN KEY (product_id) REFERENCES products(product_id)
);
Mô hình này giúp:
- Một khách hàng có thể có nhiều đơn hàng.
- Một đơn hàng có thể có nhiều sản phẩm.
- Một sản phẩm có thể xuất hiện trong nhiều đơn hàng.
- Dữ liệu không bị lặp lại quá nhiều.
Ví dụ 2: Canvas LMS
Một hệ thống LMS có thể có:
- users.
- courses.
- enrollments.
- assignments.
- submissions.
Quan hệ dữ liệu:
users.user_id
|
v
enrollments.user_id
courses.course_id
|
v
enrollments.course_id
assignments.assignment_id
|
v
submissions.assignment_id
Nhờ thiết kế đúng Primary Key và Foreign Key, hệ thống có thể quản lý học viên, khóa học, bài tập và bài nộp một cách rõ ràng.
8. Thiết kế quan hệ dữ liệu đúng cách
Một số nguyên tắc quan trọng:
- Mỗi bảng nên đại diện cho một đối tượng rõ ràng.
- Mỗi bảng nên có Primary Key.
- Dùng Foreign Key để liên kết bảng.
- Không lưu lặp dữ liệu quá nhiều.
- Đặt tên cột nhất quán.
- Đánh index cho các cột hay join, filter, search.
- Không tạo quá nhiều quan hệ phức tạp nếu không cần.
Ví dụ đặt tên tốt:
customers.customer_id
orders.order_id
orders.customer_id
products.product_id
order_items.product_id
Ví dụ đặt tên khó hiểu:
customers.id
orders.c_id
products.pid
order_items.p
9. Index trong Database là gì?
Index trong Database là cấu trúc dữ liệu giúp tăng tốc truy vấn.
Có thể hiểu Index giống như mục lục của một cuốn sách. Nếu không có mục lục, bạn phải đọc từng trang để tìm nội dung. Nếu có mục lục, bạn có thể tìm nhanh đến đúng trang cần đọc.
Trong Database, nếu bảng có hàng triệu dòng mà không có Index, câu truy vấn có thể phải quét toàn bộ bảng.
Ví dụ truy vấn:
SELECT *
FROM customers
WHERE email = '[email protected]';
Nếu cột email có Index, Database có thể tìm nhanh hơn rất nhiều.
CREATE INDEX idx_customers_email
ON customers(email);
10. Clustered Index là gì?
Clustered Index là loại index quyết định cách dữ liệu được sắp xếp vật lý hoặc logic trong bảng, tùy hệ quản trị Database.
Trong nhiều hệ quản trị, Primary Key thường gắn với Clustered Index hoặc cấu trúc lưu trữ chính của bảng.
Ví dụ dễ hiểu:
- Dữ liệu trong bảng được sắp xếp theo customer_id.
- Khi tìm theo customer_id, Database truy xuất rất nhanh.
Ưu điểm:
- Truy vấn theo khóa chính rất nhanh.
- Phù hợp dữ liệu cần tìm theo ID.
- Hữu ích cho range query nếu key được thiết kế tốt.
Nhược điểm:
- Không nên chọn khóa thường xuyên thay đổi.
- Không nên chọn khóa quá dài nếu không cần thiết.
- Thiết kế sai có thể ảnh hưởng hiệu năng ghi dữ liệu.
11. Non-Clustered Index là gì?
Non-Clustered Index là index phụ, không quyết định trực tiếp thứ tự lưu trữ chính của dữ liệu.
Ví dụ bạn có bảng customers với Primary Key là customer_id, nhưng thường xuyên tìm theo email. Khi đó bạn có thể tạo Non-Clustered Index trên email.
CREATE INDEX idx_customers_email
ON customers(email);
Ưu điểm:
- Tăng tốc tìm kiếm theo cột không phải Primary Key.
- Hữu ích cho filter, join, sort.
- Có thể tạo nhiều index phụ cho các nhu cầu truy vấn khác nhau.
Nhược điểm:
- Tốn thêm dung lượng lưu trữ.
- Làm chậm ghi dữ liệu nếu có quá nhiều index.
- Cần theo dõi index nào thật sự được sử dụng.
12. Ví dụ Index trong Database
Ví dụ 1: Index cho email khách hàng
CREATE INDEX idx_customers_email
ON customers(email);
Phù hợp khi thường xuyên tìm khách hàng theo email:
SELECT *
FROM customers
WHERE email = '[email protected]';
Ví dụ 2: Index cho đơn hàng theo khách hàng
CREATE INDEX idx_orders_customer_id
ON orders(customer_id);
Phù hợp khi thường xuyên lấy danh sách đơn hàng của một khách hàng:
SELECT *
FROM orders
WHERE customer_id = 10;
Ví dụ 3: Composite Index
Composite Index là index trên nhiều cột.
CREATE INDEX idx_orders_customer_status
ON orders(customer_id, status);
Phù hợp với truy vấn:
SELECT *
FROM orders
WHERE customer_id = 10
AND status = 'paid';
Ví dụ 4: Index cho ngày tạo đơn hàng
CREATE INDEX idx_orders_created_at
ON orders(created_at);
Phù hợp khi cần báo cáo đơn hàng theo thời gian:
SELECT *
FROM orders
WHERE created_at >= '2026-01-01'
AND created_at < '2026-02-01';
13. Yêu cầu CPU/RAM/NVMe khi chạy Database nhiều Index
Khi Database có nhiều bảng, nhiều quan hệ và nhiều index, tài nguyên máy chủ ảnh hưởng rất lớn đến hiệu năng.
| Quy mô hệ thống | CPU khuyến nghị | RAM khuyến nghị | NVMe khuyến nghị | Ghi chú |
|---|---|---|---|---|
| Website nhỏ | 2 vCPU | 4 GB RAM | 40-60 GB NVMe | WordPress, website giới thiệu |
| Website bán hàng | 4 vCPU | 8-16 GB RAM | 100-200 GB NVMe | Nhiều sản phẩm, đơn hàng, khách hàng |
| CRM/ERP | 8 vCPU | 16-32 GB RAM | 200-300 GB NVMe | Nhiều bảng, nhiều join, báo cáo |
| LMS/Canvas | 8-16 vCPU | 32 GB RAM+ | 300-500 GB NVMe | Nhiều user, khóa học, bài tập, submission |
| Database production riêng | 16 vCPU+ | 64 GB RAM+ | 500 GB-1 TB NVMe+ | Nên tách riêng Database Server |
14. CloudX hỗ trợ triển khai Database trên Cloud VPS NVMe
CloudX - Hạ tầng Cloud VPS NVMe tối ưu cho Database doanh nghiệp
CloudX hỗ trợ doanh nghiệp triển khai, tối ưu và vận hành Database hiệu quả:
- Tư vấn thiết kế Database ban đầu.
- Cài đặt MySQL, MariaDB, PostgreSQL.
- Tối ưu Primary Key, Foreign Key, Index.
- Tối ưu slow query.
- Backup và restore dữ liệu.
- Replication và High Availability.
- Giám sát CPU/RAM/Disk I/O.
- Bảo mật Database bằng Firewall và giới hạn IP.
CloudX phù hợp cho:
- Website doanh nghiệp.
- WordPress/WooCommerce.
- CRM/ERP.
- Canvas LMS.
- AI Chatbot.
- Phần mềm nội bộ.
Hotline/Zalo: 0983.357.585
15. Tạm kết Phần 1
Trong phần 1, chúng ta đã tìm hiểu Database Relationship là gì, Primary Key là gì, Foreign Key là gì, cách thiết kế quan hệ dữ liệu, Index là gì, Clustered Index, Non-Clustered Index và một số ví dụ thực tế.
Ở phần 2, CloudX sẽ tiếp tục giải thích:
- Normalization là gì?
- 1NF, 2NF, 3NF là gì?
- Khi nào nên Denormalization?
- Thiết kế Database cho doanh nghiệp.




