这将非常复杂,因为您需要为每个现有的 PK 值生成一个新的 UUID。我建议分几个步骤进行:
- 为每个表添加一个
uuid 列(请不是 varchar!)作为非空值,并使用生成uuid 的默认值。
- 为每个“新 pk”列创建唯一索引
- 为那些引用其他表的表创建新的 uuid 类型的 FK 列(还没有 FK)。
- 对于引用刚刚创建的 UUID 的每个表,使用 UPDATE 语句将生成的 PK 值存储在新的 uuid 外键列中
- 删除旧的主键和外键约束
- 使用
using index 选项重新创建主键,指定在步骤 2 中创建的唯一索引
- 重新创建指向新 uuid 列的外键
- 删除旧的数字(pk 和 fk)列
- 将新列重命名为旧列的名称
类似于以下内容:
设置示例表并插入数据:
create table one (id integer primary key);
create table two (id integer primary key);
create table three (id integer primary key, one_id integer references one);
create table four (id integer primary key, two_id integer references two);
create table five (id integer primary key, three_id integer references three);
insert into one values (1),(2),(3);
insert into two values (10),(20),(30);
insert into three (id, one_id) values (100,1),(200,2),(300,3);
insert into four (id, two_id) values (1000, 10), (2000, 20), (3000, 30);
insert into five (id, three_id) values (10000, 100), (20000, 200), (30000, 300);
添加新的uuid 列并通过默认值填充新的PK 列。
alter table one
add column new_id uuid not null default uuid_generate_v4();
create unique index one_new_pkey on one (new_id);
alter table two add column new_id uuid not null default uuid_generate_v4();
create unique index two_new_pkey on two (new_id);
alter table three add column new_id uuid not null default uuid_generate_v4(),
add column new_one_id uuid;
create unique index three_new_pkey on three (new_id);
alter table four add column new_id uuid not null default uuid_generate_v4(),
add column new_two_id uuid;
create unique index four_new_pkey on four (new_id);
alter table five add column new_id uuid not null default uuid_generate_v4(),
add column new_three_id uuid;
create unique index five_new_pkey on five(new_id);
使用生成的 ID 更新新的外键列
update three
set new_one_id = one.new_id
from one
where one.id = three.one_id;
update four
set new_two_id = two.new_id
from two
where two.id = four.two_id;
update five
set new_three_id = three.new_id
from three
where five.three_id = three.id;
替换旧的主键(删除任何外键)
alter table one drop constraint one_pkey cascade;
alter table one add primary key using index one_new_pkey;
alter table two drop constraint two_pkey cascade;
alter table two add primary key using index two_new_pkey;
alter table three drop constraint three_pkey cascade;
alter table three add primary key using index three_new_pkey;
alter table four drop constraint four_pkey cascade;
alter table four add primary key using index four_new_pkey;
alter table five drop constraint five_pkey cascade;
alter table five add primary key using index five_new_pkey;
创建新的外键
alter table three add constraint fk_three_one
foreign key (new_one_id)
references one;
alter table four add constraint fk_four_two
foreign key (new_two_id)
references two;
alter table five add constraint fk_five_three
foreign key (new_three_id)
references three;
摆脱不再需要的旧列
alter table one drop column id;
alter table one rename column new_id to id;
alter table two drop column id;
alter table two rename column new_id to id;
alter table three drop column id, drop column one_id;
alter table three rename column new_id to id;
alter table three rename column new_one_id to one_id;
alter table four drop column id, drop column two_id;
alter table four rename column new_id to id;
alter table four rename column new_two_id to two_id;
alter table five drop column id, drop column three_id;
alter table five rename column new_id to id;
alter table five rename column new_three_id to three_id;
如果您有一致的命名约定,则可以使用动态 SQL 自动执行此操作