Trong SQL Server, một ràng buộc khóa ngoại (và một CHECK
ràng buộc) có thể được tin cậy hoặc không đáng tin cậy.
Khi một ràng buộc được tin cậy, điều này có nghĩa là ràng buộc đó đã được hệ thống xác nhận. Khi không đáng tin cậy, ràng buộc có không đã được hệ thống xác minh.
Về cơ bản, khi bạn có một ràng buộc không đáng tin cậy, bạn cũng có thể có dữ liệu không hợp lệ trong cơ sở dữ liệu của mình. Bởi điều này, tôi có nghĩa là bạn có thể có dữ liệu vi phạm ràng buộc.
Điều này có nghĩa là bạn không còn duy trì tính toàn vẹn tham chiếu trong các mối quan hệ của mình, đây là cách thường không tốt khi quản lý cơ sở dữ liệu quan hệ trong quá trình sản xuất.
Trong bài viết này, tôi sẽ kiểm tra các ràng buộc hiện có của mình để biết “độ tin cậy” của chúng, sau đó tôi sẽ cập nhật chúng để trở nên đáng tin cậy một lần nữa.
Ví dụ 1 - Xem lại các Ràng buộc Hiện tại
Bạn có thể tìm hiểu xem một ràng buộc có đáng tin cậy hay không bằng cách truy vấn sys.foreign_keys
chế độ xem hệ thống.
Như thế này:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Kết quả:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
OK, vì vậy điều này cho tôi biết tôi có hai ràng buộc khóa ngoại và cả hai đều không đáng tin cậy.
Một trong những ràng buộc bị vô hiệu hóa, do đó, có nghĩa là nó không đáng tin cậy (dữ liệu xấu có thể xâm nhập vào cơ sở dữ liệu bất cứ khi nào ràng buộc bị vô hiệu hóa).
Nhưng ràng buộc khác đã được kích hoạt, vì vậy nó thực sự không nên đáng tin cậy. Không đáng tin cậy có nghĩa là có thể có dữ liệu không hợp lệ trong cơ sở dữ liệu. Điều đó không có nghĩa là có dữ liệu không hợp lệ, chỉ ở đó có thể là.
Về cơ bản, bằng cách được bật, nó sẽ kiểm tra dữ liệu trong tương lai, nhưng nó không thể đảm bảo cho dữ liệu hiện có. Nếu một ràng buộc được tin cậy, thì bạn có thể chắc chắn rằng tất cả dữ liệu hiện có đều hợp lệ.
Chỉ trả lại những ràng buộc không đáng tin cậy
Bạn có thể thấy thích sử dụng WHERE
mệnh đề chỉ trả về các ràng buộc không đáng tin cậy. Như thế này:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys WHERE is_not_trusted = 1;
Kết quả:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 1 | +-------------------+---------------+------------------+
Vì vậy, trong trường hợp này, kết quả là như nhau (vì tất cả các ràng buộc hiện tại đều không đáng tin cậy).
Ví dụ 2 - Khôi phục độ tin cậy
Để khôi phục độ tin cậy cho ràng buộc đã bật của bạn, chỉ cần bật lại nó trong khi sử dụng WITH CHECK
tùy chọn.
Như thế này:
ALTER TABLE Albums WITH CHECK CHECK CONSTRAINT FK_Albums_Genres;
Bây giờ khi chúng tôi truy vấn sys.foreign_keys
chúng tôi nhận được một kết quả khác:
SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Kết quả:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 1 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Chúng ta có thể thấy rằng ràng buộc hiện được tin cậy vì is_not_trusted
cờ được đặt thành 0
.
Ví dụ 3 - Ràng buộc trở nên không đáng tin cậy như thế nào?
Khi bạn vô hiệu hóa ràng buộc khóa ngoại, nó sẽ tự động trở nên không đáng tin cậy. Khi bạn kích hoạt lại cùng một ràng buộc, bạn có cơ hội khôi phục độ tin cậy của nó. Nếu bạn không làm điều này, nó sẽ vẫn không đáng tin cậy.
Khi bạn bật ràng buộc khóa ngoại, bạn có tùy chọn chỉ định WITH CHECK
hoặc WITH NOCHECK
. Nếu bạn chỉ định muộn hơn, ràng buộc của bạn sẽ vẫn không đáng tin cậy khi nó đã được kích hoạt.
Điều quan trọng cần lưu ý là WITH NOCHECK
là tùy chọn mặc định, vì vậy nếu bạn không chỉ định rõ ràng rằng nó phải đáng tin cậy, thì ràng buộc sẽ được bật là không đáng tin cậy.
Tuy nhiên, điều ngược lại khi bạn tạo ràng buộc khóa ngoài. Khi bạn lần đầu tiên tạo ràng buộc, tùy chọn mặc định là WITH CHECK
. Vì vậy, nếu bạn bỏ qua cài đặt này, cài đặt này sẽ được tin cậy theo mặc định (trừ khi bạn có dữ liệu không hợp lệ, trong trường hợp đó, cài đặt này sẽ không được bật). Tuy nhiên, bạn có thể ghi đè cài đặt này bằng cách chỉ định rõ ràng WITH NOCHECK
khi bạn tạo ràng buộc.
Để chứng minh cách các ràng buộc đã bật của bạn có thể dễ dàng vẫn không đáng tin cậy, tôi sẽ bật lại khóa khác (khóa bị vô hiệu hóa), nhưng tôi sẽ sử dụng cài đặt mặc định:
ALTER TABLE Albums CHECK CONSTRAINT FK_Albums_Artists; SELECT name AS 'Constraint', is_disabled, is_not_trusted FROM sys.foreign_keys;
Kết quả:
+-------------------+---------------+------------------+ | Constraint | is_disabled | is_not_trusted | |-------------------+---------------+------------------| | FK_Albums_Artists | 0 | 1 | | FK_Albums_Genres | 0 | 0 | +-------------------+---------------+------------------+
Vì vậy, do lười biếng (hoặc đãng trí) và không chỉ định rõ ràng WITH CHECK
, Tôi đã quản lý thành công để bật một hạn chế trong khi vẫn giữ nguyên trạng thái “không đáng tin cậy” của nó.
Chìa khóa rút ra từ điều này là:nếu bạn muốn các ràng buộc được bật lại của mình được tin cậy, bạn phải luôn bật chúng bằng cách sử dụng WITH CHECK
.