重构字段的外键

时间:2014-07-03 16:09:18

标签: sql postgresql database-design foreign-keys

在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;

所以开始和结束很容易,有人可以帮助中间部分吗? :)

我知道外键是为此制作的,但我必须这样做。

2 个答案:

答案 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);