简体   繁体   中英

Postgres unique combination constraint across tables

I have three tables -

file (
  file_id int primary key
  filename text not null
  etc...
)
product (
  product_id int primary key
  etc....
)
product_attachment (
  product_id references product
  file_id references file
)

I want to ensure that when these are natural-joined, product_id + filename is unique. The best solution I have so far involves adding filename to the product_attachment table, but I'm wondering if there's a way to avoid that.

If the filename column is not unique you can add a custom constraint on your product_attachment table. Note that this will execute the query below on every insert and update, which is not ideal performance wise.

CREATE OR REPLACE FUNCTION check_filename(product_id integer, file_id integer)
RETURNS boolean AS
$$
    LOCK product_attachment IN SHARE MODE;
    SELECT (COUNT(*) = 0)
    FROM product_attachment pa
    JOIN file f1 ON f1.file_id = pa.file_id
    JOIN file f2 ON f1.filename = f2.filename
    WHERE pa.product_id = $1 AND f2.file_id = $2
$$
LANGUAGE 'plpgsql'

ALTER TABLE product_attachment
ADD CONSTRAINT check_filename CHECK
(check_filename(product_id, file_id))

Why not just add a unique constraint to product_attachment ?

create unique index idx_product_attachment_2 on product_attachment(product_id, file_id);

This assumes that the file name is unique, which you can ensure by defining the file name to be unique in that table.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM