Khóa ngoại tổng hợp và khóa tự tham chiếu
Khóa tổng hợp gồm hai hoặc nhiều cột xác định duy nhất một bản ghi và phải được tham chiếu cùng nhau. Mẫu này được dùng khi khóa tự nhiên trải rộng nhiều trường, hoặc khi bạn muốn ngăn mối quan hệ trùng lặp. Ví dụ, bạn có một học phần được xác định bởi (course_id, semester) hoặc một bảng liên kết có student_id và course_id làm khóa chính tổng hợp.
-- Defines courses table
CREATE TABLE course_offerings (
course_id INT,
semester VARCHAR(10),
-- Composite primary key ensures a course can only be offered once per semester
PRIMARY KEY (course_id, semester)
);
-- Create enrollment table
CREATE TABLE enrollment (
student_id INT,
course_id INT,
semester VARCHAR(10),
-- This foreign key links enrollment records to a valid course offering
FOREIGN KEY (course_id, semester)
REFERENCES course_offerings(course_id, semester)
);
Khóa ngoại tự tham chiếu hay khóa ngoại đệ quy là khóa ngoại tham chiếu đến khóa chính trong cùng một bảng. Mẫu này phổ biến trong dữ liệu phân cấp như Nhân viên → Quản lý. Cách này cho phép biểu diễn các mối quan hệ đệ quy mà không cần tạo bảng bổ sung.
Trong truy vấn dưới đây, manager_id tham chiếu employee_id trong cùng một bảng.
CREATE TABLE employees (
employee_id INT PRIMARY KEY,
name VARCHAR(100),
-- manager_id references employee_id in the same table
manager_id INT,
FOREIGN KEY (manager_id) REFERENCES employees(employee_id)
);
Làm việc với dữ liệu và đảm bảo toàn vẹn
Giờ đây chúng ta biết khóa ngoại được dùng để đảm bảo tính toàn vẹn dữ liệu trong cơ sở dữ liệu. Phần này, chúng ta sẽ xem xét các yếu tố thực tiễn khi làm việc với khóa ngoại cho các thao tác SQL, những thách thức thường gặp và cách quản lý ràng buộc.
Các thao tác INSERT, UPDATE và DELETE
Hãy xem các thao tác này tương tác với khóa ngoại như thế nào.
Thao tác chèn với khóa ngoại
Để chèn một bản ghi con, giá trị ở bảng cha được tham chiếu phải tồn tại. Nếu không, thao tác chèn sẽ thất bại. Ví dụ, truy vấn dưới đây sẽ chèn bản ghi vào bảng orders nếu bảng users có bản ghi với user_id là 1.
-- users table contains user_id = 1
INSERT INTO orders (order_id, user_id, order_date)
VALUES (100, 1, '2024-02-01');
Nếu bạn cố chèn một bản ghi cho người dùng không tồn tại trong bảng cha, bạn sẽ nhận lỗi cho thấy vi phạm ràng buộc khóa ngoại.
-- user_id = 999 does NOT exist in users table
INSERT INTO orders (order_id, user_id, order_date)
VALUES (101, 999, '2024-02-01');
ERROR: insert or update on table "orders" violates foreign key constraint "fk_orders_users"
Thao tác cập nhật và hành vi dây chuyền
Cập nhật có thể ảnh hưởng đến bảng có khóa ngoại hoặc bảng khóa chính. Ví dụ, nếu bạn cập nhật khóa ngoại ở bảng orders, thao tác sẽ chỉ thành công nếu khóa chính tồn tại ở bảng cha. Chẳng hạn, cập nhật dưới đây chỉ thành công nếu users.user_id = 5 exists.
-- updating foreign key value
UPDATE orders
SET user_id = 5
WHERE order_id = 100;
Từ ví dụ trên, bạn không thể cập nhật khóa chính nếu không có ON UPDATE CASCADE do các dòng con vẫn tham chiếu 1. Để tránh điều này, trước tiên ta xóa ràng buộc khóa ngoại hiện có, rồi tạo lại với ON UPDATE CASCADE được bật. Với cách này, các giá trị orders.user_id liên quan sẽ được cập nhật tự động.
-- Drop existing foreign key constraint
ALTER TABLE orders
DROP CONSTRAINT fk_orders_users;
-- Recreate FK with ON UPDATE CASCADE enabled
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON UPDATE CASCADE; -- Automatically update child rows when parent key changes
UPDATE users
SET user_id = 500
WHERE user_id = 1;
Thao tác xóa và cơ chế dây chuyền
Nếu bạn cố xóa một dòng cha khi chưa có quy tắc dây chuyền, thao tác xóa sẽ thất bại và bạn sẽ nhận được lỗi. Khi thêm mệnh đề ON DELETE CASCADE, nó yêu cầu cơ sở dữ liệu tự động xóa mọi dòng con liên quan khi bản ghi cha bị xóa, để giữ mọi thứ nhất quán.
Trong ví dụ dưới đây, chúng ta tạo khóa ngoại trên orders.user_id tham chiếu users.user_id. Với ON DELETE CASCADE, nếu một người dùng bị xóa khỏi bảng users, tất cả đơn hàng liên quan sẽ bị xóa tự động.
-- Add a new foreign key constraint to the orders table
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE CASCADE; -- Delete orders automatically when user is deleted
Đôi khi bạn có thể muốn cơ sở dữ liệu tự xử lý việc xóa. Bạn có thể thực thi điều này với ON DELETE SET NULL khi tạo bảng. Tùy chọn này sẽ đặt các cột khóa ngoại ở bảng con thành NULL nếu bản ghi cha thay đổi hoặc bị xóa.
CREATE TABLE orders (
order_id INT PRIMARY KEY,
user_id INT, -- FK referencing users.user_id
order_date DATE,
FOREIGN KEY (user_id)
REFERENCES users(user_id)
ON DELETE SET NULL -- If a user is deleted, set user_id in orders to NULL
);
Xử lý các thách thức thường gặp
Khi bạn thiết kế các cơ sở dữ liệu phức tạp, khả năng cao sẽ gặp vấn đề với khóa ngoại. Sau đây là những vấn đề phổ biến tôi từng gặp với khóa ngoại và các giải pháp thực tiễn cho từng vấn đề.
-
Kiểu dữ liệu không khớp: Nếu cột khóa ngoại và cột khóa chính được tham chiếu có kiểu dữ liệu không tương thích, ràng buộc sẽ không thể tạo. Để tránh điều này, hãy luôn chuẩn hóa kiểu dữ liệu giữa các bảng liên quan.
-
Phụ thuộc vòng tròn: Xảy ra khi hai bảng tham chiếu lẫn nhau, có thể gây kẹt khi chèn dữ liệu. Để khắc phục, bạn nên đánh giá lại thiết kế lược đồ hoặc tạo bảng không có khóa ngoại trước, nạp dữ liệu nền tảng, rồi dùng
ALTER TABLEđể thêm ràng buộc. -
Khóa ngoại treo: Vấn đề xảy ra khi khóa ngoại của bảng con trỏ tới một bảng cha không tồn tại. Để sửa, hãy dùng các hành động dây chuyền để xác thực dữ liệu trong các thao tác xóa và cập nhật.
Quản lý thay đổi và xóa ràng buộc
Đôi khi bạn có thể muốn chỉnh sửa ràng buộc khóa ngoại khi thiết kế lại lược đồ cơ sở dữ liệu. Dưới đây là các cách xóa khóa ngoại với một chút khác biệt cú pháp giữa các phương ngữ SQL.
Trong PostgreSQL, SQL Server và Oracle, chúng ta dùng câu lệnh DROP CONSTRAINT.
-- Drop foreign key
ALTER TABLE orders
DROP CONSTRAINT fk_orders_users;
Tuy nhiên, trong MySQL, chúng ta dùng câu lệnh DROP FOREIGN KEY để loại bỏ khóa ngoại.
-- Drop foreign key
ALTER TABLE orders
DROP FOREIGN KEY fk_orders_users;
Bạn cần lưu ý rằng việc loại bỏ ràng buộc khóa ngoại sẽ gỡ bỏ cơ chế thực thi toàn vẹn tham chiếu của cơ sở dữ liệu. Sau khi gỡ, bạn có thể chèn hoặc cập nhật dữ liệu vi phạm mối quan hệ, điều này có thể dẫn tới dữ liệu lỗi hoặc không nhất quán.
Hiệu năng và tối ưu hóa
Từ các ví dụ trên, chúng ta đã thấy khóa ngoại đảm bảo thiết kế dữ liệu hiệu quả bằng cách duy trì toàn vẹn dữ liệu. Tuy nhiên, bạn cũng nên hiểu cách tối ưu khóa ngoại để cải thiện hiệu năng của cơ sở dữ liệu. Dưới đây là một số mẹo tôi thấy hữu ích khi làm việc với khóa ngoại:
Đánh chỉ mục và hiệu năng truy vấn
Khi bạn đánh chỉ mục cho khóa ngoại, cơ sở dữ liệu có thể nhanh chóng xác thực các thay đổi trong thao tác chèn, cập nhật hoặc xóa bằng cách tìm khóa tương ứng ở bảng cha. Tương tự, chỉ mục tăng tốc các phép nối (join) liên kết bảng con và bảng cha bằng cách cho phép bộ máy cơ sở dữ liệu ghép các dòng dựa trên giá trị khóa ngoại.
Theo thực tiễn tốt, tôi khuyến nghị bạn chủ động đánh chỉ mục các cột khóa ngoại nếu DBMS không tự xử lý.
Kỹ thuật tối ưu truy vấn
Một số công cụ SQL dùng sự tồn tại của khóa ngoại để áp dụng loại bỏ phép nối (join elimination), kỹ thuật xác định và loại bỏ các phép nối không cần thiết khỏi kế hoạch thực thi truy vấn. Ví dụ, nếu một truy vấn chỉ truy cập các cột từ bảng con nhưng bao gồm phép nối tới bảng cha để lọc mà điều kiện lọc đã được đảm bảo bởi ràng buộc khóa ngoại, phép nối có thể được tối ưu bỏ đi.
Bạn luôn có thể xem kế hoạch thực thi để biết bộ tối ưu hóa xử lý khóa ngoại và phép nối như thế nào. Các tối ưu hóa và hiệu quả của chúng khác nhau giữa các hệ SQL như PostgreSQL, MySQL và SQL Server. Hiểu hành vi của bộ tối ưu hóa trong cơ sở dữ liệu cụ thể của bạn sẽ giúp viết truy vấn hiệu quả và tận dụng tối đa ràng buộc khóa ngoại.
Ví dụ, bạn có thể dùng truy vấn sau để xem kế hoạch thực thi trong PostgreSQL:
-- View execution plan
EXPLAIN ANALYZE
SELECT o.order_id, u.email
FROM orders o
JOIN users u ON o.user_id = u.user_id;
Bảng này tóm tắt cách xem kế hoạch thực thi ở các cơ sở dữ liệu khác nhau:
|
Cơ sở dữ liệu |
Lệnh |
|
PostgreSQL |
|
|
MySQL |
|
|
SQL Server |
Estimated / Actual Execution Plan |
|
Oracle |
|
Tôi khuyến học Joining Data in SQL để tìm hiểu các loại phép nối trong SQL và cách làm việc với các bảng liên quan khác nhau trong cơ sở dữ liệu.
Các tình huống nâng cao và thực tiễn tốt nhất
Vượt ra ngoài việc triển khai cơ bản, bạn có thể dùng khóa ngoại để xây dựng kiến trúc cơ sở dữ liệu vững chắc, có khả năng mở rộng và dễ bảo trì. Phần này, tôi sẽ giải thích các kịch bản chuyên biệt và nguyên tắc thiết kế cấp cao cần cân nhắc khi dùng khóa ngoại.
Quan hệ xuyên cơ sở dữ liệu hoặc xuyên lược đồ
Mặc dù khóa ngoại được thiết kế để thực thi tính toàn vẹn trong một cơ sở dữ liệu hoặc lược đồ duy nhất, các môi trường doanh nghiệp phức tạp hơn thường yêu cầu mối quan hệ vượt qua các ranh giới này. Bảng dưới đây tóm tắt hỗ trợ xuyên lược đồ và xuyên cơ sở dữ liệu cho các phương ngữ SQL khác nhau.
|
Cơ sở dữ liệu |
Hỗ trợ xuyên lược đồ |
Hỗ trợ xuyên cơ sở dữ liệu |
Hạn chế |
|
PostgreSQL |
Có |
Không |
Giới hạn trong một cụm cơ sở dữ liệu. |
|
SQL Server |
Có |
Có |
Tính toàn vẹn xuyên cơ sở dữ liệu được quản lý bởi logic ứng dụng hoặc trigger thay vì khóa ngoại gốc. |
|
Oracle |
Có |
Có |
Database link dùng để truy cập dữ liệu; ràng buộc khóa ngoại gốc thường không được thực thi qua các link. |
|
MySQL |
Không |
Không |
Chỉ giới hạn với các bảng trong cùng cơ sở dữ liệu và cùng engine lưu trữ, như InnoDB. |
|
SQLite |
Không |
Không |
Giới hạn trong một tệp/kết nối cơ sở dữ liệu cụ thể. |
Bảo trì và kiểm toán
Khi bạn xây dựng các khóa ngoại, bạn sẽ nhận thấy chúng thay đổi mỗi khi logic nghiệp vụ thay đổi. Hãy cân nhắc các cách sau để kiểm toán và bảo trì khóa ngoại nhằm đảm bảo chúng luôn được cập nhật:
- Rà soát ràng buộc: Định kỳ kiểm toán các ràng buộc khóa ngoại để đảm bảo chúng vẫn phù hợp với quy tắc nghiệp vụ và thay đổi lược đồ.
- Kiểm tra chỉ mục thường xuyên: Luôn xác minh rằng có chỉ mục trên tất cả các cột khóa ngoại để duy trì hiệu năng tối ưu cho phép nối và xác thực, đặc biệt sau khi nhập dữ liệu lớn hoặc nâng cấp hệ thống.
- Tài liệu hóa và trực quan hóa: Dùng sơ đồ Thực thể - Quan hệ (ER) hoặc công cụ trực quan hóa lược đồ để tài liệu hóa các mối quan hệ. Các hình ảnh này giúp mọi nhà phát triển và nhà phân tích hiểu các mối quan hệ và quy tắc toàn vẹn do khóa ngoại thực thi.
Thực tiễn tốt nhất cho thiết kế cơ sở dữ liệu vững chắc
Để tận dụng tối đa cách khóa ngoại hoạt động, hãy tuân thủ các hướng dẫn sau:
-
Căn chỉnh khóa với logic nghiệp vụ thực: Đảm bảo khóa chính và khóa ngoại thực sự đại diện cho các thực thể thật và mối quan hệ giữa chúng, thay vì dựa vào các định danh nhân tạo hoặc không ổn định.
-
Dùng tên rõ ràng, nhất quán: Chọn tên ràng buộc có tính mô tả, như
fk_orders_user_idđể lược đồ dễ bảo trì, gỡ lỗi và làm việc nhóm. -
Cân bằng giữa chặt chẽ và linh hoạt: Ràng buộc nên bảo vệ chất lượng dữ liệu, nhưng thiết kế vẫn cần cho phép các trường hợp ngoại lệ thực tế hoặc các xác thực do tầng ứng dụng xử lý.
-
Tránh mối quan hệ vòng tròn: Cấu trúc lược đồ sao cho các phụ thuộc khóa ngoại không tạo thành vòng lặp, vì chúng làm cho thao tác chèn, cập nhật và xóa trở nên phức tạp không cần thiết.
-
Tối ưu hiệu năng: Đánh chỉ mục đúng cho khóa ngoại, và áp dụng hành động dây chuyền một cách thận trọng để duy trì toàn vẹn mà không làm chậm hệ thống.
Kết luận
Giống như bất kỳ kỹ năng nào, thành thạo khóa ngoại đến từ thực hành. Tôi khuyến khích bạn thử nghiệm mô hình lược đồ, kiểm tra các hành động dây chuyền và hiểu cách ràng buộc hoạt động trong các tình huống thực tế. Theo thời gian, bạn sẽ học cách cân bằng giữa các quy tắc chặt chẽ với sự linh hoạt mà ứng dụng của bạn cần, tạo ra các cơ sở dữ liệu vừa bền vững vừa thích ứng khi yêu cầu thay đổi.
Giờ bạn đã hiểu cách dùng khóa ngoại trong thiết kế cơ sở dữ liệu, tôi khuyến nghị bạn thử lộ trình nghề nghiệp Associate Data Engineer in SQL để học các nền tảng của kỹ thuật dữ liệu và kho dữ liệu. Cuối cùng, nếu bạn muốn nâng cao kỹ năng quản trị cơ sở dữ liệu cho dữ liệu lớn, tôi khuyến nghị học khóa Introduction to Data Modeling in Snowflake để tìm hiểu thêm về mô hình dữ liệu chiều.

FAQs
Sự khác nhau giữa khóa chính và khóa ngoại là gì?
Khóa chính xác định duy nhất các bản ghi trong chính bảng của nó, còn khóa ngoại tham chiếu đến khóa chính ở bảng khác để thiết lập mối quan hệ.
Một bảng có thể có nhiều khóa ngoại không?
Có, một bảng có thể có nhiều khóa ngoại, mỗi khóa liên kết tới các bảng cha khác nhau.
Một bảng có bắt buộc phải có các cột khóa ngoại duy nhất không?
Không, các cột khóa ngoại có thể chứa giá trị trùng lặp nhưng phải tham chiếu tới các hàng hợp lệ trong bảng cha.
Điều gì xảy ra nếu bạn xóa một bản ghi được khóa ngoại tham chiếu?
Tùy theo ràng buộc, cơ sở dữ liệu có thể hạn chế việc xóa, xóa dây chuyền các hàng liên quan, hoặc đặt giá trị khóa ngoại thành NULL.
Khóa ngoại có bắt buộc trong cơ sở dữ liệu quan hệ không?
Không bắt buộc, nhưng khóa ngoại rất quan trọng để thực thi toàn vẹn quan hệ và thiết kế cơ sở dữ liệu đáng tin cậy.
Trong các cơ sở dữ liệu quan hệ, dữ liệu thường được phân tán qua nhiều bảng, mỗi bảng lưu trữ một khía cạnh cụ thể của một hệ thống lớn hơn. Sự tách biệt này là một lựa chọn thiết kế tốt, nhưng nó cũng tạo ra thách thức khi dữ liệu có thể nhanh chóng trở nên khó diễn giải.
Để giải quyết thách thức này, cơ sở dữ liệu quan hệ dựa vào các quy tắc để thực thi mối quan hệ giữa các bảng. Một trong những cơ chế quan trọng nhất để duy trì cấu trúc và độ tin cậy này là sử dụng khóa ngoại, được dùng để đảm bảo dữ liệu liên quan luôn khớp nhau.
Trong hướng dẫn này, tôi sẽ giải thích cách khóa ngoại hoạt động. Nếu bạn mới bắt đầu với vai trò kỹ sư cơ sở dữ liệu, tôi khuyến nghị học các khóa học Introduction to Relational Databases in SQL và Database Design của chúng tôi để học cách tạo mối quan hệ khi định nghĩa lược đồ cơ sở dữ liệu.
Khóa chính và khóa ngoại
Cả khóa chính (chúng tôi có một bài viết khác) và khóa ngoại đều giúp duy trì cấu trúc và tính toàn vẹn của cơ sở dữ liệu quan hệ. Hãy để tôi giải thích cả hai:
Khóa ngoại là gì?
Khóa ngoại là một trường hoặc tập hợp các trường trong một bảng tham chiếu đến khóa chính ở bảng khác. Khóa ngoại này tạo liên kết giữa các bảng để đảm bảo dữ liệu trong bảng tham chiếu khớp với các bản ghi hợp lệ trong bảng được tham chiếu.
Giả sử bạn có cơ sở dữ liệu với bảng
usersvà bảngorders. Bảngorderscó thể bao gồm cộtuser_id, cột này phải khớp với mộtuser_idhiện có trong bảngusers. Ràng buộc khóa ngoại đảm bảo bạn không thể tạo đơn hàng gắn với một người dùng không tồn tại.Hiểu về khóa ngoại cũng đòi hỏi hiểu về khóa chính, vì khóa ngoại phụ thuộc vào khóa chính để thiết lập và duy trì các mối quan hệ này.
Khóa chính là gì?
Khóa chính là một cột hoặc tổ hợp cột xác định duy nhất mỗi bản ghi trong một bảng. Không có hai dòng nào có thể chia sẻ cùng một giá trị khóa chính, và nó không bao giờ được
NULL. Do đó, một bảng phải có một khóa chính là định danh duy nhất mà các khóa ngoại ở bảng khác tham chiếu đến.Ví dụ, truy vấn dưới đây tạo bảng
usersvới cộtuser_idlàm khóa chính:Những khác biệt chính giữa khóa chính và khóa ngoại
Tôi đã tóm tắt sự khác nhau giữa khóa chính và khóa ngoại trong bảng dưới đây:
Khía cạnh
Khóa chính
Khóa ngoại
Mục đích
Xác định duy nhất mỗi bản ghi trong một bảng
Tạo mối quan hệ bằng cách tham chiếu đến khóa chính ở bảng khác
Tính duy nhất
Phải là duy nhất
Có thể chứa giá trị trùng lặp
Giá trị NULL
Không thể là NULL
Có thể là NULL (trừ khi bị hạn chế)
Vị trí
Được định nghĩa trong chính bảng đó
Tham chiếu khóa chính của bảng khác
Từ giải thích trên, ta thấy khóa chính và khóa ngoại quan trọng trong việc tạo ra các cơ sở dữ liệu có cấu trúc và đáng tin cậy. Chúng phối hợp để đảm bảo dữ liệu nhất quán, mối quan hệ được duy trì và tính toàn vẹn của cơ sở dữ liệu được bảo toàn.
Xây dựng và quản lý khóa ngoại trong SQL
Giờ bạn đã hiểu khóa ngoại là gì và tại sao chúng quan trọng trong cơ sở dữ liệu, hãy học cách định nghĩa, quản lý và kiểm soát hành vi của chúng khi thiết kế cơ sở dữ liệu.
Định nghĩa khóa ngoại với SQL
Bạn có thể thiết lập khóa ngoại trong SQL theo hai cách: khi tạo bảng hoặc thêm sau nếu bảng đã tồn tại.
Ví dụ dưới đây minh họa cách đầu tiên để định nghĩa khóa ngoại khi tạo bảng trong SQL Server.
Cú pháp với PostgreSQL là giống nhau, dù chúng ta dùng
SERIALđể tự động tăng cho khóa chính.Khi thiết lập khóa ngoại trong MySQL, bạn phải dùng
InnoDBnhư dưới đây.Nếu bạn dùng cơ sở dữ liệu Oracle, bạn có thể định nghĩa khóa ngoại, nhưng hãy đảm bảo kiểu dữ liệu ở cả hai bảng khớp chính xác.
Để thêm khóa ngoại vào một bảng hiện có, hãy dùng truy vấn sau:
Tôi khuyến nghị học các khóa học Introduction to SQL Server và Creating PostgreSQL Databases để tìm hiểu thêm về khác biệt giữa các phương ngữ SQL khi tạo cơ sở dữ liệu.
Quản lý ràng buộc và quy ước đặt tên
Khóa ngoại là một loại ràng buộc, tức quy tắc do hệ quản trị cơ sở dữ liệu (DBMS) thực thi để xác thực dữ liệu trong các thao tác như chèn, cập nhật và xóa. Khi ràng buộc khóa ngoại đang hoạt động, cơ sở dữ liệu đảm bảo mọi giá trị nhập vào cột khóa ngoại phải đã tồn tại trong cột khóa chính được tham chiếu.
Thông lệ phổ biến là đặt tên ràng buộc theo mẫu
fk_<child>_<parent>. Từ ví dụ của chúng ta, khóa ngoại thànhfk_orders_users. Nếu bạn đặt tên khóa ngoại theo cách này, lược đồ sẽ dễ đọc, hỗ trợ gỡ lỗi vi phạm ràng buộc và hoạt động tốt với các công cụ migration. Việc xác thực ràng buộc sẽ áp dụng khi bạn thực hiện các thao tác sau:INSERT: Từ chối một dòng nếu giá trị ở bảng cha được tham chiếu không tồn tạiUPDATE: Ngăn việc sửa đổi có thể làm hỏng mối quan hệ.DELETE: Chặn thao tác xóa khi tồn tại các dòng con phụ thuộc.Tính toàn vẹn tham chiếu và các hành động dây chuyền
Tính toàn vẹn tham chiếu là nguyên tắc cốt lõi được ràng buộc khóa ngoại thực thi. Khóa ngoại giúp đảm bảo điều này bằng cách ngăn các bản ghi mồ côi, xảy ra khi các dòng trong bảng con trỏ tới các dòng không tồn tại ở bảng cha.
SQL cũng cho phép bạn thiết lập các hành động dây chuyền (cascading). Đây là các chỉ dẫn tự động cho DBMS về cách xử lý những thay đổi đối với bản ghi được tham chiếu. Ví dụ, bạn có thể dùng các thao tác dây chuyền để làm những việc như:
Hành động
Hành vi
ON DELETE CASCADEXóa các dòng con khi dòng cha bị xóa
ON UPDATE CASCADECập nhật khóa ở bảng con khi khóa ở bảng cha thay đổi
SET NULLKhóa ngoại ở bảng con trở thành
NULLSET DEFAULTBảng con nhận giá trị mặc định
NO ACTION/RESTRICTNgăn các thay đổi làm hỏng mối quan hệ
Ví dụ, truy vấn sau thêm các thao tác dây chuyền để xóa bản ghi người dùng nếu họ bị xóa đơn hàng của mình, và tự động cập nhật nếu
user_idcủa họ thay đổi.Thiết kế mối quan hệ giữa các bảng
Khóa ngoại là những khối xây dựng trong mô hình dữ liệu, dùng để định nghĩa mối quan hệ giữa các bảng trong cơ sở dữ liệu. Phần này, chúng ta sẽ xem các cách mà khóa ngoại đảm bảo tính nhất quán dữ liệu khi liên kết các bảng.
Quan hệ một-nhiều và nhiều-nhiều
Trong quan hệ một-nhiều (1:N), một dòng ở bảng cha có thể được liên kết với nhiều bản ghi ở bảng con. Mối quan hệ này được thực thi bằng cách đặt khóa chính của bảng cha, như
users.user_id, làm khóa ngoại trong bảng con, nhưorders.customer_id.Ví dụ, một người dùng có thể có nhiều đơn hàng, hoặc một phòng ban có thể có nhiều nhân viên.
Ví dụ quan hệ một-nhiều. Hình do Tác giả cung cấp.
Ngược lại, quan hệ nhiều-nhiều (M:N) xảy ra khi nhiều bản ghi ở một bảng có thể liên quan đến nhiều bản ghi ở bảng khác. Vì bạn không thể triển khai trực tiếp quan hệ nhiều-nhiều trong cơ sở dữ liệu chuẩn hóa, chúng ta dùng một bảng liên kết (bridge) chứa hai khóa ngoại.
Ví dụ quan hệ nhiều-nhiều. Hình do Tác giả cung cấp.