Мне нужно импортировать данные из старой базы данных в новую, с немного другой структурой. Например, в старой базе данных есть таблица с записями сотрудников и их руководителей:
CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)
Теперь новая база данных выглядит следующим образом:
CREATE TABLE person (id BIGSERIAL PRIMARY KEY, name TEXT, old_ident TEXT);
CREATE TABLE team (id BIGSERIAL PRIMARY KEY);
CREATE TABLE teammember (person_id BIGINT, team_id BIGINT, role CHAR(1));
То есть вместо простой таблицы сотрудников с именами их руководителей новая (более общая) база данных позволяет создавать группы людей. Сотрудники являются членами с ролью 'e'
, руководители с ролью 's'
.
Вопрос заключается в том, как легко перенести данные employee
в новую структуру, по одной команде на пару сотрудник-руководитель. Например, работники
employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')
должны быть перенесены как
person: (1, 'John', 'abc01'), (2, 'Dave', NULL), (3, 'Kyle', 'abc02'), (4, 'Emily', NULL)
team: (1), (2)
teammember: (1, 1, 'e'), (2, 1, 's'), (3, 2, 'e'), (4, 2, 's')
Я хотел бы рассмотреть вопрос об использовании CTE для изменения данных, сначала включить сотрудников и руководителей, а затем группы из них. Однако CTE может возвращать данные только из вставленной строки таблицы. Таким образом, я не могу сопоставить, кто был руководителем кого.
Единственное решение, которое я вижу, это использование plpgsql
, которое будет просто перебирать данные, удерживать вставленные идентификаторы команды во временной переменной, а затем вставлять соответствующие teammember
строки. Но мне любопытно, есть ли более простые или более элегантные решения.
Там будет примерно от нескольких сотен до нескольких тысяч сотрудников. Хотя в целом это хорошая практика, в моем случае я не хотел бы генерировать новые идентификаторы на основе старых, поскольку старые идентификаторы похожи на строки *.GM2
. Я храню их в old_ident
столбце для справки.
источник
team
котором будет храниться идентификатор человека, для которого была создана команда, решит проблему. Мне все еще интересно, есть ли более элегантное решение (то есть без использования DDL).Ответы:
У вас есть вся информация, необходимая для заполнения новой базы данных из старой 4-мя операторами вставки:
Возможно, вам придется приспособиться к вкусу. Я предполагаю, что employee.ident может быть сопоставлен с person.id, и что ваша СУБД позволяет присваивать значения столбцам с автоматически сгенерированными значениями. За исключением этого, это просто базовый SQL, ничего особенного и, конечно , никаких циклов.
Дополнительный комментарий:
SERIAL
(с его 2 миллиардами возможностей) должно быть много, не нужноBIGSERIAL
.CHECK
илиFOREIGN KEY
ограничения для teammember.role? Возможно, вопрос упростил эти детали.источник
person
таблице.PL / PgSQL сделает эту работу.
источник