Рефакторинг внешнего ключа к полям

В 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 ответа

Решение

Прежде всего: кажется, что ваше изменение идет не в ту сторону. Ваша исходная нормализованная схема обычно лучше. Если вам нужно отобразить магазин / пользователя, создайте VIEW,

Но у вас могут быть свои причины, так что здесь идет:

UPDATE purchases p
SET  (shop, shop_user) = (s.name, s."user")
FROM  shop s
WHERE s.id = p.shop_id;

Вы не должны использовать зарезервированное слово "user" в качестве идентификатора.
И "имя" вряд ли когда-либо будет хорошим именем.
И вряд ли есть веская причина для использования varchar(255) в Postgres (в отличие от SQL Server).

Около varchar(255):

Поэтому мне кажется, что вам не хватает только обновления таблицы покупок, чтобы она содержала информацию из таблицы вашего магазина. Если это правильно, то вы можете просто обновить таблицу, используя существующий внешний ключ, прежде чем ее удалить:

UPDATE purchases SET (shop, shop_user) =
    (SELECT name, user FROM shop
     WHERE shop.id = purchases.shop_id);
Другие вопросы по тегам