tags:

views:

1205

answers:

1

I want to add a constraint to my table student such that any value entered in its majors column must also exist in majors table. How can I do this?

+3  A: 

That's a foreign key constraint.

ALTER TABLE student 
 ADD CONSTRAINT somename 
 FOREIGN KEY (major_id) REFERENCES major (id);

Note that if student.major_id is nullable, the column's value can still be null.

Note also your table doesn't accommodate double majors. To do that, we'd have a student_major table that is a many-to-many relation between student and major. This also demonstrates creating foreign keys in a create table, instead of in an alter table

create table student_major (
 id serial not null unique primary key,           -- optional, but good idea
 student_id int not null references student(id),  -- fk 
 major_id int not null references major(id),      -- fk
 UNIQUE (student_id, major_id)                    -- no redundant relations
);

Comment:

-1 for rejecting composite keys. – Bill Karwin

So let me understand this. Bill agrees that I correctly answered the OP's questions about constraints. He agrees that I correctly saw what the OP hadn't asked about, possible double majors. But Bill still marks this answer as wrong because Bill and I disagree about composite keys.

I didn't even say that a synthetic id was necessary; indeed, I specifically said it was optional but in my opinion a good idea. (Why? It "plays better" with deletes, with tables that might reference student_majors, and with ORMS and generated code in general.)

Bill, that's frankly petty. You marked down a correct answer over an elaboration (composite/synthetic) on an elaboration (students:majors being M:M instead of M:1), and over what's a "religious" war. Do you mark down correct answers because you disagree with the answerer's stand on tabs vs. spaces or vi vs. emacs? Maybe you should have taken the time to give your own answer, rather than marking down correct answers.

tpdi
Good advice, but drop the useless serial id "PK" column, and just make (student_id, major_id) the PK. No reason to introduce a worthless surrogate key here.
kquinn
Composite keys are a pain in the ass.
tpdi
-1 for rejecting composite keys.
Bill Karwin
To be consistent with kquinn's advice, you'd also need to remove the majors.major_id and students.student_id fields unless they were facts and not surrogates Depending on the types and number of fields making students and majors unique, a surrogate key might be just what is needed
MkV
I would argue that superfluous ID columns just to avoid composite keys is a bigger PITA then composite keys themselves. You've already got the unique constraint specified, making it the primary key just ratifies the design. The ID column adds no value and detracts from the design in this case.
Evan
I think there shouldn't be an id column in this, but it doesn't change the fact that the part of tpdi response which was answer to hassan question was 100% correct. Modding down based on such criteria (natural vs. surrogate key) is insane.
depesz
James: No, surrogate keys have uses. But not for this table. See http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx for more.
kquinn
Ok, since you feel so slighted, I have reversed the downvote. I still think it's wrong to make blanket statements against composite keys (or any other valid feature). Consider this a "-0" downvote.
Bill Karwin
+1 for rejecting composite keys. :)
egarcia