Как проверить отношения аргументов функции?

У меня есть несколько функций postgres, которые принимают ряд аргументов для записи в несколько таблиц.

fn_trade
(
  _product_id BIGINT[],
  _user_id BIGINT[],
  _location_id BIGINT
)

Поскольку аргументы поступают от клиента или сервера Node.js, мне нужно проверить, что данные существуют (обрабатываются ограничениями FK, но не в случае BIGINT []), и мне нужно подтвердить, что отношения аргументов действительны. . Например, я должен проверить, что user и product существуют для location, а product принадлежит к user. Сложность этой проверки возрастает с увеличением количества аргументов. Я могу привести более 10 аргументов, и проверка их взаимосвязи будет сложной и дорогостоящей.

Я не знаю, упускаю ли я важную картину, пытаясь проверить аргументы функции. Это правильный подход? Есть ли лучший способ быть уверенным в взаимосвязях аргументов, чтобы заполненные данные всегда были ожидаемыми?

Возможный подход может заключаться в том, чтобы предсказать результат и проверить, записан ли результат после завершения записи (иначе откат)?

Postgres 9.6+

Обновлено: добавлен пример, чтобы прояснить вопрос

Таблицы:

location (id, name) -- e.g. 1, 'Canada'

user (id, name, location_id) -- e.g. 1, Jane, 1

product (id, name, user_id, location_id) -- e.g. 1, 'skates', 1, 1

trade (id, user_id[], product_id[]) -- e.g. 1, [1,2], [1,2,3,4]

Когда происходит сделка, мне нужно подтвердить, что предоставленные данные соответствуют данным в базе данных.

Например, я получаю:

fn_trade
(
  [1,2,3,4],
  [1,2],
  1
)

Таким образом, торговля происходит для пользователей [1,2] на продукты [1,2,3,4] в Канаде. У пользователей могут быть элементы в разных местах, и пользователи могут перемещаться в разные места.

При вставке user_id[] и product_id[] в trade проверка отдельных идентификаторов не выполняется автоматически. Я не знаю, можно ли установить значения в массиве как FK, поэтому проверка здесь выполняется вручную. Мне нужно гарантировать, что все идентификаторы [1,2,3,4] существуют для продукта.

А как насчет отношений? Мне нужно проверить, что идентификаторы также принадлежат пользователям [1,2].

Принадлежать пользователю недостаточно. Товары должны находиться в том же месте, где происходит торговля.

Что касается пользователей, мне нужно знать, можно ли им торговать. Если они живут в разных местах (Канада против Тайваня), то торговля невозможна.

Поскольку данные клиента зависят от БД, а данные, передаваемые в fn_trade, могут быть ненадежными, как следует проверить отношение, чтобы доказать, что данные верны для наших пользователей, продуктов и отношений местоположения?

Внешние ключи были изобретены только для того, чтобы вам не приходилось вручную проверять эти отношения. Если внешние ключи неверны при вставке или обновлении строк, сервер вызовет исключение.

klin 27.04.2018 22:39

@klin Я думал, что FK проверяет только то, что ключ существует в таблице, а не то, что product принадлежит user, и они оба живут в location. Не удалось передать ошибочный аргумент, содержащий действительный FK? Я вставляю или обновляю product, не принадлежащий к user, а не тот location. Все идентификаторы существуют для таблиц, но не для правильных отношений.

Dan 27.04.2018 22:52

Я снова прочитал вопрос и ваш комментарий и не уверен, что понял логику. Вроде стоит попробовать поставить Минимальный, полный и проверяемый пример.

klin 27.04.2018 23:21

@klin Я добавил пример, который, надеюсь, устранит некоторую двусмысленность из моего вопроса. Глядя на проблему, возможно, что хранение массивов может быть нежелательным. Мне все еще не хватает опыта, чтобы сказать.

Dan 30.04.2018 01:37

Модель вашей базы данных не смоделирована должным образом для выполнения проверок FK, как указано @klin. Правильный способ имел бы одну строку для каждого пользователя / продукта в торговой таблице. Для значений массива нет проверки внешнего ключа. Вот лучшее объяснение: stackoverflow.com/questions/41054507/…

Jorge Campos 30.04.2018 01:44

Если бы он был правильно смоделирован, вам даже не понадобилась бы функция.

Jorge Campos 30.04.2018 01:45

@JorgeCampos Я мог бы в будущем провести рефакторинг схемы, но предлагаемые проверки ограничений в ссылке для массивов сразу же полезны. Нормализация схемы должна упростить проверку, но по-прежнему не может гарантировать, что переданные значения связаны. Предполагая, что я нормализовал продукты, я все равно могу передать продукт, который принадлежит кому-то другому. Чем больше у меня аргументов, тем больше проверка отношения.

Dan 30.04.2018 04:55

Нет, если у вас есть ограничение между пользователем и продуктом, вы создаете таблицу для нормализации этого ограничения, и ваша сделка будет иметь FK для этой таблицы. Это все о нормализации. Опять же, если вы все сделаете правильно, вам не понадобится функция для проверки.

Jorge Campos 30.04.2018 13:48
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
8
49
0

Другие вопросы по теме