Массив PostgreSQL элементов, каждый из которых является внешним ключом

Я пытаюсь создать БД для своего приложения, и я бы хотел найти лучший способ сделать это - создать связь «один ко многим» между моими таблицами Users и Items.

Я знаю, что могу создать третью таблицу, ReviewedItems, и столбцы будут иметь User id и Item id, но я хотел бы знать, можно ли создать столбец в Users, скажем reviewedItems, который является целочисленным массивом содержащие внешние ключи к Items, которые User рассмотрел.

Если PostgreSQL может это сделать, дайте мне знать! Если нет, я просто пойду по своему третьему столовому маршруту.


person Zach    schedule 09.12.2016    source источник
comment
Существовали патчи для добавления этой функции в Postgres, см. blog.2ndquadrant.com/ (2012) и postgresql.org/message-id/ (2017). Они еще не приняты, но, надеюсь, когда-нибудь.   -  person Simon Kissane    schedule 10.09.2017


Ответы (2)


Нет, это невозможно.

PostgreSQL - это реляционная СУБД, наиболее эффективно работающая с правильно нормализованными моделями данных. Массивы по определению являются упорядоченными наборами, а не реляционными структурами данных, поэтому стандарт SQL не поддерживает определение внешних ключей для элементов массива, как и PostgreSQL.

Однако вы можете создать прекрасную базу данных с элементами массива, связанными с первичными ключами в других таблицах. Однако эти элементы массива не могут быть объявлены внешними ключами, и поэтому СУБД не будет поддерживать ссылочную целостность.

person Patrick    schedule 09.12.2016
comment
Вы можете определить триггер ограничения, который будет это проверять. Но я не уверен, что он работает надежно во всех случаях. - person a_horse_with_no_name; 09.12.2016
comment
@a_horse_with_no_name: не могли бы вы привести пример о reliably in all cases? Вы имеете в виду, что иногда триггер может не сработать? Спасибо. - person Luan Huynh; 09.12.2016
comment
@LuanHuynh: Я не помню (технических) деталей, но в последний раз, когда это обсуждалось в списке рассылки, кто-то упомянул, что соответствующий триггер ограничения может не улавливать все случаи, но это может больше не соответствовать действительности - person a_horse_with_no_name; 09.12.2016
comment
Спасибо, я просто сделаю для них таблицу отношений - person Zach; 10.12.2016
comment
@a_horse_with_no_name, можете ли вы опубликовать ответ с примером такого ограничения? - person OrangeDog; 18.01.2019
comment
это как-то увеличивает производительность? Или кто-то должен придерживаться подхода третьей таблицы? - person Muhammad Asim; 14.02.2020
comment
обходной путь / редизайн: наличие отдельной таблицы многие-ко-многим - person Jean Monet; 05.02.2021
comment
Очевидно, sql: 2016 действительно поддерживает такое поведение. К сожалению, стандарт недоступен в свободном доступе, но вы можете увидеть ссылки на него в обоих разделах документация Microsoft и список неподдерживаемых стандартных функций PostgreSQL. - person Phil Frost; 22.07.2021

Вскоре это станет возможным: https://commitfest.postgresql.org/17/1252/ - Марк Рофайл проделал отличную работу над этим патчем!

Патч (после завершения) позволит

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

Тем не менее, в настоящее время автору нужна помощь в перебазировании патча (за пределами моих возможностей), поэтому любой, кто читает это, кто знает внутреннее устройство Postgres, пожалуйста, помогите, если сможете.

person Jarym    schedule 21.05.2018
comment
действительно очень жарко ... CREATE TABLE FKTABLEFORARRAY ( ftest1 int[], FOREIGN KEY (EACH ELEMENT OF ftest1) REFERENCES PKTABLEFORARRAY, ftest2 int ) - person Victor; 19.06.2018
comment
Патч ожидает ответа от автора. Пока эта функция не станет доступной, вам придется использовать триггер для проверки целостности, что может быть медленным. - person yoonghm; 09.07.2018
comment
позор, похоже, не включили :( - person Teocali; 24.07.2019
comment
2020, все еще не поддерживается: postgresql.org/docs/13/unsupported -features-sql-standard.html - person M Imam Pratama; 24.09.2020
comment
Это действительно полезно. - person karianpour; 02.02.2021