I have a database design that makes use of compound primary keys to ensure uniqueness and which are also foreign keys.
These tables are then linked to other tables in the same way, so that in the end the compound key can get up to 4 or 5 columns. This led to some rather large JOINs, so I thought a simple solution would be to use an autoincrement column which is not part of the primary key but which is used as part of the primary key of other table(s).
Here is some pseudo code showing the general layout :
CREATE TABLE Item (
id AUTO_INCREMENT,
...
PRIMARY KEY (id)
) ENGINE = InnoDB;
CREATE TABLE PriceCategory (
id AUTO_INCREMENT,
...
PRIMARY KEY (id)
)
CREATE TABLE ItemPriceCategory (
itemId,
priceCategoryId,
id AUTO_INCREMENT,
...
UNIQUE INDEX id,
PRIMARY KEY (eventId, priceCategoryId)
)
CREATE TABLE ClientType (
id AUTO_INCREMENT,
...
PRIMARY KEY (id)
)
CREATE TABLE Price (
itemPriceCategoryId,
clientTypeId,
id AUTO_INCREMENT,
...
UNIQUE INDEX id,
PRIMARY KEY (itemPriceCategoryId, clientTypeId)
)
table Purchase (
priceId,
userId,
amount,
PRIMARY KEY (priceId, userId)
)
The names of tables have been changed to protect the innocent 😉 Also the actual layout is a little deeper in terms of references.
So, my question is, is this a viable strategy, from a performance and data integrity point of view ? Is it better to have all keys from all the referenced tables in the Purchase table ?
Thanks in advance.
Generally, the advice on primary keys is to have “meaningless”, immutable primary keys with a single column. Auto incrementing integers are nice.
So, I would reverse your design – your join tables should also have meaningless primary keys. For instance:
That way, the itemPriceCategoryId column in price is a proper foreign key, linking to the primary key of the ItemPriceCategory table.
You can then use http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html foreign keys to ensure the consistency of your database.
In terms of performance, broadly speaking, this strategy should be faster than querying compound keys in a join, but with a well-indexed database, you may not actually notice the difference…