#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:
Существует три подхода:
- Сначала вставьте a
faculty
, гдеid_dean
равно NULL . Затем вставьте aprofessors
, который ссылается на этуfaculty
запись. Затем обновите первую запись, чтобы она указывала на вторую.Это работает, потому
id_dean
что может быть нулевым, а внешний ключ, для которого установлено значение NULL, не применяется.В общем, рекомендуется иметь как можно больше столбцов
NOT NULL
. В этом случае используйте один из других методов. - Внешние ключи проверяются в конце инструкции, поэтому вставьте обе строки в одну инструкцию:
WITH newfac AS ( INSERT INTO faculty (...) VALUES (...) RETURNING id ) INSERT INTO professors (id_faculty, ...) SELECT newfac.id, ... FROM newfac;
- Используйте ограничение отложенного внешнего ключа:
CREATE TABLE faculty( ..., id_dean int REFERENCES professors DEFERRABLE INITIALLY DEFERRED );
Такое ограничение внешнего ключа проверяется не в конце инструкции, а в конце транзакции. Таким образом, вы можете сначала ввести
faculty
, затемprofessors
, если вы делаете это в одной транзакции базы данных.