我在PostgreSQL中有两个表:
create Table student (
studentID integer primary key,
studentname text
);
create Table courses (
courseID text primary key,
schoolname text
);
我想创建第三个表schoolstudent
,该表具有外键(studentID, schoolname)
,其中studentID
引用student
表的主键和schoolname
个引用schoolname
表中的courses
键。
如何在PostgreSQL 9.4或9.5中的两个不同的表中创建外键?
答案 0 :(得分:1)
FK约束要求目标列具有UNIQUE或PK约束,schoolname
显然无法提供。每个学校需要另一个包含唯一行的表:
CREATE TABLE school(
school_id serial PRIMARY KEY,
schoolname text NOT NULL
);
CREATE TABLE student(
student_id serial PRIMARY KEY,
studentname text
);
CREATE TABLE schoolstudent(
school_id int REFERENCES school,
student_id int REFERENCES student,
PRIMARY KEY (school_id, student_id)
);
CREATE TABLE course(
course_id text PRIMARY KEY,
school_id int REFERENCES school
);
对外键约束使用短语法。 Details in the manual.
如果您在schoolname
表中确实需要schoolstudent
(我严重怀疑,看起来像是 设计错误 ),那么可以添加它。要强制引用完整性,您可以在外键中包含,但在UNIQUE
上也需要(冗余)匹配school(school_id, schoolname)
约束。
CREATE TABLE schoolstudent(
school_id int,
student_id int REFERENCES student,
schoolname text,
PRIMARY KEY (school_id, student_id),
CONSTRAINT schoolstudent_combo_fk FOREIGN KEY (school_id, schoolname)
REFERENCES school (school_id, schoolname) ON UPDATE CASCADE
);
在这种情况下使用显式语法。我建议级联更新。
或如果schoolname
实际上保证为UNIQUE
(再次,我怀疑),您可以完全替换school_id
并使用schoolname
作为PK和FK列。但是,如果性能很重要,那么长text
列对于此目的来说效率不高。而且学校名称发生了变化,这对PK专栏来说并不理想。
在任何情况下,您仍然需要一个单独的school
表。
答案 1 :(得分:0)
只有当两个字段都是唯一(可能是主键)时才能设置多对多关系。如果上述条件已满足,则可以使用
CREATE TABLE Schoolstudent(
ID INT references student(studentID),
Schoolname CHAR(50) references courses(Schoolname),
);
但表schoolname
中的courses
应该唯一或PK 。