MikeTheCoder
MikeTheCoder

Reputation: 963

Does it make sense to have three primary keys, two of which are foreign keys, in one table?

I've created a database with three tables in it:

Restaurant
restaurant_id (autoincrement, PK)

Owner
owner_id (autoincrement, PK)
restaurant_id (FK to Restaurant)

Deal
deal_id (autoincrement)
owner_id (FK to Owner)
restaurant_id (FK to Restaurant)
(PK: deal_id, owner_id, restaurant_id)

There can be many owners for each restaurant. I chose two foreign keys for Deal so I can reference the deal by either the owner or the restaurant. The deal table would have three primary keys, two being foreign keys. And it would have two one-to-many relationships pointing to it. All of my foreign keys are primary keys and I don't know if I'll regret doing it like this later on down the road. Does this design make sense, and seem good for what I'm trying to achieve?

Edit: What I really need to be able to accomplish here is when a owner is logged in and viewing their account, I want them to be able to see and edit all the deals that are associated with that particular restaurant. And because there can be more that one owner per restaurant, I need to be able to perform a query something like: select *from deals where restaurant_id = restaurant_id. In other words, if I'm an owner and I'm logged in, I need to be able to make query: get all of the deal that are related to not just me, the owner, but to all of the owners associated with this restaurant.

Upvotes: 0

Views: 8065

Answers (5)

umlcat
umlcat

Reputation: 4143

Its not wrong, it works. But, its not recommended.

Autoincrement Primary Keys works without Foreign Keys (or Master Keys)

In some databases, you cannot use several fields as a single primary key.

Compound Primary Keys or Compose Primary Keys are more difficult to handle in a query.

Compound Primary Key Query Example:

SELECT
  D.*
FROM 
  Restaurant AS R,
  Owner AS O,
  Deal AS D
WHERE
  (1=1) AND
  (D.RestaurantKey = D.RestaurantKey) AND
  (D.OwnerKey = D.OwnerKey)

Versus

Single Primary Key Query Example:

SELECT
  D.*
FROM 
  Restaurant AS R,
  Owner AS O,
  Deal AS D
WHERE
  (D.OwnerKey = O.OwnerKey)

Sometimes, you have to change the value of foreign key of a record, to another record. For Example, your customers already order, the deal record is registered, and they decide to change from one restaurant table to another. So, the data must be updated, in the "Owner", and "Deal" tables.

+-----------+-------------+
|  OwnerKey | OwnerName   |
+-----------+-------------+
|      1    | Anne Smith  |
+-----------+-------------+
|      2    | John Connor |
+-----------+-------------+
|      3    | Mike Doe    |
+-----------+-------------+

+-----------+-------------+-------------+
|  OwnerKey |   DealKey   |     Food    |
+-----------+-------------+-------------+
|      1    |       1     | Hamburguer  |
+-----------+-------------+-------------+
|      2    |       2     |   Hot-Dog   |
+-----------+-------------+-------------+
|      3    |       3     | Hamburguer  |
+-----------+-------------+-------------+
|      1    |       3     |    Soda     |
+-----------+-------------+-------------+
|      2    |       1     | Apple Pie   |
+-----------+-------------+-------------+
|      3    |       3     |    Chips    |
+-----------+-------------+-------------+

If you use compound primary keys, you have to create a new record for "Owner", and new records for "Deals", copy the other fields, and delete the previous records.

If you use single keys, you just have to change the foreign key of Table, without inserting or deleting new records.

Cheers.

Upvotes: 0

Larry Lustig
Larry Lustig

Reputation: 50970

You're having some trouble with terminology.

A table can only ever have a one primary key. It is not possible to create a table with two different primary keys. You can create a table with two different unique indexes (which are much like a primary key) but only one primary key can exist.

What you're asking about is whether you should have a composite or compound primary key; a primary key using more than one column.

Your design is okay, but as written you probably have no need for the column deal_id. It seems to me that restaurant_id and owner_id together are enough to uniquely identify a row in Deal. (This may not be true if one owner can have two different ownership stakes in a single restaurant as the result of recapitalization or buying out another owner, but you don't mention anything like that in your problem statement).

In this case, deal_id is largely wasted storage. There might be an argument to be made for using the deal_id column if you have many tables that have foreign keys pointing to Deal, or if you have instances in which you want to display to the user Deals for multiple restaurants and owners at the same time.

If one of those arguments sways you to adopt the deal_id column, then it, and only it, should be the primary key. There would be nothing added by including the other two columns since the autoincrement value itself would be unique.

Upvotes: 4

ErikE
ErikE

Reputation: 50211

I think it is not best.

First of all, the Deal table PK should be the deal_id. There is no reason to add additional columns to it--and if you did want to refer to the deal_id in another table, you'd have to include the restaurant_id and owner_id which is not good. Whether deal_id should also be the clustered index (a.k.a. index organized on this column) depends on the data access pattern. Will your database be full of data_id values most often used for lookup, or will you primarily be looking deals up by owner_id or restaurant_id?

Also, using two separate FKs way the you have described it (as far as I can tell!) would allow a deal to have an owner and restaurant combination that are not a valid (combining an owner that does not belong to that restaurant). In the Deal table, instead of one FK to Owner and one FK to Restaurant, if you must have both columns, there should be a composite FK to only the Owner table on (OwnerID, RestaurantID) with a corresponding unique key in the Owner table to allow this link up.

However, with such a simple table structure I don't really see the problem in leaving RestaurantID out of the Deal table, since the OwnerID always fully implies the RestaurantID. Obviously your deals cannot be linked only with the restaurant, because that would imply a 1:M relationship on Deal:Owner. The cost of searching based on Restaurant through the Owner table shouldn't really be that bad.

Upvotes: 0

Christopher Pelayo
Christopher Pelayo

Reputation: 802

if you want to create 2 foreign keys in the deal table which are the restaurant and the owner the logic is something like a table could exist in the deal even without an owner or an owner could exist in the deal even without identifying the table on it but you could still identify the table because it's being used as a foreign key on the owner table, but if your going to put values on each columns that you defined as foreign key then I think it's going to be redundant cause I'm not sure how you would use the deal table later on but by it's name I think it speaks like it would be used to identify if a restaurant table is being reserved or not by a customer and to see how you have designed your database you could already identify the table which they have reserved even without specifying the table as foreign key in the deal table cause by the use of the owner table you would able to identify which table they have reserved already since you use it as foreign key on the owner table you just really have to be wise on defining relationships between your tables and avoid redundancy as much as possible. :)

Upvotes: 0

Itay Moav -Malimovka
Itay Moav -Malimovka

Reputation: 53597

If u have a unique field, this should be the PK, that would be the incremented field.
In this specific case it gives u nothing at all to add more fields to this key, it actually somewhat impacts performance (don't ask me how much, u bench it).

Upvotes: 1

Related Questions