我需要将数据从旧数据库导入到新数据库,结构稍有不同。例如,在旧数据库中,有一个表记录员工及其主管:
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
,它将简单地遍历数据,将插入的团队ID保留在临时变量中,然后插入适当的teammember
行。但是我很好奇是否有更简单或更优雅的解决方案。
大约会有数百到数千名员工。尽管通常这是一个好习惯,但就我而言,我不希望基于旧ID生成新ID,因为旧ID是类似的字符串*.GM2
。我将它们存储到该old_ident
列中以供参考。
3
我建议将一些临时标识符添加到新表中。这样,您可以在仍保持旧连接的同时向其中插入数据-然后您可以从旧表中获取必要的行,并将其插入下一个表中,依此类推。为此,我将使用单独的SQL语句,不需要复杂的CTE或过程函数。
—
dezso
@dezso感谢您的建议。添加一个临时标识符以
—
的Ondrej布达
team
保存创建团队的人员的ID将解决此问题。不过,我仍然很好奇是否有一个更优雅的解决方案(即不使用DDL)。
@OndřejBouda可以将表构建为CTE查询,但是很快就会变得非常复杂。(temp)表解决方案使您可以例如通过检查行数来单独测试步骤。
—
dezso 2015年