Postgres跨表的唯一组合约束

时间:2014-07-23 12:08:08

标签: sql postgresql foreign-keys unique-constraint

我有三张桌子 -

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
)

我想确保当这些是自然连接时,product_id + filename是唯一的。 到目前为止,我所拥有的最佳解决方案是将文件名添加到product_attachment表中,但我想知道是否有办法避免这种情况。

2 个答案:

答案 0 :(得分:3)

如果文件名列不唯一,您可以在product_attachment表上添加自定义约束。请注意,这将在每次插入和更新时执行以下查询,这不是理想的性能。

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

答案 1 :(得分:0)

为什么不向product_attachment添加唯一约束?

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

这假定文件名是唯一的,您可以通过在该表中定义文件名是唯一的来确保文件名。