Jak*_*yle 4 postgresql query primary-key
我的 postgres 数据库有一个名为“id”的列,其范围从 40,000,000 到大约 50,000,000。“id”列是主键。我需要更改“id”列值,使它们跨越不同的数字,以便将此数据库与另一个数据库合并。
我如何生成代码以将值从 40,000,000 - 50,000,000 更改为 0 - 10,000,000?
表的定义是
CREATE TABLE public.keyvaluehistory (
id bigint NOT NULL
DEFAULT nextval('keyvaluehistory_id_seq'::regclass),
segkey text NOT NULL,
dvalue double precision,
bvalue bytea,
tstamp timestamp with time zone,
CONSTRAINT keyvaluehistory_pkey PRIMARY KEY (id)
);
Run Code Online (Sandbox Code Playgroud)
表上没有外键。
我可以承受几分钟/几小时的停机时间。
我会暂时添加另一列。
第一部分可以在数据库处于活动状态时运行:
ALTER TABLE keyvaluehistory ADD new_id bigint;
CREATE SEQUENCE keyvaluehistory_new_id_seq OWNED BY keyvaluehistory.new_id;
/* update in batches to avoid table bloat */
UPDATE keyvaluehistory SET new_id = id - 39999999
WHERE id BETWEEN 40000000 AND 40999999;
VACUUM keyvaluehistory;
UPDATE keyvaluehistory SET new_id = id - 39999999
WHERE id BETWEEN 41000000 AND 41999999;
VACUUM keyvaluehistory;
...
SET maintenance_work_mem = '1GB';
CREATE UNIQUE INDEX CONCURRENTLY keyvaluehistory_new_pkey (new_id);
Run Code Online (Sandbox Code Playgroud)
接下来的部分会锁定表并需要停机时间。
最耗时的部分是添加主键,因为这需要扫描表。
/* downtime starts here */
BEGIN;
LOCK TABLE keyvaluehistory IN ACCESS EXCLUSIVE MODE;
/* catch up */
UPDATE keyvaluehistory SET new_id = id - 39999999
WHERE new_id IS NULL;
ALTER TABLE keyvaluehistory
DROP CONSTRAINT keyvaluehistory_pkey;
ALTER TABLE keyvaluehistory
DROP COLUMN id;
ALTER TABLE keyvaluehistory
ADD CONSTRAINT keyvaluehistory_pkey USING keyvaluehistory_new_pkey;
ALTER INDEX keyvaluehistory_new_pkey RENAME TO keyvaluehistory_pkey;
ALTER TABLE keyvaluehistory RENAME new_id TO id;
ALTER SEQUENCE keyvaluehistory_new_id_seq RENAME TO keyvaluehistory_id_seq;
SELECT setval('keyvaluehistory_new_id_seq', 10000001);
COMMIT;
Run Code Online (Sandbox Code Playgroud)
请在生产环境中运行之前进行测试;我可能忘记了什么。