从两个不同的表

时间:2015-12-02 06:15:57

标签: postgresql database-design foreign-keys many-to-many foreign-key-relationship

我在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中的两个不同的表中创建外键?

2 个答案:

答案 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