在PostgreSQL中我需要重构一个表(Purchases
);它有另一个表的外键(Shop
)。相反,我想要两个以文本方式保持关系的字段。我不能丢失任何信息,表格中已包含数据。
Purchases.shop_id: (long) -- is the field I need to drop
Purchases.shop: (characters) -- will hold the Shop's name
Purchases.shop_user: (characters) -- will hold the Shop's user name.
Shop.id: (long, pk) -- still referenced from Purchases
Shop.name: (characters) -- Shop's name
Shop.user: (characters) -- Shop's user name
因为商店在(name,user)
上是唯一的(或当然是id
),所以需要两个字段。
ALTER TABLE Purchases ADD COLUMN shop CHARACTER VARYING(255);
ALTER TABLE Purchases ADD COLUMN shop_user CHARACTER VARYING(255);
-- ???
ALTER TABLE Purchases DROP CONSTRAINT shop_id_fk;
ALTER TABLE Purchases DROP COLUMN shop_id;
所以开始和结束很容易,有人可以帮助中间部分吗? :)
我知道外键是为此制作的,但我必须这样做。
答案 0 :(得分:3)
首先:你的改变似乎走错了路。您原始的规范化架构通常更优越。如果您需要显示商店/用户,请创建VIEW
。
但是你可能有你的理由,所以这里有:
UPDATE purchases p
SET (shop, shop_user) = (s.name, s."user")
FROM shop s
WHERE s.id = p.shop_id;
您不应该使用reserved word "user"
作为标识符
并且"名称"也不是一个好名字。
并且在Postgres中使用varchar(255)
几乎没有充分的理由(与SQL Server不同)。
varchar(255)
答案 1 :(得分:0)
因此,在我看来,您缺少的部分只是更新您的购买表以包含商店表中的信息。如果这是正确的,那么您可以在删除之前使用现有外键更新表:
UPDATE purchases SET (shop, shop_user) =
(SELECT name, user FROM shop
WHERE shop.id = purchases.shop_id);