PostgreSQL-Array von Elementen, die jeweils ein Fremdschlüssel sind


83

Ich versuche, eine Datenbank für meine App zu erstellen, und ich möchte den besten Weg finden, eine Eins-zu-Viele-Beziehung zwischen meiner Usersund meinen ItemsTabellen herzustellen.

Ich weiß , ich kann einen dritten Tisch machen, ReviewedItemsund haben die Säulen sein , UserID und eine ItemID, aber ich würde gerne wissen , ob es möglich ist , in eine Spalte zu machen Users, lassen Sie uns sagen reviewedItems, das ist eine ganze Zahl Array mit Fremdschlüssel zu , Itemsdass das Userhat überprüft.

Wenn PostgreSQL dies kann, lassen Sie es mich bitte wissen! Wenn nicht, gehe ich einfach meine dritte Tischroute entlang.


3
Es gab Patches, um diese Funktion zu Postgres hinzuzufügen, siehe blog.2ndquadrant.com/… (2012) und postgresql.org/message-id/… (2017). Sie wurden noch nicht akzeptiert, aber hoffentlich eines Tages.
— Simon Kissane

Antworten:


68

Nein das ist nicht möglich.

PostgreSQL ist ein relationales DBMS, das am effizientesten mit ordnungsgemäß normalisierten Datenmodellen arbeitet. Arrays sind - per Definition - geordnete Mengen - keine relationalen Datenstrukturen, und der SQL-Standard unterstützt daher nicht die Definition von Fremdschlüsseln für Array-Elemente und PostgreSQL auch nicht.

Sie können jedoch eine einwandfreie Datenbank mit Array-Elementen erstellen, die mit Primärschlüsseln in anderen Tabellen verknüpft sind. Diese Array-Elemente können jedoch nicht als Fremdschlüssel deklariert werden, und das DBMS behält daher keine referenzielle Integrität bei.


3
Sie können einen Einschränkungsauslöser definieren, der dies überprüft. Ich bin mir aber nicht sicher, ob es in allen Fällen zuverlässig funktioniert.
— a_horse_with_no_name

@a_horse_with_no_name: Könnten Sie ein Beispiel geben reliably in all cases? Du meinst manchmal kann der Trigger fehlschlagen? Vielen Dank.
— Luan Huynh

1
@LuanHuynh: Ich erinnere mich nicht an die (technischen) Details, aber als dies das letzte Mal auf der Mailingliste besprochen wurde, erwähnte jemand, dass ein entsprechender Einschränkungsauslöser möglicherweise nicht alle Fälle
— abfängt

Danke, ich denke, ich mache nur eine Beziehungstabelle für sie
— Zach

1
@a_horse_with_no_name können Sie eine Antwort mit einem Beispiel für eine solche Einschränkung posten?
— OrangeDog

65

Möglicherweise ist dies bald möglich: https://commitfest.postgresql.org/17/1252/ - Mark Rofail hat hervorragende Arbeit an diesem Patch geleistet!

Der Patch wird (sobald er abgeschlossen ist) zulassen

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

Derzeit benötigt der Autor jedoch Hilfe, um den Patch neu zu starten (über meine eigenen Fähigkeiten hinaus). Wenn Sie dies lesen und Postgres-Interna kennen, helfen Sie bitte, wenn Sie können.


8
sehr heiß in der Tat ...CREATE TABLE FKTABLEFORARRAY ( ftest1 int[], FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY, ftest2 int )
— Victor

1
Der Patch wartet darauf, dass der Autor nachverfolgt wird. Bis die Funktion verfügbar ist, müssen Sie den Trigger verwenden, um die Integrität zu überprüfen, die möglicherweise langsam ist.
— Yoonghm

34
Schade, es scheint nicht enthalten gewesen zu sein :(
— Teocali

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.