Mảng PostgreSQL của các phần tử mà mỗi phần tử là một khóa ngoại


83

Tôi đang cố gắng tạo DB cho ứng dụng của mình và một điều tôi muốn tìm ra cách tốt nhất để làm là tạo mối quan hệ một-nhiều giữa UsersItemscác bảng.

Tôi biết tôi có thể tạo một bảng thứ ba ReviewedItemsvà có các cột là một Userid và một Itemid, nhưng tôi muốn biết liệu có thể tạo một cột trong đó hay không Users, giả sửreviewedItems , đó là một mảng số nguyên chứa các phím nước ngoài Itemsmà các Userđã xem xét.

Nếu PostgreSQL có thể làm được điều này, vui lòng cho tôi biết! Nếu không, tôi sẽ đi xuống tuyến bàn thứ ba.


3
Đã có các bản vá để thêm tính năng này vào Postgres, xem blog.2ndquadrant.com/… (2012) và postgresql.org/message-id/… (2017). Chúng vẫn chưa được chấp nhận, nhưng hy vọng một ngày nào đó.
Simon Kissane

Câu trả lời:


68

Không, điều này là không thể.

PostgreSQL là một quan hệ DBMS , hoạt động hiệu quả nhất trên các mô hình dữ liệu được chuẩn hóa đúng cách. Mảng - theo định nghĩa, chúng là các tập hợp có thứ tự - không phải là cấu trúc dữ liệu quan hệ và tiêu chuẩn SQL do đó không hỗ trợ xác định khóa ngoại trên các phần tử mảng và PostgreSQL cũng vậy.

Tuy nhiên, bạn có thể xây dựng một cơ sở dữ liệu hoàn hảo với các phần tử mảng liên kết với các khóa chính trong các bảng khác. Tuy nhiên, các phần tử mảng đó không thể được khai báo là khóa ngoại và do đó DBMS sẽ không duy trì tính toàn vẹn tham chiếu.


3
Bạn có thể xác định một trình kích hoạt ràng buộc sẽ kiểm tra điều đó. Nhưng tôi không chắc liệu nó có hoạt động đáng tin cậy trong mọi trường hợp hay không.
a_horse_with_no_name

@a_horse_with_no_name: bạn có thể cho ví dụ về reliably in all caseskhông? Ý bạn là đôi khi kích hoạt có thể bị lỗi? Cảm ơn.
Luan Huynh

1
@LuanHuynh: Tôi không nhớ lại chi tiết (kỹ thuật), nhưng lần cuối cùng điều này được thảo luận trên danh sách gửi thư, ai đó đã đề cập rằng một trình kích hoạt ràng buộc tương ứng có thể không bắt được tất cả các trường hợp - nhưng điều đó có thể không còn đúng nữa
a_horse_with_no_name

Cảm ơn, tôi đoán tôi sẽ chỉ làm cho một bảng mối quan hệ đối với họ
Zach

1
@a_horse_with_no_name, bạn có thể đăng câu trả lời với ví dụ về ràng buộc như vậy không?
OrangeDog

65

Có thể sớm làm được điều này: https://commitfest.postgresql.org/17/1252/ - Mark Rofail đã thực hiện một số công việc xuất sắc trên bản vá này!

Bản vá sẽ (sau khi hoàn thành) cho phép

CREATE TABLE PKTABLEFORARRAY (
    ptest1 float8 PRIMARY KEY,
    ptest2 text
);
CREATE TABLE FKTABLEFORARRAY (
    ftest1 int[],
    FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY,
    ftest2 int
);

Tuy nhiên, tác giả hiện đang cần trợ giúp để căn bản lại bản vá (ngoài khả năng của mình) nên những ai đang đọc bài này mà biết nội bộ của Postgres hãy giúp đỡ nếu có thể.


8
thực sự rất HOT ...CREATE TABLE FKTABLEFORARRAY ( ftest1 int[], FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY, ftest2 int )
Victor

1
Bản vá đang chờ tác giả theo dõi. Cho đến khi tính năng có sẵn, bạn sẽ phải sử dụng trình kích hoạt để kiểm tra tính toàn vẹn có thể bị chậm.
yoonghm 09/07/18

34
xấu hổ, nó không dường như đã được bao gồm :(
Teocali

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.