23

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?

sandalone
  • 41,141
  • 63
  • 222
  • 338

4 Answers4

29

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!

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • 4
    @askmo. So let me get this right. You would add (a) an autoincrement column (b) and additional index, for the sake of simpler coding ? No concerns about the complete non-dat or non-business requirement ? No concerns re the negative performance ? The lost navigaton (see Larry's answer) ? – PerformanceDBA Jan 25 '11 at 06:59
  • 4
    @marc_s. This is what happens when you let people who are concerned about their personal likes and dislikes; their ease of coding, design "databases". Instead of professional database designers who are concerned with overall use, performance, standards, Relational power. The industry is in a very sad state. – PerformanceDBA Jan 25 '11 at 07:06
  • 8
    @PerformanceDBA: I disagree with your statements - I will **always** prefer a simple INT surrogate key over a complicated, "natural" composite key, for the exact reasons I mentioned - ease of use and ease of creating foreign key relations. I've seen too many times that folks just gave up creating FK constraints because their PK was a composite monster of 6, 10 or even more columns.... – marc_s Jan 25 '11 at 08:18
  • 1
    @marc. Sure, and I have seen about 120 "database" crippled with ID "keys". Forget the Straw Man. 10 columns or 30-byte primary keys are absurd, they **should** have an additional surrogate key, that's sensible. Additional surrogates for a few columns is crippling (did you appreciate Larry's answer). It is not black/white or Databaseland. Simple "rules" for for simple people with black/whie thinking. Anyway, you are free to disagree, whether for technical of personal reasons, it is a free country. – PerformanceDBA Jan 25 '11 at 12:19
  • 2
    @PerformanceDBA: While I'm not certain why you're being so abrasive about this, you both have valid points. Like so many conventions, this very often comes down to personal preference. Yes, there are certain circumstances wherein a natural key (composite or not) will provide a performance or storage benefit. However, database design--like application design, communications protocol design, etc.--cannot be viewed in a vacuum. Consistency in design (e.g. consistently using either natural or surrogate keys) *does* generally provide a benefit, even if that benefit is at another layer. – Adam Robinson Jan 25 '11 at 13:53
  • 3
    (cont.) Natural keys--*especially* natural composite keys--make the table more brittle. That's a fact. *Every* manner of constraint makes a table more brittle, but natural composite keys doubly so, as you're combining a technical constraint (PK) with a business constraint (user-specified uniqueness). Requirements can *and do* change, and I would suspect that you've been in more than one situation where a natural composite key has suddenly become something that is no longer suitable as a primary key. It's disingenuous to say that "real" DBA's are the ones concerned with overall use (or, rather – Adam Robinson Jan 25 '11 at 13:57
  • 2
    (cont.) that they're the *only* ones). The user doesn't give a whit about what you've defined as an identifier in the database. The user doesn't (or shouldn't) care if you're storing the data by altering the refractive index of cat hair. The user cares that the data that gets put in comes out correctly and quickly. – Adam Robinson Jan 25 '11 at 13:59
  • 3
    @Adam. That is entirely and totally incorrect, and that is a fact that can be easily proved. Part of the problem in the industry, is people posting opinions **as fact**. Technical facts are not the same as opinion, they do not change with the person or their level of qualification. If you actually believe any of those "facts" Open a new question, and I will take up each of your points. But this long-winded personal opinion in the commentary is a weird way of getting your "facts" across. Until then, they are mere personal opinion, without evidence, challenged. – PerformanceDBA Jan 27 '11 at 13:03
  • 1
    @Adam, marc. If you are executing a technical endeavour, you should find out the correct way of doing things, why the other ways are incorrect, and execute that. There is no place for personal preferences. When your personal preferences get in the way, you create something selfish, non-technical, without the proper (required for the job) concern for other users. Refer [this answer](http://stackoverflow.com/questions/4808301/when-are-nulls-safe-in-a-column/4813626#4813626). – PerformanceDBA Jan 27 '11 at 13:12
  • 6
    @PerformanceDBA: Thank you for your respectful expression of your own personal opinion. You can rest assured that anyone who reads this will certainly give it all of the consideration that it's due. – Adam Robinson Jan 27 '11 at 13:33
  • 1
    @Adam. Computers work on facts not fiction. That is why qualified technical people work on facts, not opinions. Opinions need to be couched in polite language and sales talk; only non-technicians buy it. Opinions fold at any technical challenge because they have no evidence. Facts have evidence. The FAQ encourages us to be **technically honest**. So please stop posting personal opinions that have no technical basis as facts. Ok ? Otherwise be honest and retract them. Otherwise be honest and ask a question re the facts about your opinions. Thanks. – PerformanceDBA Jan 27 '11 at 14:40
18

You ask the following questions:

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

Uniqueness can be preserved by declaring a separate composite UNIQUE index on columns that would otherwise form the natural primary key.

Which way is better?

Different people have different opinions, sometimes strongly held. I think you will find that more people use surrogate integer keys (not that that makes it the "right" solution).

What are the bad sides of using the 2nd approach?

Here are some of the disadvantages to using a surrogate key:

  1. You require an additional index to maintain the unique-ness of the natural primary key.

  2. You sometimes require additional JOINs to when selecting data to get the results you want (this happens when you could satisfy the requirements of the query using only the columns in the composite natural key; in this case you can use the foreign key columns rather than JOINing back to the original table).

Larry Lustig
  • 49,320
  • 14
  • 110
  • 160
  • 1
    Good answer. Always, not sometimes. (2) might need explanation for some readers, and all the responders. Great-granchild to parent is lost; IDs require joining great-grandchild to grandchild to child to parent. – PerformanceDBA Jan 25 '11 at 07:02
  • 1
    +1 for your second argument against using surrogate keys. (not that I'm against surrogate keys - just the opposite actually) – goku_da_master Sep 13 '13 at 21:28
  • Stated more fair than I might have. The concept of your DB as a fortress seems lost in the new frameworks. Yes, simple, surrogate keys make ORMs easier to set up. But composite keys and, especially, composite natural keys make data analysis easier and raw SQL leaner. With the work I do, working with an ID column on every table is mega-tedious. Apps will come and go but the data stays and has the most value. Simple keys vs composite keys, and surrogate keys vs natural keys are arguments that will never be resolved. Read "Enterprise Rails" by Dan Chak. Some get it, some don't, others ignore it. – juanitogan Jan 27 '14 at 17:00
  • "Enterprise Rails" by Dan Chak is now available online. Chapter 8 deals with Surrogate vs. Composite Keys: http://dan.chak.org/enterprise-rails/chapter-8-composite-keys-and-domain-key-normal-form/ – user2029904 Nov 24 '14 at 20:20
0

There are cases like M:N join tables where composite keys make most sense (and if the nature or the M:N link changes, you'll have to rework this table anyway).

9000
  • 39,899
  • 9
  • 66
  • 104
  • Actually I think you meant about M:M joins where composite keys do have the most sense, but it's better practise to introduce artificial (surrogate) key. It's easier for managing app development. – sbrbot Jun 14 '15 at 16:45
-3

I know it is a very long time since this post was made. But I had to come across a similar situation regarding the composite key so I am posting my thoughts.

Let's say we have two tables T1 and T2.

T1 has the columns C1 and C2.

T2 has the columns C1, C2 and C3

C1 and C2 are the composite primary keys for the table T1 and foreign keys for the table T2.

Let's assume we used a surrogate key for the Table T1 (T1_ID) and used that as a Foreign Key in table T2, if the values of C1 and C2 of the Table T1 changes, it is additional work to enforce the referential ingegrity constraint on the table T2 as we are looking only at the surrogate key from Table T1 whose value didn't change in Table T1. This could be one issue with second approach.

  • 4
    In a normalised database T2 wouldn't contain C1 and C2 so I'm afraid I don't think this is a valid argument. – Caltor Jan 08 '14 at 13:09