Giải thích lý do tại sao SQL CHECK constraint khôn hoạt động :(

https://dev.mysql.com/doc/refman/8.0/en/create-table-check-constraints.html

Trước MySQL 8.0.16, CREATE TABLEchỉ cho phép phiên bản giới hạn của CHECKcú pháp ràng buộc bảng sau , được phân tích cú pháp và bỏ qua:

CHECK (expr)

Kể từ MySQL 8.0.16, CREATE TABLE cho phép các tính năng cốt lõi của các CHECKràng buộc bảng và cột , cho tất cả các công cụ lưu trữ. CREATE TABLEcho phép CHECKcú pháp ràng buộc sau , cho cả ràng buộc bảng và ràng buộc cột:

[CONSTRAINT [symbol]] CHECK (expr) [[NOT] ENFORCED]

Tùy chọn symbolchỉ định tên cho ràng buộc. Nếu bị bỏ qua, MySQL sẽ tạo một tên từ tên bảng, chữ _chk_và số thứ tự (1, 2, 3, ...). Tên ràng buộc có độ dài tối đa 64 ký tự. Họ là trường hợp nhạy cảm, nhưng không nhạy cảm.

exprchỉ định điều kiện ràng buộc dưới dạng biểu thức boolean phải ước tính TRUEhoặc UNKNOWN(cho NULLcác giá trị) cho mỗi hàng của bảng. Nếu điều kiện ước tính FALSE, nó sẽ thất bại và vi phạm ràng buộc xảy ra. Tác động của vi phạm tùy thuộc vào tuyên bố được thực thi, như được mô tả sau trong phần này.

Điều khoản thi hành tùy chọn cho biết liệu ràng buộc có được thi hành hay không:

  • Nếu được bỏ qua hoặc chỉ định là ENFORCED, ràng buộc được tạo và thi hành.

  • Nếu được chỉ định là NOT ENFORCED, ràng buộc được tạo nhưng không được thi hành.

Một CHECKràng buộc được chỉ định là ràng buộc bảng hoặc ràng buộc cột:

  • Ràng buộc bảng không xuất hiện trong định nghĩa cột và có thể tham chiếu đến bất kỳ cột hoặc cột nào trong bảng. Tham chiếu chuyển tiếp được phép cho các cột xuất hiện sau trong định nghĩa bảng.

  • Một ràng buộc cột xuất hiện trong một định nghĩa cột và chỉ có thể tham chiếu đến cột đó.

Xem xét định nghĩa bảng này:

CREATE TABLE t1
(
  CHECK (c1 <> c2),
  c1 INT CHECK (c1 > 10),
  c2 INT CONSTRAINT c2_positive CHECK (c2 > 0),
  c3 INT CHECK (c3 < 100),
  CONSTRAINT c1_nonzero CHECK (c1 <> 0),
  CHECK (c1 > c3)
);

Định nghĩa bao gồm các ràng buộc bảng và ràng buộc cột, trong các định dạng được đặt tên và không tên:

  • Ràng buộc đầu tiên là ràng buộc bảng: Nó xuất hiện bên ngoài bất kỳ định nghĩa cột nào, do đó, nó có thể (và không) tham chiếu đến nhiều cột trong bảng. Ràng buộc này chứa các tham chiếu chuyển tiếp đến các cột chưa được xác định. Không có tên ràng buộc nào được chỉ định, vì vậy MySQL tạo ra một tên.

  • Ba ràng buộc tiếp theo là các ràng buộc cột: Mỗi ràng buộc xảy ra trong một định nghĩa cột và do đó chỉ có thể tham chiếu đến cột được xác định. Một trong những ràng buộc được đặt tên rõ ràng. MySQL tạo một tên cho hai cái còn lại.

  • Hai mâu thuẫn cuối cùng là các ràng buộc bảng. Một trong số đó được đặt tên rõ ràng. MySQL tạo một tên cho cái khác.

Như đã đề cập, MySQL tạo một tên cho bất kỳ CHECKràng buộc nào được chỉ định mà không có một ràng buộc nào . Để xem tên được tạo cho định nghĩa bảng trước, sử dụngSHOW CREATE TABLE:

mysql> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `c1` int(11) DEFAULT NULL,
  `c2` int(11) DEFAULT NULL,
  `c3` int(11) DEFAULT NULL,
  CONSTRAINT `c1_nonzero` CHECK ((`c1` <> 0)),
  CONSTRAINT `c2_positive` CHECK ((`c2` > 0)),
  CONSTRAINT `t1_chk_1` CHECK ((`c1` <> `c2`)),
  CONSTRAINT `t1_chk_2` CHECK ((`c1` > 10)),
  CONSTRAINT `t1_chk_3` CHECK ((`c3` < 100)),
  CONSTRAINT `t1_chk_4` CHECK ((`c1` > `c3`))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

Tiêu chuẩn SQL chỉ định rằng tất cả các loại ràng buộc (khóa chính, chỉ mục duy nhất, khóa ngoại, kiểm tra) thuộc về cùng một không gian tên. Trong MySQL, mỗi loại ràng buộc có không gian tên riêng cho mỗi lược đồ (cơ sở dữ liệu). Do đó, CHECKtên ràng buộc phải là duy nhất cho mỗi lược đồ; không có hai bảng trong cùng một lược đồ có thể chia sẻ một CHECKtên ràng buộc. (Ngoại lệ: Một TEMPORARYbảng ẩn một TEMPORARYbảng không cùng tên, vì vậy nó cũng có thể có cùng CHECKtên ràng buộc.)

Bắt đầu các tên ràng buộc được tạo bằng tên bảng giúp đảm bảo tính duy nhất của lược đồ vì tên bảng cũng phải là duy nhất trong lược đồ.

CHECKbiểu thức điều kiện phải tuân thủ các quy tắc sau. Xảy ra lỗi nếu một biểu thức có chứa các cấu trúc không được phép.

  • Các cột được tạo và tạo được cho phép, ngoại trừ các cột có AUTO_INCREMENTthuộc tính và các cột trong các bảng khác.

  • Nghĩa đen, hàm tích hợp xác định và toán tử được phép. Một hàm có tính xác định nếu, được cung cấp cùng một dữ liệu trong các bảng, nhiều lệnh gọi tạo ra cùng một kết quả, độc lập với người dùng được kết nối. Ví dụ về các chức năng mà là không xác định và không định nghĩa này: CONNECTION_ID(), CURRENT_USER(), NOW().

  • Các chức năng được lưu trữ và các chức năng do người dùng xác định không được phép.

  • Thủ tục lưu trữ và các tham số chức năng không được phép.

  • Các biến (biến hệ thống, biến do người dùng xác định và biến cục bộ của chương trình được lưu trữ) không được phép.

  • Truy vấn con không được phép.

Các hành động tham chiếu khóa ngoài ( ON UPDATE, ON DELETE) bị cấm trên các cột được sử dụng trong các CHECKràng buộc. Tương tự, các CHECKràng buộc bị cấm trên các cột được sử dụng trong các hành động tham chiếu khóa ngoài.

CHECKhạn chế được đánh giá cho INSERT, UPDATE, REPLACE, LOAD DATA, và LOAD XMLbáo cáo và một lỗi xảy ra nếu một hạn chế để đánh giá FALSE. Nếu xảy ra lỗi, việc xử lý các thay đổi đã được áp dụng khác nhau đối với các công cụ lưu trữ giao dịch và không giao dịch, và cũng phụ thuộc vào việc chế độ SQL nghiêm ngặt có hiệu lực hay không, như được mô tả trong Chế độ SQL nghiêm ngặt .

CHECKhạn chế được đánh giá cho INSERT IGNORE, UPDATE IGNORE, LOAD DATA ... IGNORE, và LOAD XML ... IGNOREbáo cáo và cảnh báo xảy ra nếu một hạn chế để đánh giá FALSE. Việc chèn hoặc cập nhật cho bất kỳ hàng vi phạm nào bị bỏ qua.

Nếu biểu thức ràng buộc ước tính thành một loại dữ liệu khác với loại cột được khai báo, thì việc ép buộc ngầm định đối với loại khai báo xảy ra theo quy tắc chuyển đổi loại MySQL thông thường. Xem Phần 12.2, Chuyển đổi loại hình trong Đánh giá biểu hiện . Nếu chuyển đổi loại không thành công hoặc dẫn đến mất độ chính xác, sẽ xảy ra lỗi.chú thích

Đánh giá biểu thức ràng buộc sử dụng chế độ SQL có hiệu lực tại thời điểm đánh giá. Nếu bất kỳ thành phần nào của biểu thức phụ thuộc vào chế độ SQL, các kết quả khác nhau có thể xảy ra cho các mục đích sử dụng khác nhau của bảng trừ khi chế độ SQL giống nhau trong tất cả các lần sử dụng.

Last updated