Muszę zaimportować dane ze starej bazy danych do nowej, o nieco innej strukturze. Na przykład w starej bazie danych znajduje się tabela rejestrująca pracowników i ich przełożonych:
CREATE TABLE employee (ident TEXT PRIMARY KEY, name TEXT, supervisor_name TEXT)
Nowa baza danych wygląda następująco:
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));
Oznacza to, że zamiast prostej tabeli pracowników z nazwiskami ich przełożonych, nowa (bardziej ogólna) baza danych umożliwia tworzenie zespołów ludzi. Pracownicy są członkami z rolą 'e'
, przełożeni z rolą 's'
.
Pytanie brzmi, jak łatwo migrować dane employee
do nowej struktury, po jednym zespole na parę pracowników i przełożonych. Na przykład pracownicy
employee: ('abc01', 'John', 'Dave'), ('abc02', 'Kyle', 'Emily')
mają być migrowane jako
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')
Rozważałbym zastosowanie CTE modyfikującego dane, najpierw umieszczając pracowników i przełożonych, a następnie zespoły. CTE może jednak zwracać dane tylko z wstawionego wiersza tabeli. Dlatego nie jestem w stanie dopasować, kto był przełożonym.
Jedyne rozwiązanie, jakie widzę, to użycie plpgsql
, które po prostu iteruje dane, przechowuje wstawione identyfikatory zespołów w zmiennej tymczasowej, a następnie wstawia odpowiednie teammember
wiersze. Ale jestem ciekawy, czy istnieją prostsze czy bardziej eleganckie rozwiązania.
Będzie około kilkuset do kilku tysięcy pracowników. Chociaż ogólnie jest to dobra praktyka, w moim przypadku nie chciałbym generować nowych identyfikatorów na podstawie starych, ponieważ stare identyfikatory są ciągami *.GM2
. Przechowuję je w old_ident
kolumnie w celach informacyjnych.
źródło
team
którego będzie przechowywany identyfikator osoby, dla której zespół został utworzony, rozwiązałoby problem. Nadal jestem ciekawy, czy istnieje bardziej eleganckie (tj. Bez użycia DDL) rozwiązanie.Odpowiedzi:
Masz wszystkie informacje potrzebne do zapełnienia nowej bazy danych ze starej za pomocą 4 instrukcji wstawiania:
Być może będziesz musiał dostosować się do smaku. Zakładam, że pracownik.ident można zmapować na person.id i że Twój system DBMS umożliwia przypisywanie wartości do kolumn z automatycznie wygenerowanymi wartościami. Poza tym jest to tylko podstawowy SQL, nic szczególnego i oczywiście żadnych pętli.
Dodatkowy komentarz:
SERIAL
(z 2 miliardami możliwości) powinno być dużo, bez potrzebyBIGSERIAL
.CHECK
lubFOREIGN KEY
ograniczenie dla teammember.role? Być może pytanie uprościło te szczegóły.źródło
person
tabeli.PL / PgSQL wykona zadanie.
źródło