Bây giờ PostgreSQL 12 đã ra mắt, chúng tôi coi các khóa ngoại hoàn toàn tương thích với các bảng được phân vùng. Bạn có thể có một bảng được phân vùng ở hai bên của ràng buộc khóa ngoại và mọi thứ sẽ hoạt động bình thường.
Tại sao tôi chỉ ra điều này? Hai lý do:thứ nhất, khi các bảng được phân vùng lần đầu tiên được giới thiệu trong PostgreSQL 10, chúng hoàn toàn không hỗ trợ khóa ngoại; bạn không thể tạo FK trên các bảng được phân vùng, cũng như không thể tạo FK tham chiếu đến một bảng được phân vùng. Thứ hai, vì tính năng kế thừa bảng (những ngày đầu) cũng không thực sự hỗ trợ khóa ngoại. Tất cả điều này có nghĩa là lần đầu tiên PostgreSQL có thể duy trì khối lượng lớn dữ liệu trong khi duy trì tính toàn vẹn tham chiếu. Bây giờ tính năng này đã hoàn tất, một số trường hợp sử dụng mới được mở cho PostgreSQL mà trước đây chưa có.
Đây là một ví dụ khá đơn giản.
CREATE TABLE items ( item_id integer PRIMARY KEY, description text NOT NULL ) PARTITION BY hash (item_id); CREATE TABLE items_0 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 0); CREATE TABLE items_1 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 1); CREATE TABLE items_2 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 2); CREATE TABLE warehouses (warehouse_id integer primary key, location text not null); CREATE TABLE stock ( item_id integer not null REFERENCES items, warehouse_id integer not null REFERENCES warehouses, amount int not null ) partition by hash (warehouse_id); CREATE TABLE stock_0 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 0); CREATE TABLE stock_1 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 1); CREATE TABLE stock_2 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 2); CREATE TABLE stock_3 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 3); CREATE TABLE stock_4 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 4);
Bạn có thể thấy có hai khóa ngoại ở đây. Một trỏ đến một bảng kho thông thường (không được phân vùng) , các mục khác trỏ đến các mục trong bảng được phân vùng . Bạn có nhận thấy rằng mỗi khóa ngoại chỉ được khai báo một lần không?
Có hai thao tác cơ bản mà bạn muốn khóa ngoại cung cấp. Đầu tiên, nếu bạn chèn một hàng trong stock (sự tham khảo bảng) không có hàng tương ứng trong mục hoặc nhà kho ( được tham chiếu bảng), một lỗi phải được nêu ra. Thứ hai, nếu bạn xóa một hàng trong một trong hai bảng được tham chiếu và có các hàng phù hợp trong stock , thao tác đó cũng phải bị từ chối.
Cả hai đều được xác minh dễ dàng:
INSERT INTO stock values (1, 1, 10); ERROR: insert or update on table "stock_0" violates foreign key constraint "stock_item_id_fkey" DETAIL: Key (item_id)=(1) is not present in table "items".
Tốt. Sau đó, bạn có thể chèn các hàng phù hợp trong cả bảng được tham chiếu và hàng tham chiếu. Sau đó, việc xóa một trong hai bảng được tham chiếu sẽ không thành công, như mong đợi.
INSERT INTO items VALUES (1, 'item 1'); INSERT INTO warehouses VALUES (1, 'The moon'); INSERT INTO stock VALUES (1, 1, 10); DELETE FROM warehouses; ERROR: update or delete on table "warehouses" violates foreign key constraint "stock_warehouse_id_fkey" on table "stock" DETAIL: Key (warehouse_id)=(1) is still referenced from table "stock". DELETE FROM items; ERROR: update or delete on table "items_2" violates foreign key constraint "stock_item_id_fkey3" on table "stock" DETAIL: Key (item_id)=(1) is still referenced from table "stock".
(Tất nhiên, một CẬP NHẬT hoạt động dành cho hoạt động trước đây giống như một INSERT và đối với thao tác thứ hai giống như DELETE - nghĩa là phải kiểm tra cả tuple gốc và tuple đã sửa đổi, nếu UPDATE sửa đổi các cột liên quan đến khóa ngoại.)
Nếu những ví dụ này có vẻ khập khiễng với người dùng có kinh nghiệm, đó là vì những điều này hoạt động giống hệt nhau đối với các bảng thông thường (không phân vùng) từ thời xa xưa.
Trong cách sử dụng thực tế, bạn sẽ cần các chỉ mục trong các cột tham chiếu trong stock bảng, nếu bạn đã từng sửa đổi các bảng được tham chiếu. Điều này là do máy chủ cần xác định vị trí các hàng tham chiếu đó để biết lỗi hoặc tương tự. Bạn có thể làm điều đó với bảng tham chiếu được phân vùng đủ dễ dàng:
CREATE INDEX ON stock (item_id); CREATE INDEX ON stock (warehouse_id);
Trong bài đăng này, tôi đã trình bày những điều cơ bản về khóa ngoại và cách chúng có thể được sử dụng trên các bảng được phân vùng giống như chúng có thể làm trên các bảng thông thường. Trong một bài đăng tiếp theo, tôi sẽ đề cập đến một số tính năng bổ sung của những tính năng đó. Hãy cho tôi biết trong một bình luận nếu bạn thích cải tiến PostgreSQL 12 này!