Composite primary key or not?

sandalone picture sandalone · Jan 19, 2011 · Viewed 21.1k times · Source

Here's what's confusing me. I often have composite primary keys in database tables. The bad side of that approach is that I have pretty extra work when I delete or edit entries. However, I feel that this approach is in the spirit of database design.

On the other side, there are friends of mine, who never use composite keys, but rather introduce another 'id' column in a table, and all other keys are just FKs. They have much less work while coding delete and edit procedures. However, I do not know how they preserve uniqueness of data entries.

For example:
Way 1

create table ProxUsingDept (
    fkProx int references Prox(ProxID) NOT NULL,    
    fkDept int references Department(DeptID) NOT NULL,    
    Value int,    
    PRIMARY KEY(fkProx,fkDept)
)

Way 2

create table ProxUsingDept (
        ID int NOT NULL IDENTITY PRIMARY KEY
        fkProx int references Prox(ProxID) NOT NULL,    
        fkDept int references Department(DeptID) NOT NULL,    
        Value int
)

Which way is better? What are the bad sides of using the 2nd approach? Any suggestions?

Answer

marc_s picture marc_s · Jan 19, 2011

I personally prefer your 2nd approach (and would use it almost 100% of the time) - introduce a surrogate ID field.

Why?

  • makes life a lot easier for any tables referencing your table - the JOIN conditions are much simpler with just a single ID column (rather than 2, 3, or even more columns that you need to join on, all the time)

  • makes life a lot easier since any table referencing your table only needs to carry a single ID as foreign key field - not several columns from your compound key

  • makes life a lot easier since the database can handle the creation of unique ID column (using INT IDENTITY)

However, I do not know how they preserve uniqueness of data entries.

Very simple: put a UNIQUE INDEX on the compound columns that you would otherwise use as your primary key!

CREATE UNIQUE INDEX UIX_WhateverNameYouWant 
   ON dbo.ProxUsingDept(fkProx, fkDept)

Now, your table guarantees there will never be a duplicate pair of (fkProx, fkDept) in your table - problem solved!