SQL外键数组引用非数组

时间:2014-04-28 01:47:29

标签: sql postgresql

CREATE TABLE orders (
   id          SERIAL PRIMARY KEY,
   productid   INTEGER[] NOT NULL,
   amount      INTEGER[] NOT NULL,
   totalprice   FLOAT NOT NULL,
   ordertime    TIMESTAMP NOT NULL,
   FOREIGN KEY (productid) REFERENCES products(id)
);

我试图创建一个表来记录订单。由于那个订单可能包含多个产品,我计划使用数组来记录每个产品的产品,同样数量的产品。但是当我想让productid成为引用表产品的id属性的外键时,我发现productid是一个数组,但是products(id)只是一个数字。如何解决这个问题,使productid数组的每个元素都引用产品(id)?我正在使用postgresql btw。

谢谢adhead!

3 个答案:

答案 0 :(得分:5)

目前PostgreSQL不支持外键数组。

支持PostgreSQL 9.4,但性能和实施质量问题导致其从发布中被删除。它可能会在将来的版本中添加,也可能不会添加。从9.6开始,我看不到有人在做这件事。

不能使用CHECK约束,因为它们不支持子查询,FROM子句或对其他表中列的引用。虽然可以通过编写一个隐藏其他表的查询的函数来欺骗解析器,然后使用CHECK表达式中的函数,但这个不正确并且无法可靠地工作

我强烈建议对表进行规范化,因此您使用多个单独的记录而不是数组。

答案 1 :(得分:1)

我认为要解决这个问题,您可以使用表格来实现" order"和#34;产品"

的另一个表格

如果他们之间的关系是:很多人把外国钥匙放在"产品"表 然而,似乎关系很多:很多,所以创建一个新表" order-product" 具有来自其他两个表的两个键。

答案 2 :(得分:1)

Postgres不支持int []的外键约束。但是,您可以使用触发器来帮助自动强制执行约束。以下是删除产品时更新订单的示例:

CREATE FUNCTION remove_product() RETURNS TRIGGER as $_$                                
BEGIN                                                                                
  UPDATE orders                                                                 
  SET topic_id=array_remove(products, OLD.id)                                  
  WHERE products @> ARRAY[OLD.topic_id];                                             
  RETURN NEW;                                                                        
END;                                                                                 
$_$ LANGUAGE plpgsql;                                                              

create trigger R               
after delete on products
for each row
execute procedure remove_product();