Postgres unique combination constraint across tables

陌路散爱 提交于 2021-02-05 07:45:26

问题


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.


回答1:


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))



回答2:


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.



来源:https://stackoverflow.com/questions/24910113/postgres-unique-combination-constraint-across-tables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!