PostgreSQL - дополнительные ограничения внешнего ключа для авторизации - PullRequest
0 голосов
/ 10 марта 2019

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

Это может быть неясно, но я думаю, что пример прояснит то, что я спрашиваю:

Рассмотрим базу данных с таблицей с именем user_account, которая представляет учетные записи пользователей. Пользователи приложения могут создавать books и chapters, которые представлены в виде отдельных таблиц в базе данных.

Каждый chapter и book имеет внешний ключ для user_account - учетной записи, которая создала и «владеет» этим фрагментом данных. Идея заключается в том, что пользователи должны иметь возможность изменять только свои собственные книги и главы.

Фрагмент таблицы book может выглядеть примерно так:

CREATE TABLE book (
  user_account_id uuid,
  FOREIGN KEY (user_account_id) REFERENCES user_account(id)
);

Кроме того, каждый chapter должен иметь связанный book. Рассмотрим этот фрагмент определения таблицы chapter:

CREATE TABLE chapter (
  user_account_id uuid,
  book_id uuid,

  FOREIGN KEY (book_id) REFERENCES book(id),
  FOREIGN KEY (user_account_id) REFERENCES user_account(id)
);

Проблема с этим внешним ключом состоит в том, что он позволяет пользователю создавать главу, связанную с чужой книгой , если только я не насторожусь с этим в коде приложения.

Если он должен применяться на прикладном уровне, то это нормально. Тем не менее, это похоже на то, что PostgreSQL может обеспечить. Есть ли способ потребовать, чтобы book_id данного chapter ссылалось на book с тем же user_account_id, что и chapter?

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

1 Ответ

0 голосов
/ 10 марта 2019

Я понял это, используя ответы здесь и две возможности PostgreSQL:

  1. Ограничения
  2. Составные внешние ключи

Во-первых, в таблицу books добавьте CONSTRAINT:

UNIQUE (id, user_account_id)

Это позволит PostgreSQL знать, что комбинация этих двух столбцов уникальна для всей таблицы.Хотя user_account_id может быть продублирован, мы знаем, что id всегда уникален.Следовательно, идентификатор в сочетании с чем-либо еще также гарантированно будет уникальным (это то, на что ссылается плакат упомянутого вопроса).

Если продолжить, настройка этого ограничения позволяет использовать aсоставной внешний ключ в таблице chapters:

FOREIGN KEY (asset_id, user_account_id) REFERENCES asset(id, user_account_id) ON DELETE SET NULL,

Кажется, это работает как ожидалось.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...