-1

I'm trying to create a foreign key between two tables. Problem is one of those tables has a composite primary key..

My tables are products (one row per product) and product_price_history (many rows per product). I have a composite key in product_price_history, which is product id and start date of a specific price for that product.

Here's my code :

CREATE TABLE products (
    product_id INT IDENTITY(1,1) PRIMARY KEY,
    product_name VARCHAR(50) NOT NULL,
    product_desc VARCHAR(255) NULL,
    product_group_id INT
)
CREATE TABLE product_price_history (
    product_id INT NOT NULL,
    start_date DATE NOT NULL,
    end_date DATE NULL,
    price NUMERIC (6,2) NOT NULL
)
ALTER TABLE product_price_history
    ADD CONSTRAINT pk_product_id_start_dt
    PRIMARY KEY (product_id,start_date)

Now I'm trying to create a foreign key between the products table and the product_price_history table but I can't because its a composite key.

Also it doesn't make sense to add the start date (the other part of the foreign key) to the products table.

What's the best way to deal with this? Can I create a foreign key between these tables? Do I even NEED a foreign key?

My intentions here are

  1. to enforce uniqueness of the product price information. A product can only have one price at any time.
  2. to link these two tables so there's a logical join between them, and I can show this in a database diagram
philipxy
  • 14,867
  • 6
  • 39
  • 83
Nick
  • 9
  • 3
  • 1
    _but I can't_ Why can't you? Did you try and encounter an error? If so, post the complete error message. And as already noted, the foreign key must be added to the history table and refers back to the product table. – SMor Aug 15 '22 at 11:09
  • The error / warning was: "There are no primary or candidate keys in the referenced table 'product_price_history' that match the referencing column list in the foreign key 'fk_product_pp_history'. Could not create constraint or index. " – Nick Aug 15 '22 at 13:30

1 Answers1

0

The foreign key on the product_price_history table should only include product_id. Your target is to ensure that any entry product_price_history already has "parent" entry in products. That has nothing to do with start_date.

The way I see this situation, in theory, fully normalized version of the tables would have to have current_price as unique value in products table. And the product_price_history is simply a log table.

It's not necessary to do it this way, with a physical field, but thinking from this perspective helps to see where your tables model is slightly de-normalized.

Also, if you make product_price_history table anything but simple log table, how do you ensure that new start_date is newer than previous end_date? You can't even express that as a primary key. What if you edit start_date later? I would even think to create different compaund key for product_price_history table. Perhaps product_id+insert_date or only auto-increment id, while still keeping foreign key relationship to the products.product_id.

Nenad
  • 24,809
  • 11
  • 75
  • 93
  • @Nick Don't thank people. If this answers your question, then mark it as such so future information seekers can find the "answer" when searching. – SMor Aug 15 '22 at 17:37