天天看点

如何优雅的ALTER被引用的TABLE

PostgreSQL , 视图 , 表 , alter table , 修改字段属性

在修改数据库表字段的长度时,数据库提供了alter table的语法进行修改。

但是被修改的字段如果有其他引用(例如视图)时,必须先将引用的对象删除,再修改对应的字段。

例子如下

PostgreSQL支持将DDL语句封装在事务中处理,所以从删除依赖,到修改字段,再到重建依赖,都可以封装在一个事务中完成。

1. DDL是需要对表加排它锁的,排它锁与所有其他锁冲突,因此建议在事务开始时设置锁超时参数,避免问题。

2. 如果修改字段涉及到rewrite table(例如int改到text),那么表很大时间会很久。如果需要很久,意味着需要长时间持有排它锁(堵塞也是比较严重的)。

PostgreSQL的定义都记录在元数据中,所以某些操作,可以直接修改元数据来实现。比如从numeric低精度修改到高精度,从字符串短长度修改到长长度。

不建议这么做,直接修改元数据存在隐患,甚至可能对数据库造成不可修复的伤害。

首先要查看将要修改的C1字段的pg_attribute元信息

在修改时,需要将这三个atttypmod一起修改掉。

变长字段的长度为4字节头+实际长度,所以36表示可以存储32个字符。

修改为varchar(64)这样操作

更新后,可以看到结构发生了变化.

<a href="https://github.com/digoal/blog/blob/master/201504/20150410_01.md">《如何比较PostgreSQL表的定义》</a>

<a href="https://github.com/digoal/blog/blob/master/201306/20130617_01.md">《PostgreSQL 9.0 modify pg_attribute.atttypmod extend variable char length avoid rewrite table》</a>

<a href="https://github.com/digoal/blog/blob/master/201308/20130823_01.md">《PostgreSQL WHY modify numeric scale must rewrite table》</a>

<a href="https://github.com/digoal/blog/blob/master/201308/20130817_01.md">《PostgreSQL How can i decode the NUMERIC precision and scale in pg_attribute.atttypmod》</a>