views:

55

answers:

2

Is it better to have a single primary key, or use composite primary keys (usually, they are combination of one primary key and foriegn keys). I have examples below:

Composite Primary Key example:

AMeta

    --- AMetaId - Primary Key
    --- AMetaText

BMeta

    --- BMetaId - Primary Key
    --- AMetaID - Foreign Key to Table AMeta
    --- BMetaText

A

    --- AId - Primary Key
    --- AMetaId - Primary Key and Foreign Key to Table AMeta
    --- AText

B

    --- BId - Primary Key
    --- BMetaId - Primary Key Foreign Key to Table BMeta
    --- AId - Primary Key and Foreign Key to Table A
    --- BText


Single Primary Key example:

AMeta

    --- AMetaId - Primary Key
    --- AMetaText

BMeta

    --- BMetaId - Primary Key
    --- AMetaId - Foreign Key to Table AMeta
    --- BMetaText

A

    --- AId - Primary Key
    --- AMetaId - Foreign Key to Table AMeta
    --- AText

B

    --- BId - Primary Key
    --- BMetaId - Foreign Key to Table BMeta
    --- AId - Foreign Key to Table A
    --- BText

Which is the better Database Design?

+1  A: 

The first scheme makes no sense, because it implies (and allows) that there can be multiple rows in Table B with the same BId value but with different values of AId, and there is no meaning associated with column Bid. Is it a FK to somewhere else? If so, to what? If not, what is generating it ? What does it mean?

The second scheme, on the other hand, is logically consistent, but implies that rows in Table B can be associated with two different rows in Table AMeta,

  1. through Table B using the FK Column BMetaId and from there to Table AMeta using TableB.AMetaId, and
  2. Through table BMeta using column BMetaId to Table BMeta and from there to AMeta using BMEta.AMetaId

Is this really an accurate representation of your business domain model?

Charles Bretana
That is true Charles. That is why all three columns have to be used in order to make it a primary key. BID is actually a sequence number that starts over for each AID. This is not my domain model, but one I inherited, unfortunately LOL
Moderator71
Also, TableB doesn't have a AMetaId. AMetaID provides a description to TableA. TableA is a parent to TableB; therefore, TableB can walk up the heirarchy to get to the AMetaTable. Do you see anything wrong with that? If so, let me know!
Moderator71
@Moderator, Your column naming scheme is confusing me then. In general, the phrase Id, should be used only when the value in the column is a single unique Id in some table somewhere, which BId is not in your scheme, "SeqNo" would be a more descriptibe name. (I know, you inherited it lol) So, clearly in this case the BId in the second scheme is totaly different from the bId in the first scheme?
Charles Bretana
Yes, I would need to create a seperate Sequence column for the BTable. Thanks for following up. I wish I could select two answers or combine them into one because both of you provided some good feedback to my question.
Moderator71
+1  A: 

I genereally tend to use single-column primary keys almost exclusively - either there is a good natural key available (pretty rarely), or then I add a surrogate INT IDENTITY key to the table.

My main reasons are:

  • the primary key needs to be unique, non-null at all times
  • the primary key is the clustering key in SQL Server by default, which adds stable (non-changing), narrow (4 bytes max.) and preferably ever-increasing to the list of criteria
  • with a single column primary key, all my foreign keys are also easy to use single columns - I don't like having to join two tables on 3, 5 or even more columns just to get the join to work, which is exactly what happens if you have a compound primary key
marc_s