#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 записей — вероятно, есть хороший способ пакетной загрузки обновлений.