alter table add column foo; create table foo ( row_version integer not null default 0 id integer not null unique; ); create table foo_eav ( id integer not null unique; recno integer not null references foo (id); name varchar(32) not null; value varchar(32); ); -- add a column to foo and move all fields named "bar" into that field alter table foo add colum bar varchar(32); -- row_version 1 update foo rec set foo.bar = eav.value , foo.row_version = 1 join foo_eav eav on (foo.id = foo_eav.recno) where eav.name = 'bar' and foo.row_version = 0 -- this can be done incrementally -- your program should write its schema version for the row to the DB -- move column "bar" back to the EAV store insert into rec select foo.id as recno , 'bar' as name , foo.bar as value where foo.row_version = 1; update foo rec set foo.row_version = 2; -- if there are no more rows with version < 2, we can drop the column "bar" -- retrieve rows select id , foo.row_version , case when foo.row_version = 1 then foo.bar else foo_bar.bar end as bar from foo left join foo_eav foo_bar on foo.id = foo_eav.recno and foo_eav.name = 'bar'