Перекрестный внешний ключ Postgresql

#database #postgresql #foreign-keys #primary-key

#База данных #postgresql #внешние ключи #первичный ключ

Вопрос:

Мне нужно создать две таблицы, такие как:

  • Id_faculty_reference и Id_professor являются первичными ключами (это работает)
  • Id_dean является внешним ключом со ссылкой на Id_professor
  • Id_faculty является внешним ключом со ссылкой на Id_faculty_reference (проблему).

Я попробовал это:

 CREATE TABLE Faculty(
      Id_faculty_reference int PRIMARY KEY,
      faculty_name varchar,
      Id_dean int
);

CREATE TABLE Professors(
      Id_professor int PRIMARY KEY,
      Name varchar,
      Last_name varchar,
      Salary int,
      Id_faculty int REFERENCES Faculty(id_faculty_reference)
);

ALTER TABLE Faculty ADD FOREIGN KEY (Id_dean)
   REFERENCES Professors(id_professor);
 

Проблема возникает, когда я пытаюсь добавить информацию в таблицы. Если я попытаюсь добавить информацию Faculty , ссылки не будет, потому Professors что она пуста:

 Key is not present in table "Professors"
 

Если я попытаюсь добавить информацию Professors , ссылки не будет, потому что факультет пуст:

 Key is not present in table "Faculty"
 

Ошибка имеет смысл для меня, но мой профессор говорит, что то, что он просит, можно сделать; как я могу это сделать?

Ответ №1:

Существует три подхода:

  1. Сначала вставьте a faculty , где id_dean равно NULL . Затем вставьте a professors , который ссылается на эту faculty запись. Затем обновите первую запись, чтобы она указывала на вторую.

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

    В общем, рекомендуется иметь как можно больше столбцов NOT NULL . В этом случае используйте один из других методов.

  2. Внешние ключи проверяются в конце инструкции, поэтому вставьте обе строки в одну инструкцию:
     WITH newfac AS (
       INSERT INTO faculty (...) VALUES (...)
       RETURNING id
    )
    INSERT INTO professors (id_faculty, ...)
    SELECT newfac.id, ...
    FROM newfac;
     
  3. Используйте ограничение отложенного внешнего ключа:
     CREATE TABLE faculty(
       ...,
       id_dean int REFERENCES professors DEFERRABLE INITIALLY DEFERRED
    );
     

    Такое ограничение внешнего ключа проверяется не в конце инструкции, а в конце транзакции. Таким образом, вы можете сначала ввести faculty , затем professors , если вы делаете это в одной транзакции базы данных.