Копировать связанные записи в новые таблицы

#sql #postgresql

#sql #postgresql

Вопрос:

У меня есть четыре таблицы — company_targetables , employee_targetables , employees и users . Я использую Postgresql 9.6.

Схема:

company_targetables

  • id
  • company_id внешний ключ
  • name строка
  • value — строка

employee_targetables

  • id
  • company_targetable_id внешний ключ
  • employee_id внешний ключ

employees
user_id

employee_targetables является соединением между company_targetables и employees .

Я хочу переместить company_targetables и employee_targetables в новые таблицы custom_attributes и user_custom_attributes соответственно, сохранив отношения, но вместо того, чтобы связываться user_custom_attributes с employee, я хочу связать его с user записью с user_id внешним ключом.

Схема для новых таблиц:

custom_attributes :

  • аналогично схеме для company_targetables

user_custom_attributes

  • custom_attribute_id
  • user_id необходимо получить идентификатор пользователя из ассоциированной employee записи из старой таблицы

Например, если у меня есть employee_targetable связанный с company_targetable с идентификатором 1, я могу легко скопировать company_targetable_id , но мне нужно убедиться, что соответствующая custom_attribute запись создана с теми же значениями, что и company_targetable , чтобы значения столбцов в связи были сохранены. Кроме того, я хочу убедиться, что новая user_custom_attribute запись заполняет user_id столбец employees.user_id значением.

В настоящее время я делаю это 1 к 1 — сначала создаю custom_attribute запись, а затем user_id отключаю employee и создаю user_custom_attribute запись, но примерно с 500 000 записей это занимает некоторое время.

Есть ли способ эффективно сделать это?

Комментарии:

1. Я не понимаю проблему. Вы не указали, что какие-либо значения изменяются между новой и старой таблицами. Итак, почему вы не можете просто создать новую custom_attributes таблицу, выполнить INSERT INTO ... SELECT * FROM company_targetable_id , а затем сделать то же самое для user_custom_attributes таблицы? Идентификаторы, на которые ссылаются, останутся одинаковыми для всех таблиц, поэтому вы фактически просто переименовываете таблицы обходным путем. Или есть что-то еще?

2. да, значение меняется, и я должен был указать это — мы меняем employee_id ассоциацию в employee_targetables на user_id в user_custom_attributes . Итак, вместо ссылки на запись о сотрудниках мне нужно ссылаться на запись пользователя (сотрудники связаны с пользователями с user_id столбцом в таблице employees.

Ответ №1:

Вот что я придумал

Сначала скопируйте все, начиная с company_targetables и заканчивая custom_attributes:

       INSERT INTO custom_attributes(id, name, value, targetable, company_id, created_at, updated_at)
  SELECT company_targetables.id, company_targetables.name, company_targetables.value, 't',
         company_targetables.company_id, company_targetables.created_at, company_targetables.updated_at
  FROM company_targetables
  

И затем все из employee_targetables в user_custom_attributes, присоединяясь к employees, чтобы я мог заполнить user_id столбец:

       INSERT INTO user_custom_attributes(id, custom_attribute_id, user_id, created_at, updated_at)
  SELECT employee_targetables.id, employee_targetables.company_targetable_id, employees.user_id,
         employee_targetables.created_at, employee_targetables.updated_at
  FROM employee_targetables
  INNER JOIN employees ON employees.id = employee_targetables.employee_id
  

Потребовалось 22 секунды для примерно 500 000 записей — вероятно, есть хороший способ пакетной загрузки обновлений.