Thêm khóa ngoài mysql

Các kiểu dữ liệu là một cách để giới hạn loại dữ liệu có thể được lưu trữ trong một bảng. Tuy nhiên, đối với nhiều ứng dụng, ràng buộc mà chúng cung cấp là quá thô. Ví dụ: cột chứa giá sản phẩm có thể chỉ chấp nhận giá trị dương. Nhưng không có kiểu dữ liệu chuẩn chỉ chấp nhận số dương. Một vấn đề khác là bạn có thể muốn hạn chế dữ liệu cột đối với các cột hoặc hàng khác. Ví dụ: trong bảng chứa thông tin sản phẩm, chỉ nên có một hàng cho mỗi mã số sản phẩm

Cuối cùng, SQL cho phép bạn xác định các ràng buộc trên các cột và bảng. Các ràng buộc cung cấp cho bạn nhiều quyền kiểm soát dữ liệu trong bảng của bạn như bạn muốn. Nếu người dùng cố gắng lưu trữ dữ liệu trong một cột vi phạm ràng buộc, sẽ xảy ra lỗi. Điều này áp dụng ngay cả khi giá trị đến từ định nghĩa giá trị mặc định

Ràng buộc kiểm tra là loại ràng buộc chung nhất. Nó cho phép bạn chỉ định rằng giá trị trong một cột nhất định phải đáp ứng biểu thức Boolean [giá trị thực]. Chẳng hạn, để yêu cầu giá sản phẩm dương, bạn có thể sử dụng

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0]
];

Như bạn thấy, định nghĩa ràng buộc xuất hiện sau kiểu dữ liệu, giống như định nghĩa giá trị mặc định. Các giá trị và ràng buộc mặc định có thể được liệt kê theo bất kỳ thứ tự nào. Ràng buộc kiểm tra bao gồm từ khóa

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7 theo sau là một biểu thức trong ngoặc đơn. Biểu thức ràng buộc kiểm tra phải liên quan đến cột bị ràng buộc, nếu không, ràng buộc sẽ không có ý nghĩa gì nhiều

Bạn cũng có thể đặt tên riêng cho ràng buộc. Điều này làm rõ các thông báo lỗi và cho phép bạn tham khảo ràng buộc khi bạn cần thay đổi nó. Cú pháp là

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];

Vì vậy, để chỉ định một ràng buộc được đặt tên, hãy sử dụng từ khóa

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
8 theo sau là mã định danh, sau đó là định nghĩa ràng buộc. [Nếu bạn không chỉ định tên ràng buộc theo cách này, hệ thống sẽ chọn tên cho bạn. ]

Một ràng buộc kiểm tra cũng có thể tham chiếu đến một số cột. Giả sử bạn lưu trữ giá thông thường và giá chiết khấu và bạn muốn đảm bảo rằng giá chiết khấu thấp hơn giá thông thường

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];

Hai ràng buộc đầu tiên sẽ trông quen thuộc. Cái thứ ba sử dụng một cú pháp mới. Nó không được gắn vào một cột cụ thể, thay vào đó, nó xuất hiện dưới dạng một mục riêng biệt trong danh sách cột được phân tách bằng dấu phẩy. Các định nghĩa cột và các định nghĩa ràng buộc này có thể được liệt kê theo thứ tự hỗn hợp

Chúng ta nói rằng hai ràng buộc đầu tiên là ràng buộc cột, trong khi ràng buộc thứ ba là ràng buộc bảng vì nó được viết riêng biệt với bất kỳ định nghĩa một cột nào. Ràng buộc cột cũng có thể được viết dưới dạng ràng buộc bảng, trong khi điều ngược lại là không nhất thiết có thể, vì ràng buộc cột được cho là chỉ tham chiếu đến cột mà nó được gắn vào. [PostgreSQL không thực thi quy tắc đó, nhưng bạn nên tuân theo quy tắc đó nếu bạn muốn các định nghĩa bảng của mình hoạt động với các hệ thống cơ sở dữ liệu khác. ] Ví dụ trên cũng có thể được viết là

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];

hoặc thậm chí

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];

Đó là một vấn đề của hương vị

Có thể gán tên cho các ràng buộc bảng giống như cách gán các ràng buộc cột

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];

Cần lưu ý rằng một ràng buộc kiểm tra được thỏa mãn nếu biểu thức kiểm tra ước tính giá trị đúng hoặc giá trị null. Vì hầu hết các biểu thức sẽ đánh giá giá trị null nếu bất kỳ toán hạng nào là null, nên chúng sẽ không ngăn các giá trị null trong các cột bị ràng buộc. Để đảm bảo rằng một cột không chứa giá trị null, có thể sử dụng ràng buộc không null được mô tả trong phần tiếp theo

Ghi chú

PostgreSQL không hỗ trợ các ràng buộc

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7 tham chiếu dữ liệu bảng khác với hàng mới hoặc hàng cập nhật đang được kiểm tra. Mặc dù ràng buộc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7 vi phạm quy tắc này có thể hoạt động trong các thử nghiệm đơn giản, nhưng nó không thể đảm bảo rằng cơ sở dữ liệu sẽ không đạt đến trạng thái trong đó điều kiện ràng buộc là sai [do các thay đổi tiếp theo của [các] hàng khác có liên quan]. Điều này sẽ gây ra kết xuất cơ sở dữ liệu và khôi phục không thành công. Quá trình khôi phục có thể không thành công ngay cả khi trạng thái cơ sở dữ liệu hoàn chỉnh phù hợp với ràng buộc, do các hàng không được tải theo thứ tự sẽ thỏa mãn ràng buộc. Nếu có thể, hãy sử dụng các ràng buộc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
1,
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
2 hoặc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
3 để thể hiện các ràng buộc giữa các hàng và giữa các bảng

Ghi chú

PostgreSQL giả định rằng các điều kiện của ràng buộc

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7 là không thay đổi, nghĩa là chúng sẽ luôn cho cùng một kết quả cho cùng một hàng đầu vào. Giả định này là điều biện minh cho việc kiểm tra các ràng buộc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7 chỉ khi các hàng được chèn hoặc cập nhật chứ không phải vào các thời điểm khác. [Cảnh báo ở trên về việc không tham chiếu dữ liệu bảng khác thực sự là trường hợp đặc biệt của hạn chế này. ]

Một ví dụ về cách phổ biến để phá vỡ giả định này là tham chiếu hàm do người dùng xác định trong biểu thức

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7, sau đó thay đổi hành vi của hàm đó. PostgreSQL không cho phép điều đó, nhưng nó sẽ không nhận thấy nếu có hàng trong bảng hiện vi phạm ràng buộc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
7. Điều đó sẽ gây ra kết xuất cơ sở dữ liệu tiếp theo và khôi phục không thành công. Cách được khuyến nghị để xử lý thay đổi như vậy là loại bỏ ràng buộc [sử dụng
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
8], điều chỉnh định nghĩa hàm và thêm lại ràng buộc, từ đó kiểm tra lại ràng buộc đối với tất cả các hàng của bảng

5. 4. 2. Ràng buộc không null

Ràng buộc không null chỉ đơn giản xác định rằng một cột không được nhận giá trị null. Một ví dụ cú pháp

CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric
];

Ràng buộc không null luôn được viết dưới dạng ràng buộc cột. Một ràng buộc không null về mặt chức năng tương đương với việc tạo một ràng buộc kiểm tra

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
9 IS NOT NULL], nhưng trong PostgreSQL, việc tạo một ràng buộc không null rõ ràng sẽ hiệu quả hơn. Hạn chế là bạn không thể đặt tên rõ ràng cho các ràng buộc không null được tạo theo cách này

Tất nhiên, một cột có thể có nhiều hơn một ràng buộc. Chỉ cần viết các ràng buộc lần lượt

CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric NOT NULL CHECK [price > 0]
];

Thứ tự không quan trọng. Nó không nhất thiết xác định thứ tự các ràng buộc được kiểm tra

Ràng buộc

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
0 có nghịch đảo. ràng buộc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
1. Điều này không có nghĩa là cột phải rỗng, điều này chắc chắn sẽ vô ích. Thay vào đó, điều này chỉ đơn giản là chọn hành vi mặc định mà cột có thể là null. Ràng buộc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
1 không có trong tiêu chuẩn SQL và không được sử dụng trong các ứng dụng di động. [Nó chỉ được thêm vào PostgreSQL để tương thích với một số hệ thống cơ sở dữ liệu khác. ] Tuy nhiên, một số người dùng thích nó vì nó giúp dễ dàng chuyển đổi ràng buộc trong tệp tập lệnh. Ví dụ, bạn có thể bắt đầu với

CREATE TABLE products [
    product_no integer NULL,
    name text NULL,
    price numeric NULL
];

và sau đó chèn từ khóa

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
3 vào nơi mong muốn

Mẹo

Trong hầu hết các thiết kế cơ sở dữ liệu, phần lớn các cột phải được đánh dấu là không rỗng

5. 4. 3. Ràng buộc duy nhất

Các ràng buộc duy nhất đảm bảo rằng dữ liệu chứa trong một cột hoặc một nhóm cột là duy nhất trong số tất cả các hàng trong bảng. Cú pháp là

CREATE TABLE products [
    product_no integer UNIQUE,
    name text,
    price numeric
];

khi được viết dưới dạng ràng buộc cột và

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
0

khi được viết dưới dạng ràng buộc bảng

Để xác định một ràng buộc duy nhất cho một nhóm cột, hãy viết nó dưới dạng ràng buộc bảng với các tên cột được phân tách bằng dấu phẩy

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
1

Điều này xác định rằng sự kết hợp của các giá trị trong các cột được chỉ định là duy nhất trên toàn bộ bảng, mặc dù bất kỳ cột nào trong số các cột không nhất thiết phải [và thường không phải là] duy nhất

Bạn có thể gán tên riêng của mình cho một ràng buộc duy nhất, theo cách thông thường

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
2

Việc thêm một ràng buộc duy nhất sẽ tự động tạo một chỉ mục cây B duy nhất trên cột hoặc nhóm cột được liệt kê trong ràng buộc. Hạn chế về tính duy nhất chỉ bao gồm một số hàng không thể được viết dưới dạng ràng buộc duy nhất, nhưng có thể thực thi hạn chế đó bằng cách tạo chỉ mục bộ phận duy nhất

Nói chung, một ràng buộc duy nhất bị vi phạm nếu có nhiều hơn một hàng trong bảng có giá trị của tất cả các cột có trong ràng buộc bằng nhau. Theo mặc định, hai giá trị null không được coi là bằng nhau trong so sánh này. Điều đó có nghĩa là ngay cả khi có một ràng buộc duy nhất, vẫn có thể lưu trữ các hàng trùng lặp có chứa giá trị null trong ít nhất một trong các cột bị ràng buộc. Hành vi này có thể được thay đổi bằng cách thêm mệnh đề

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
4, như

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
3

hoặc là

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
4

Hành vi mặc định có thể được chỉ định rõ ràng bằng cách sử dụng

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
5. Xử lý null mặc định trong các ràng buộc duy nhất được xác định theo triển khai theo tiêu chuẩn SQL và các triển khai khác có hành vi khác. Vì vậy, hãy cẩn thận khi phát triển các ứng dụng dành cho thiết bị di động

Ràng buộc khóa chính chỉ ra rằng một cột hoặc một nhóm cột có thể được sử dụng làm mã định danh duy nhất cho các hàng trong bảng. Điều này yêu cầu các giá trị phải là duy nhất và không rỗng. Vì vậy, hai định nghĩa bảng sau đây chấp nhận cùng một dữ liệu

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
5_______2_______6

Các khóa chính có thể kéo dài nhiều hơn một cột;

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
7

Việc thêm khóa chính sẽ tự động tạo chỉ mục cây B duy nhất trên cột hoặc nhóm cột được liệt kê trong khóa chính và sẽ buộc [các] cột được đánh dấu là

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
0

Một bảng có thể có nhiều nhất một khóa chính. [Có thể có bất kỳ số ràng buộc duy nhất và không null nào, về mặt chức năng gần như giống nhau, nhưng chỉ có một ràng buộc có thể được xác định là khóa chính. ] Lý thuyết cơ sở dữ liệu quan hệ quy định rằng mọi bảng phải có khóa chính. Quy tắc này không được thực thi bởi PostgreSQL, nhưng tốt nhất bạn nên tuân theo quy tắc này

Khóa chính hữu ích cho cả mục đích tài liệu và ứng dụng khách. Ví dụ: ứng dụng GUI cho phép sửa đổi giá trị hàng có thể cần biết khóa chính của bảng để có thể xác định duy nhất các hàng. Ngoài ra còn có nhiều cách khác nhau mà hệ thống cơ sở dữ liệu sử dụng khóa chính nếu một khóa đã được khai báo;

Ràng buộc khóa ngoại xác định rằng các giá trị trong một cột [hoặc một nhóm cột] phải khớp với các giá trị xuất hiện trong một số hàng của bảng khác. Chúng tôi nói điều này duy trì tính toàn vẹn tham chiếu giữa hai bảng liên quan

Giả sử bạn có bảng sản phẩm mà chúng tôi đã sử dụng nhiều lần rồi

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
8

Giả sử bạn có một bảng lưu trữ đơn đặt hàng của những sản phẩm đó. Chúng tôi muốn đảm bảo rằng bảng đơn hàng chỉ chứa đơn hàng của sản phẩm thực sự tồn tại. Vì vậy, chúng tôi xác định một ràng buộc khóa ngoại trong bảng đơn hàng tham chiếu đến bảng sản phẩm

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CONSTRAINT positive_price CHECK [price > 0]
];
9

Bây giờ không thể tạo đơn đặt hàng với các mục nhập không phải NULL

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
7 không xuất hiện trong bảng sản phẩm

Ta nói rằng trong tình huống này, bảng đơn hàng là bảng tham chiếu và bảng sản phẩm là bảng được tham chiếu. Tương tự, có các cột tham chiếu và tham chiếu

Bạn cũng có thể rút ngắn lệnh trên thành

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
0

bởi vì trong trường hợp không có danh sách cột, khóa chính của bảng được tham chiếu được sử dụng làm [các] cột được tham chiếu

Bạn có thể gán tên riêng của mình cho một ràng buộc khóa ngoại, theo cách thông thường

Khóa ngoại cũng có thể hạn chế và tham chiếu một nhóm cột. Như thường lệ, sau đó nó cần được viết dưới dạng ràng buộc bảng. Đây là một ví dụ cú pháp giả định

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
1

Tất nhiên, số lượng và loại cột bị ràng buộc phải khớp với số lượng và loại cột được tham chiếu

Đôi khi nó hữu ích cho “bảng khác” của ràng buộc khóa ngoại là cùng một bảng; . Ví dụ: nếu bạn muốn các hàng của bảng biểu thị các nút của cấu trúc cây, bạn có thể viết

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
2

Nút cấp cao nhất sẽ có NULL

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
8, trong khi các mục nhập không phải NULL
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
8 sẽ bị hạn chế tham chiếu các hàng hợp lệ của bảng

Một bảng có thể có nhiều ràng buộc khóa ngoại. Điều này được sử dụng để thực hiện các mối quan hệ nhiều-nhiều giữa các bảng. Giả sử bạn có các bảng về sản phẩm và đơn đặt hàng, nhưng bây giờ bạn muốn cho phép một đơn hàng có thể chứa nhiều sản phẩm [cấu trúc ở trên không cho phép]. Bạn có thể sử dụng cấu trúc bảng này

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
3

Lưu ý rằng khóa chính trùng với khóa ngoại trong bảng cuối cùng

Chúng tôi biết rằng khóa ngoại không cho phép tạo đơn đặt hàng không liên quan đến bất kỳ sản phẩm nào. Nhưng điều gì sẽ xảy ra nếu một sản phẩm bị xóa sau khi tạo đơn đặt hàng tham chiếu đến sản phẩm đó? . Theo trực giác, chúng tôi có một vài lựa chọn

  • Không cho phép xóa một sản phẩm được tham chiếu

  • Xóa các đơn đặt hàng là tốt

  • Thứ gì khác?

Để minh họa điều này, hãy triển khai chính sách sau trên ví dụ về mối quan hệ nhiều-nhiều ở trên. khi ai đó muốn xóa một sản phẩm vẫn được tham chiếu bởi một đơn đặt hàng [thông qua

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
0], chúng tôi không cho phép điều đó. Nếu ai đó xóa đơn đặt hàng, các mặt hàng trong đơn đặt hàng cũng bị xóa

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
4

Xóa hạn chế và xếp tầng là hai tùy chọn phổ biến nhất.

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
1 ngăn việc xóa một hàng được tham chiếu.
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
2 có nghĩa là nếu bất kỳ hàng tham chiếu nào vẫn tồn tại khi kiểm tra ràng buộc, thì sẽ xảy ra lỗi; . [Sự khác biệt cơ bản giữa hai lựa chọn này là
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
2 cho phép séc được hoãn lại cho đến sau này trong giao dịch, trong khi
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
1 thì không. ]
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
5 chỉ định rằng khi một hàng được tham chiếu bị xóa, [các] hàng tham chiếu nó cũng sẽ tự động bị xóa. Có hai lựa chọn khác.
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
6 và
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
7. Những điều này làm cho [các] cột tham chiếu trong [các] hàng tham chiếu được đặt thành null hoặc giá trị mặc định của chúng, tương ứng, khi hàng được tham chiếu bị xóa. Lưu ý rằng những điều này không miễn cho bạn quan sát bất kỳ ràng buộc nào. Ví dụ: nếu một hành động chỉ định
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
7 nhưng giá trị mặc định không thỏa mãn ràng buộc khóa ngoại, thì thao tác đó sẽ thất bại

Lựa chọn thích hợp của hành động

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
9 phụ thuộc vào loại đối tượng mà các bảng liên quan đại diện. Khi bảng tham chiếu đại diện cho một cái gì đó là một thành phần của những gì được đại diện bởi bảng được tham chiếu và không thể tồn tại độc lập, thì
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
5 có thể phù hợp. Nếu hai bảng đại diện cho các đối tượng độc lập, thì
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
1 hoặc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
2 sẽ phù hợp hơn; . Trong ví dụ trên, các mục đơn hàng là một phần của đơn hàng và sẽ thuận tiện nếu chúng tự động bị xóa nếu đơn hàng bị xóa. Tuy nhiên, sản phẩm và đơn đặt hàng là những thứ khác nhau và do đó, việc xóa một sản phẩm tự động dẫn đến việc xóa một số mặt hàng trong đơn đặt hàng có thể được coi là có vấn đề. Các hành động
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
6 hoặc
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
7 có thể phù hợp nếu mối quan hệ khóa ngoài đại diện cho thông tin tùy chọn. Ví dụ: nếu bảng sản phẩm chứa tham chiếu đến trình quản lý sản phẩm và mục nhập trình quản lý sản phẩm bị xóa, thì việc đặt trình quản lý sản phẩm của sản phẩm thành null hoặc mặc định có thể hữu ích

Các hành động

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
6 và
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
7 có thể lấy danh sách cột để chỉ định cột nào sẽ đặt. Thông thường, tất cả các cột của ràng buộc khóa ngoại được đặt; . Xem xét ví dụ sau

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
5

Nếu không có thông số kỹ thuật của cột, khóa ngoại cũng sẽ đặt cột

CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric
];
7 thành null, nhưng cột đó vẫn được yêu cầu như một phần của khóa chính

Tương tự như

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
9 cũng có ____18_______9 được gọi khi một cột được tham chiếu bị thay đổi [cập nhật]. Các hành động có thể thực hiện giống nhau, ngoại trừ việc không thể chỉ định danh sách cột cho
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
6 và
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
7. Trong trường hợp này,
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric,
    CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0],
    CONSTRAINT valid_discount CHECK [price > discounted_price]
];
5 có nghĩa là các giá trị cập nhật của [các] cột được tham chiếu phải được sao chép vào [các] hàng tham chiếu

Thông thường, một hàng tham chiếu không cần thỏa mãn ràng buộc khóa ngoại nếu bất kỳ cột tham chiếu nào của nó là null. Nếu

CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric NOT NULL CHECK [price > 0]
];
3 được thêm vào khai báo khóa ngoại, một hàng tham chiếu chỉ thoát khỏi ràng buộc nếu tất cả các cột tham chiếu của nó là null [do đó, sự kết hợp giữa các giá trị null và không null được đảm bảo sẽ không vượt qua ràng buộc
CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric NOT NULL CHECK [price > 0]
];
3]. Nếu bạn không muốn các hàng tham chiếu có thể tránh thỏa mãn ràng buộc khóa ngoại, hãy khai báo [các] cột tham chiếu là
CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric,
    CHECK [discounted_price > 0 AND price > discounted_price]
];
0

Khóa ngoại phải tham chiếu các cột là khóa chính hoặc tạo thành một ràng buộc duy nhất. Điều này có nghĩa là các cột được tham chiếu luôn có một chỉ mục [chỉ mục bên dưới khóa chính hoặc ràng buộc duy nhất]; . Vì một

CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric NOT NULL CHECK [price > 0]
];
6 của một hàng từ bảng được tham chiếu hoặc một
CREATE TABLE products [
    product_no integer NOT NULL,
    name text NOT NULL,
    price numeric NOT NULL CHECK [price > 0]
];
7 của một cột được tham chiếu sẽ yêu cầu quét bảng tham chiếu để tìm các hàng khớp với giá trị cũ, nên bạn cũng nên lập chỉ mục cho các cột tham chiếu. Vì điều này không phải lúc nào cũng cần thiết và có nhiều lựa chọn về cách lập chỉ mục, nên việc khai báo ràng buộc khóa ngoại không tự động tạo chỉ mục trên các cột tham chiếu

Thông tin thêm về cách cập nhật và xóa dữ liệu có trong Chương 6. Ngoài ra, hãy xem mô tả về cú pháp ràng buộc khóa ngoại trong tài liệu tham khảo về CREATE TABLE

5. 4. 6. Ràng buộc loại trừ

Các ràng buộc loại trừ đảm bảo rằng nếu bất kỳ hai hàng nào được so sánh trên các cột hoặc biểu thức đã chỉ định bằng cách sử dụng các toán tử đã chỉ định, thì ít nhất một trong các so sánh toán tử này sẽ trả về false hoặc null. Cú pháp là

CREATE TABLE products [
    product_no integer,
    name text,
    price numeric CHECK [price > 0],
    discounted_price numeric CHECK [discounted_price > 0],
    CHECK [price > discounted_price]
];
6

Xem thêm để biết chi tiết

Việc thêm một ràng buộc loại trừ sẽ tự động tạo một chỉ mục của loại được chỉ định trong khai báo ràng buộc

Chủ Đề