由于现在pg的版本,修改int到bigint仍然需要rewrite表,会导致表阻塞,无法使用。但可以考虑其他方式来做。
此问题是排查现网pg使用序列的情况时遇到的。

由于int的最大值只有21亿左右,而且自增列多为主键,当达到最大值时,数据就会无法插入。一般情况是修改类型为bigint,但直接做会锁表,影响现网使用。

这里分两块来看:

1、分区表(修改序列):
对于分区表可以直接修改序列为循环形式,而且最大值设置为int的最大值,因为单个分区表很少会将int值用完。

alter sequence seq_name MAXVALUE 2147483647  CYCLE;

注意这里适用于按日或按月分区的表,对于hash分区表,只能修改字段类型。

2、非分区表(修改为bigint)

由于创建表时,可能使用的是serial,所以此时就需要新建一个序列,不然字段id在删除时,之前的序列也会跟着一同被删除。
下面的步骤中要注意,添加主键约束部分,如果new_id上没有not null约束,则此时会进行全表扫描检查有无not null的记录。虽然pg检查记录是否为not null的操作比较快,但这一步还是会锁较长时间(看记录数多少而定)。

alter table table_name add  column new_id bigint;

---循环更新new_id
do language plpgsql $$
declare
i int;
begin
for i in 0..1000 loop
update table_name set new_id = id where id >= min(id)+ (max(id)-min(id))/1000*i and id< min(id) + max(id)-min(id))/1000*(i+1);
end loop;
end $$; create unique index CONCURRENTLY on table_name(new_id); BEGIN;
ALTER TABLE table_name DROP CONSTRAINT table_name_pkey;
CREATE SEQUENCE table_name_new_id_seq;
ALTER TABLE table_name ALTER COLUMN new_id SET DEFAULT nextval('table_name_new_id_seq'::regclass);
UPDATE table_name SET new_id = id WHERE new_id IS NULL;
ALTER TABLE table_name ADD CONSTRAINT table_name_pkey PRIMARY KEY USING INDEX table_name_pk_idx;
ALTER TABLE table_name DROP COLUMN id;
ALTER TABLE table_name RENAME COLUMN new_id to id;
ALTER SEQUENCE table_name_new_id_seq RENAME TO table_name_id_seq;
SELECT setval('table_name_id_seq', (SELECT max(id) FROM table_name));
COMMIT;

还有可以通过修改数据字典来实现同样操作的,不过不推荐使用,有可能引起元数据损坏。

PostgreSQL 修改字段类型从int到bigint的更多相关文章

  1. 曲演杂坛--使用ALTER TABLE修改字段类型的吐血教训

    --===================================================================== 事件起因:开发发现有表插入数据失败,查看后发现INT类型 ...

  2. Oracle修改字段类型和长度

    Oracle修改字段名 alter table 表名 rename column 旧字段名 to 新字段名 Oracle修改字段类型和长度 alter table 表名 modify 字段名 数据类型 ...

  3. Oracle基本操作,Oracle修改列名,Oracle修改字段类型

    oracle基本操作,Oracle修改列名,Oracle修改字段类型 >>>>>>>>>>>>>>>>& ...

  4. 使用SQL修改字段类型

    修改字段类型步骤: 1.首先需要检查字段约束 2.删除字段约束 3.修改字段类型 4.加上字段约束 --不加这个条件,库中所有默认约束都可以看到 SELECT  a.name AS DFName , ...

  5. SQL语句修改字段类型与第一次SQLServer试验解答

    SQL语句修改字段类型 mysql中 alert table name modify column name type; 例子:修改user表中的name属性类型为varchar(50) alert ...

  6. SQL Server 添加字段,修改字段类型,修改字段名,删除字段

    -- 1.添加字段-- 基本语法alter table 表 add 列名 字段类型 null-- 例:给学生表添加Telephone字段并指定类型为vachar,长度为50,可空alter table ...

  7. sqlServer 2008修改字段类型和重命名字段名称的sql语句

    sqlServer 2008修改字段类型和重命名字段名称的sql语句 //修改字段的类型 alter table fdi_news alter column c_author nvarchar(50) ...

  8. Oracle/SQL 修改字段类型和长度

    标准SQL修改字段类型和长度语句: ALTER TABLE tableName modify column columnName 类型;例如Mysql的修改字段类型语句:alter table tes ...

  9. Mysql字段操作—增加字段、删除字段、修改字段名、修改字段类型(约束条件)

    1.增加字段:    alter table   tablename    add   new_field_id   type   not null default '0';     例:     a ...

随机推荐

  1. RabbitMQ理论部分

    概念 queue        队列 exchange   交换机 bind          绑定 channel     通道 一个发送消息流程包含上述四个概念.消息经过channel传递给exc ...

  2. 元素transform: rotate()之后,元素宽高该怎么计算?

    通常,利用transform: rotate()元素之后,我们并不会去在意元素大小的变化,因为看上去并没有什么变化.虽然看上去没有变化,其实是有变化的.下面用一个例子来说明一下. html: < ...

  3. C++ 类 复制构造函数 The Copy Constructor

    一.复制构造函数的定义 复制构造函数是一种特殊的构造函数,具有一般构造函数的所有特性.复制构造函数创建一个新的对象,作为另一个对象的拷贝.复制构造函数只含有一个形参,而且其形参为本类对象的引用.复制构 ...

  4. Task 10 统计从1到某个整数之间出现的1的次数

    任务:给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 写一个函数 f(N) ,返回1 到 N 之间出现的 “1”的个数.例如 f(12) = 5. 在3 ...

  5. java读取properties文件的几种方法

    一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取 Properties p=new Properties(); ...

  6. C++自学及C的补缺

    我这个寒假可以坐在电脑前的时间算是比较少的,因为我放假不久后就去打工了,而打工的时间是很流动的,所以我无法固定时间来学习,因此我只能根据我的打工时间来安排我的学习. 由于我的书是除夕前夕淘宝的,近期是 ...

  7. HTML和CSS <h1> --3-- <h1>

    标签语义化,让网页更好的被搜索引擎理解 标签的用途:我们学习网页制作时,常常会听到一个词,语义化.那么什么叫做语义化呢,说的通俗点就是:明白每个标签的用途(在什么情况下使用此标签合理)比如,网页上的文 ...

  8. 使用java开发微信公众平台(1)

    目录 开发服务器 域名验证 获取access_token 自定义菜单 个人账号不能定义url访问服务器,使用测试号就不用认证添加url了,进入公众平台测试账号 开发服务器 域名验证 进入公众平台测试账 ...

  9. 使用Fabric自动化你的任务

    Fabric是一个Python库,可以通过SSH在多个host上批量执行任务.你可以编写任务脚本,然后通过Fabric在本地就可以使用SSH在大量远程服务器上自动运行.这些功能非常适合应用的自动化部署 ...

  10. JDBC连接数据库代码和步骤

    JDBC连接数据库 创建一个以JDBC连接数据库的程序,包含7个步骤: 1.加载JDBC驱动程序  在连接数据库之前,首先要加载想要连接的数据库的驱动,这通过java.lang.Class类的静态方法 ...