-- Author: fruit.com.cn -- -- S0 主键改雪花 · 存量库迁移(PostgreSQL 18) -- -- 背景:第一阶段建表用的是 GENERATED BY DEFAULT AS IDENTITY(数据库自增序列), -- 这会让 ID 分配集中在单库的序列上,一旦分库分表就无法横向扩展。 -- S0 把主键改成应用侧雪花 ID(MyBatis-Plus IdType.ASSIGN_ID), -- DDL 侧只需要把 identity 去掉——序列不再需要。 -- -- 本脚本只做一件事:把所有 identity 列改成普通 BIGINT(**保留已有数据,不重建表**)。 -- 刻意不用 DROP TABLE / TRUNCATE,避免误伤存量数据。 -- 幂等:已经迁移过的库再跑一遍不做任何改动,NOTICE 里的数字会是 0。 -- -- 执行:psql -h 127.0.0.1 -U fruitshorts -d fruitshorts -f sql/migrate-s0-snowflake.sql -- 复查:脚本末尾的注释 SQL(改写后应返回 0 行) DO $$ DECLARE r record; v_done int := 0; BEGIN -- relispartition = false 表示"只处理顶层表": -- 分区父表在 pg_class 里 relkind = 'p',月分区子表 relispartition = true; -- identity 定义在父表上,子表跟着继承,所以逐个改子表是多余的。 FOR r IN SELECT c.oid::regclass AS tbl, a.attname AS col FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace JOIN pg_attribute a ON a.attrelid = c.oid WHERE n.nspname = 'public' AND c.relkind IN ('r', 'p') AND c.relispartition = false AND a.attidentity <> '' AND a.attnum > 0 ORDER BY c.relname LOOP EXECUTE format('ALTER TABLE %s ALTER COLUMN %I DROP IDENTITY IF EXISTS', r.tbl, r.col); v_done := v_done + 1; END LOOP; RAISE NOTICE 'S0 迁移完成:处理 % 个 identity 列(重复执行时为 0)', v_done; END $$; -- 复查用(结果应为 0 行): -- SELECT c.relname, a.attname -- FROM pg_class c -- JOIN pg_namespace n ON n.oid = c.relnamespace -- JOIN pg_attribute a ON a.attrelid = c.oid -- WHERE n.nspname = 'public' AND a.attidentity <> '' -- ORDER BY 1, 2;