Postgres — Ограничение, если атрибут в одной таблице совпадает с ключом в другой [СОЗДАТЬ ТАБЛИЦУ]

#sql #postgresql

#sql #postgresql

Вопрос:

У меня проблема, которую я не могу решить. У меня есть две таблицы Branches и Students . У каждого учащегося есть атрибут program, и у каждой ветви есть имя и программа, это объединенный первичный ключ.

 CREATE TABLE Branches(
    name TEXT NOT NULL,
    program TEXT NOT NULL,
    PRIMARY KEY (name, program),
    FOREIGN KEY (program) REFERENCES Programs(name)
);

CREATE TABLE Students(
    idnr NUMERIC(10) PRIMARY KEY,
    name TEXT NOT NULL,
    login TEXT NOT NULL UNIQUE, 
    program TEXT NOT NULL,
    FOREIGN KEY (program) REFERENCES Programs(name)

);
  

Я хочу создать новую таблицу, StudentBranches содержащую информацию о том, к какой ветви, если таковая имеется, принадлежит студент. Пока это мой код:

 CREATE TABLE StudentBranches(
    student NUMERIC(10) PRIMARY KEY,
    branch TEXT NOT NULL, 
    program TEXT NOT NULL,
    FOREIGN KEY (student) REFERENCES Students(idnr),
    FOREIGN KEY (branch, program) REFERENCES Branches(name,program)
);
  

Мой вопрос заключается в следующем, мне нужно проверить, совпадает ли внешний ключ программы из филиалов с программой, назначенной учащемуся. Я не могу использовать какие-либо триггеры. Как бы мне это сделать?

Ответ №1:

Добавьте уникальное ограничение для учащихся как с номером, так и с программой:

 CREATE TABLE Students (
    idnr NUMERIC(10) PRIMARY KEY,
    name TEXT NOT NULL,
    login TEXT NOT NULL UNIQUE, 
    program TEXT NOT NULL,
    FOREIGN KEY (program) REFERENCES Programs(name),
    UNIQUE (program, idnr)
);
  

Это немного избыточно — в конце концов, idnr это уже уникально. Однако это позволяет добавить ссылку на внешний ключ, которая включает program :

 CREATE TABLE StudentBranches(
    student NUMERIC(10) PRIMARY KEY,
    branch TEXT NOT NULL, 
    program TEXT NOT NULL,
    FOREIGN KEY (student) REFERENCES Students(idnr),
    FOREIGN KEY (program, student) REFERENCES Students(program, idnr,),
    FOREIGN KEY (branch, program) REFERENCES Branches(name,program)
);