Khóa chính và khóa ngoại trong SQLite với các ví dụ
⚡ Tóm tắt thông minh
Khóa chính và khóa ngoại trong SQLite Đảm bảo tính toàn vẹn dữ liệu bằng cách xác định duy nhất từng hàng và liên kết các bảng liên quan, đảm bảo các giá trị được tham chiếu luôn tồn tại và ngăn ngừa các bản ghi trùng lặp, rỗng hoặc mồ côi trong cơ sở dữ liệu quan hệ.

Các phần dưới đây giải thích SQLite Trình bày chi tiết các ràng buộc, bắt đầu với KHÓA CHÍNH và KHÓA NGOẠI dùng để định nghĩa và kết nối các bảng, và bao gồm các quy tắc KHÔNG ĐƯỢC NULL, MẶC ĐỊNH, DUY NHẤT và KIỂM TRA để xác thực dữ liệu trong mỗi cột.
SQLite Những ràng buộc
Các ràng buộc cột áp đặt các quy tắc lên các giá trị được chèn vào một cột để xác thực dữ liệu. Các ràng buộc này được định nghĩa khi tạo bảng, bên trong phần định nghĩa cột. Chúng giúp dữ liệu được lưu trữ nhất quán và chính xác bằng cách loại bỏ các giá trị vi phạm các quy tắc bạn đặt ra, chẳng hạn như các giá trị trùng lặp, giá trị null hoặc các giá trị không tồn tại trong bảng liên quan.
SQLite Khóa chính
Tất cả các giá trị trong cột khóa chính phải là duy nhất và không được rỗng. Khóa chính xác định duy nhất mỗi hàng trong bảng.
Khóa chính có thể được áp dụng cho chỉ một cột hoặc cho sự kết hợp của nhiều cột. Trong trường hợp thứ hai, sự kết hợp các giá trị của các cột phải là duy nhất đối với tất cả các hàng trong bảng.
Cú pháp:
Có nhiều cách khác nhau để định nghĩa khóa chính trên một bảng:
Trong chính định nghĩa cột:
ColumnName INTEGER NOT NULL PRIMARY KEY;
Là một định nghĩa riêng:
PRIMARY KEY(ColumnName);
Để tạo tổ hợp các cột làm khóa chính:
PRIMARY KEY(ColumnName1, ColumnName2);
SQLite Các ràng buộc NOT NULL, DEFAULT, UNIQUE và CHECK
Ngoài khóa chính, SQLite Cung cấp một số ràng buộc cột để xác thực các giá trị được nhập vào bảng. Các ràng buộc NOT NULL, DEFAULT, UNIQUE và CHECK được định nghĩa trong phần định nghĩa cột, và mỗi ràng buộc đều thực thi một quy tắc cụ thể đối với cột đó. loại dữ liệu và các giá trị.
Ràng buộc KHÔNG NULL
SQLite Ràng buộc NOT NULL ngăn không cho một cột có giá trị null:
ColumnName INTEGER NOT NULL;
Ràng buộc MẶC ĐỊNH
Với SQLite Ràng buộc DEFAULT: nếu bạn không nhập bất kỳ giá trị nào vào một cột, giá trị mặc định sẽ được nhập thay thế.
Ví dụ:
ColumnName INTEGER DEFAULT 0;
Nếu bạn viết câu lệnh INSERT mà không chỉ định giá trị cho cột đó, cột sẽ có giá trị là 0.
Hạn chế duy nhất
SQLite Ràng buộc UNIQUE ngăn chặn việc trùng lặp giá trị giữa tất cả các giá trị trong cột.
Ví dụ:
EmployeeId INTEGER NOT NULL UNIQUE;
Điều này đảm bảo giá trị “EmployeeId” là duy nhất; không cho phép các giá trị trùng lặp. Lưu ý rằng điều này chỉ áp dụng cho các giá trị trong cột “EmployeeId”.
KIỂM TRA Ràng buộc
SQLite Ràng buộc CHECK đặt ra một điều kiện để kiểm tra giá trị được chèn vào. Nếu giá trị không khớp với điều kiện, nó sẽ không được chèn.
Quantity INTEGER NOT NULL CHECK(Quantity > 10);
Bạn không thể nhập giá trị nhỏ hơn 10 vào cột “Số lượng”.
SQLite chính nước ngoài
SQLite Khóa ngoại là một ràng buộc xác minh sự tồn tại của một giá trị có trong một bảng ở một bảng khác có quan hệ với bảng đầu tiên nơi khóa ngoại được định nghĩa.
Khi làm việc với nhiều bảng, có những trường hợp hai bảng liên kết với nhau thông qua một cột chung. Nếu bạn muốn đảm bảo rằng giá trị được chèn vào một trong hai bảng phải tồn tại trong cột của bảng kia, thì bạn nên sử dụng ràng buộc khóa ngoại trên cột chung đó.
Trong trường hợp này, khi bạn cố gắng chèn một giá trị vào cột đó, khóa ngoại sẽ đảm bảo rằng giá trị được chèn tồn tại trong cột của bảng được tham chiếu.
Lưu ý rằng các ràng buộc khóa ngoại không được bật theo mặc định trong SQLiteBạn cần kích hoạt chúng trước bằng cách chạy lệnh sau:
PRAGMA foreign_keys = ON;
Ràng buộc khóa ngoại được đưa vào SQLite bắt đầu từ phiên bản 3.6.19.
Ví dụ về SQLite chính nước ngoài
Giả sử chúng ta có hai bảng: Sinh viên và Khoa.
Bảng Students chứa danh sách sinh viên, và bảng Departments chứa danh sách các khoa. Mỗi sinh viên thuộc về một khoa; nghĩa là, mỗi sinh viên có một cột departmentId.
Bây giờ chúng ta sẽ xem cách ràng buộc khóa ngoại có thể hữu ích để đảm bảo rằng giá trị của mã phòng ban trong bảng Sinh viên phải tồn tại trong bảng Phòng ban.
Vì vậy, nếu chúng ta tạo ràng buộc khóa ngoại trên DepartmentId trong bảng Students, thì mỗi departmentId được chèn vào phải có mặt trong bảng Departments.
CREATE TABLE [Departments] ( [DepartmentId] INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, [DepartmentName] NVARCHAR(50) NULL ); CREATE TABLE [Students] ( [StudentId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, [StudentName] NVARCHAR(50) NULL, [DepartmentId] INTEGER NOT NULL, [DateOfBirth] DATE NULL, FOREIGN KEY(DepartmentId) REFERENCES Departments(DepartmentId) );
Để kiểm tra cách các ràng buộc khóa ngoại có thể ngăn chặn việc chèn một phần tử hoặc giá trị chưa được định nghĩa vào một bảng có quan hệ với bảng khác, chúng ta sẽ xem xét ví dụ sau.
Trong ví dụ này, bảng Departments có mối quan hệ khóa ngoại với bảng Students, vì vậy bất kỳ giá trị departmentId nào được chèn vào bảng Students đều phải tồn tại trong bảng Departments. Nếu bạn cố gắng chèn một giá trị departmentId không tồn tại trong bảng Departments, ràng buộc khóa ngoại sẽ ngăn bạn thực hiện điều đó.
Chúng ta hãy thêm hai phòng ban, “CNTT” và “Nghệ thuật”, vào bảng Phòng ban với các thao tác sau: Truy vấn INSERT:
INSERT INTO Departments VALUES(1, 'IT'); INSERT INTO Departments VALUES(2, 'Arts');
Hai câu lệnh này sẽ chèn hai phòng ban vào bảng Departments. Bạn có thể xác nhận việc hai giá trị đã được chèn bằng cách chạy truy vấn “SELECT * FROM Departments” sau đó:
Sau đó, hãy thử thêm một sinh viên mới với mã phòng ban (departmentId) không tồn tại trong bảng Departments:
INSERT INTO Students(StudentName,DepartmentId) VALUES('John', 5);
Dòng dữ liệu sẽ không được chèn và bạn sẽ nhận được thông báo lỗi: Ràng buộc khóa ngoại không thành công.
Sự khác biệt giữa khóa chính và khóa ngoại trong SQLite
Khóa chính và khóa ngoại đều giúp duy trì tính toàn vẹn dữ liệu, nhưng chúng đóng vai trò khác nhau. Khóa chính xác định các hàng trong một bảng duy nhất, trong khi khóa ngoại liên kết các hàng giữa hai bảng có liên quan. Bảng dưới đây tóm tắt những điểm khác biệt chính.
| Cơ sở | Khóa chính | chính nước ngoài |
|---|---|---|
| Mục đích | Xác định duy nhất từng hàng trong bảng tương ứng. | Tham chiếu đến khóa chính của bảng khác để liên kết chúng. |
| Tính độc đáo | Các giá trị phải là duy nhất | Các giá trị có thể lặp lại, do đó nhiều hàng con có thể chia sẻ một hàng cha. |
| Giá trị rỗng | Không được phép là null | Có thể là null khi mối quan hệ là tùy chọn. |
| Số lượng mỗi bàn | Mỗi bảng chỉ có một khóa chính. | Một bảng có thể có nhiều khóa ngoại. |
| Lập chỉ mục | Được lập chỉ mục tự động | Không được lập chỉ mục tự động; hãy thêm một chỉ mục để cải thiện hiệu suất. |
Trong ví dụ về Sinh viên và Khoa, DepartmentId là khóa chính của bảng Khoa và là khóa ngoại trong bảng Sinh viên, liên kết mỗi sinh viên với một khoa hợp lệ.
SQLite Khóa chính tổng hợp
Khóa chính phức hợp là khóa chính được tạo thành từ hai hoặc nhiều cột. Nó được sử dụng khi không có cột nào là duy nhất khi đứng riêng lẻ, nhưng sự kết hợp của các cột lại là duy nhất đối với mọi hàng. SQLite Coi các giá trị kết hợp như một khóa duy nhất.
Ví dụ, bảng đăng ký có thể cho phép cùng một sinh viên tham gia nhiều khóa học và cùng một khóa học cho nhiều sinh viên, nhưng mỗi cặp sinh viên-khóa học chỉ được xuất hiện một lần:
CREATE TABLE Enrollments ( StudentId INTEGER NOT NULL, CourseId INTEGER NOT NULL, Grade TEXT, PRIMARY KEY (StudentId, CourseId) );
Ở đây, cả StudentId và CourseId đều không duy nhất khi đứng riêng lẻ, nhưng cặp (StudentId, CourseId) thì duy nhất, vì vậy cùng một sinh viên không thể đăng ký cùng một khóa học hai lần. Hãy lưu ý những điểm sau khi sử dụng khóa tổng hợp:
- Sử dụng khóa tổng hợp khi một cột đơn không thể xác định duy nhất một hàng.
- Mỗi cột trong khóa tổng hợp đều tuân theo các quy tắc của khóa chính, do đó giá trị kết hợp phải là duy nhất và không được rỗng.
- Khóa tổng hợp được viết dưới dạng một mệnh đề PRIMARY KEY riêng biệt ở cấp độ bảng, chứ không phải nằm trong định nghĩa của một cột duy nhất.
SQLite Các thao tác khóa ngoại: ON DELETE và ON UPDATE
Khóa ngoại cũng có thể kiểm soát những gì xảy ra với các hàng con khi hàng cha mà chúng tham chiếu bị xóa hoặc cập nhật. Các hành động tham chiếu này được thêm vào bằng các mệnh đề ON DELETE và ON UPDATE khi bạn định nghĩa khóa ngoại. SQLite Hỗ trợ năm hành động:
- KHÔNG CÓ HÀNH ĐỘNG — hành động mặc định, sẽ báo lỗi nếu các hàng con vẫn tham chiếu đến hàng cha.
- HẠN CHẾ — Ngăn chặn việc xóa hoặc cập nhật ngay lập tức, trước khi bất kỳ thay đổi nào khác được thực thi.
- Đặt vô giá trị — đặt cột khóa ngoại con thành null.
- THIẾT BỊ DEFAULT — đặt cột khóa ngoại con về giá trị mặc định đã khai báo.
- CASCADE — Áp dụng cùng một thay đổi cho các hàng con, vì vậy việc xóa một hàng cha sẽ xóa luôn các hàng con của nó.
Ví dụ dưới đây tạo lại bảng Sinh viên sao cho việc xóa một khoa sẽ tự động xóa sinh viên thuộc khoa đó, và việc cập nhật ID khoa sẽ cập nhật thông tin sinh viên tương ứng:
CREATE TABLE Students ( StudentId INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, StudentName NVARCHAR(50) NULL, DepartmentId INTEGER NOT NULL, FOREIGN KEY(DepartmentId) REFERENCES Departments(DepartmentId) ON DELETE CASCADE ON UPDATE CASCADE );
Hãy nhớ rằng các thao tác tham chiếu chỉ chạy khi hỗ trợ khóa ngoại được bật, vì vậy hãy chạy lệnh PRAGMA foreign_keys = ON khi bắt đầu mỗi kết nối. Nếu không, SQLite Phân tích các điều khoản ON DELETE và ON UPDATE nhưng không thực thi chúng.


