2014-06-30 16 views
11

Czy można przypisać klucz obcy do właściwości json w PostgreSQL? Oto przykład tego, co chciałbym osiągnąć, ale to nie działa:Klucze obce JSON w PostgreSQL

CREATE TABLE Users (Id int NOT NULL PRIMARY KEY); 

CREATE TABLE Data (
    Id int NOT NULL PRIMARY KEY, 
    JsonData json NOT NULL, -- [{Id: 1, somedata: null},{Id: 2, somedata: null}, ...] 
    CONSTRAINT FK_Users_Data FOREIGN KEY (JsonData->Id) REFERENCES Users(Id) -- this constraint will fail 
); 
+0

Nie, to niemożliwe. –

+0

Dlaczego nie bierzesz id z json i używasz jako FK w swoim stole .. – cracker

+0

@cracker: to tylko przykład; w moim projekcie mam szereg elementów w polu json - bez takiego ograniczenia będzie wymagało utworzenia nowej tabeli ... – user1613797

Odpowiedz

10

Nie jest możliwe i nigdy nie będzie możliwe przypisanie klucza obcego do właściwości json. Byłaby to poważna i dość skomplikowana zmiana w stosunku do zagranicznych kluczy PostgreSQL. Nie wydaje mi się, żeby było to niemożliwe, ale napotkałby podobne problemy, jak te, których doświadczyła łatka "klucze obce-tablice".

Przy pomocy 9.4 możliwe będzie utworzenie całego obiektu json jako klucza obcego, ponieważ jsonb obsługuje testy równości. W 9.3 nie możesz tego zrobić.

+1

Dzisiaj (2015 r.), Ze stabilną wersją pg9.4 + i jej społecznością, istnieje pewna "dobra praktyka" lub zwyczajna konwencja społeczności pg do wyrażania klucza obcego (z formalnym lub nieformalnym pg-assign)? Zobacz [ten stary linking_in_json] (https://www.mnot.net/blog/2011/11/25/linking_in_json) jako odwołanie do "konwencji linków JSON" ... Przykład, tutaj @ArtemGr pokaż alternatywę i do wyrażenia ID z rzędu, lubię [JSON Reference] (https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03), ale jest on używany w pg-community?) –

+0

@PeterKrauss Nie , nie całkiem. Sytuacja nie zmieniła się znacząco, podobnie jak obce klucze do pól tablicy. Istnieje kilka trudnych problemów z wydajnością, z którymi można sobie poradzić, nawet jeśli ktoś chciał je wdrożyć, i jak dotąd nikt nie robi. –

2

Oto mały funkcja SPI have_ids którego używam na ograniczenia integralności relacji jeden-do-wielu z kolumną jsonb: https://gist.github.com/ArtemGr/67196668a1ea22cfda66

CREATE TABLE foo (
    id INTEGER NOT NULL 
) 

CREATE TABLE bar (
    foo_ids pg_catalog.jsonb DEFAULT '[]'::jsonb NOT NULL, 
    CONSTRAINT bar_fooids_chk CHECK (have_ids ('foo', foo_ids)) 
) 

z kilku wyzwalaczy na foo to prawie tak dobre jak klucz obcy.

+0

Czy masz benchmark pokazujący wydajność (najlepiej w porównaniu z jego analogiem w SQL) swojej funkcji "have_ids()"? Nawet przy "złej wydajności", jeśli jest generyczny i stabilny, będzie dobrą propozycją dla społeczności PostgreSQL. –

+0

Nie, nie porównałem tego, ale charakterystyka wydajności wydaje mi się bardzo przejrzysta. Funkcja wykonuje pętle nad tablicą JSONB i wykonuje zapytanie SELECT COUNT (*) FROM dla każdego identyfikatora. Jest tak szybki, jak suma tych zapytań. Koszt wydajności samej funkcji powinien być niedostateczny. Nie mam wersji SQL, ani nie wiem, jak ją napisać. Myślę, że PosgreSQL będzie w końcu miał pierwszorzędne wsparcie dla kluczy obcych opartych na tablicy (https://wiki.postgresql.org/wiki/Todo#Referential_Integrity), więc to obejście nie powinno być potrzebne w dłuższej perspektywie. – ArtemGr

Powiązane problemy