如何优雅的ALTER被引用的TABLE

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
简介:

标签

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


背景

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

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

例子如下

测试表  
postgres=# create table test_t (id int, info text, crt_time timestamp, c1 varchar(10));  
CREATE TABLE  
  
被修改字段上建立索引  
postgres=# create index idx_test_t on test_t(c1);  
CREATE INDEX  
  
被修改字段上建立视图  
postgres=# create view v_test_t as select id,c1 from test_t;  
CREATE VIEW  
  
修改字段的长度报错  
postgres=# alter table test_t alter column c1 type varchar(32);  
ERROR:  cannot alter type of a column used by a view or rule  
DETAIL:  rule _RETURN on view v_test_t depends on column "c1"  

优雅的修改被视图引用的表字段

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

注意

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

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

例子

begin;  -- 开始事务  
  
set local lock_timeout = '1s';  -- 设置锁超时  
  
drop view v_test_t;  -- 删除依赖视图  
  
alter table test_t alter column c1 type varchar(32);  -- 修改字段长度  
  
create view v_test_t as select id,c1 from test_t;  -- 创建视图  
  
end;  -- 结束事务  

hack PostgreSQL pg_attribute元数据的修改方法

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

注意

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

例子

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

视图、索引、表 在pg_attribute中都有对应的元信息,如下  
  
postgres=# select attrelid::regclass,* from pg_attribute where attname='c1';  
  attrelid  | attrelid | attname | atttypid | attstattarget | attlen | attnum | attndims | attcacheoff | atttypmod | attbyval | attstorage | attalign | attnotnull | atthasdef | attidentity | attisdropped | attislocal | attinhcount | attcollation | attacl | attoptions | attfdwoptions   
------------+----------+---------+----------+---------------+--------+--------+----------+-------------+-----------+----------+------------+----------+------------+-----------+-------------+--------------+------------+  
  
 test_t     |    21988 | c1      |     1043 |            -1 |     -1 |      4 |        0 |          -1 |        36 | f        | x          | i        | f          | f         |             | f            | t          |           0 |          100 |        |            |   
 v_test_t   |    21998 | c1      |     1043 |            -1 |     -1 |      2 |        0 |          -1 |        36 | f        | x          | i        | f          | f         |             | f            | t          |           0 |          100 |        |            |   
 idx_test_t |    22002 | c1      |     1043 |            -1 |     -1 |      1 |        0 |          -1 |        36 | f        | x          | i        | f          | f         |             | f            | t          |           0 |          100 |        |            |   
(6 rows)  

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

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

修改为varchar(64)这样操作

postgres=# update pg_attribute set atttypmod=68 where attname='c1' and attrelid in (21988,21998,22002);  
UPDATE 3  

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

postgres=# \d+ test_t  
                                              Table "public.test_t"  
  Column  |            Type             | Collation | Nullable | Default | Storage  | Stats target | Description   
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------  
 id       | integer                     |           |          |         | plain    |              |   
 info     | text                        |           |          |         | extended |              |   
 crt_time | timestamp without time zone |           |          |         | plain    |              |   
 c1       | character varying(64)       |           |          |         | extended |              |   
Indexes:  
    "idx_test_t" btree (c1)  
  
postgres=# \d+ v_test_t  
                                  View "public.v_test_t"  
 Column |         Type          | Collation | Nullable | Default | Storage  | Description   
--------+-----------------------+-----------+----------+---------+----------+-------------  
 id     | integer               |           |          |         | plain    |   
 c1     | character varying(64) |           |          |         | extended |   
View definition:  
 SELECT test_t.id,  
    test_t.c1  
   FROM test_t;  
  
postgres=# \d+ idx_test_t   
               Index "public.idx_test_t"  
 Column |         Type          | Definition | Storage    
--------+-----------------------+------------+----------  
 c1     | character varying(64) | c1         | extended  
btree, for table "public.test_t"  

参考

《如何比较PostgreSQL表的定义》

《PostgreSQL 9.0 modify pg_attribute.atttypmod extend variable char length avoid rewrite table》

《PostgreSQL WHY modify numeric scale must rewrite table》

《PostgreSQL How can i decode the NUMERIC precision and scale in pg_attribute.atttypmod》

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
8月前
|
数据采集 资源调度 监控
数字化转型的关键工具:甘特图的应用与优势
在数字化转型浪潮中,企业面临复杂的项目规划、资源分配不均、进度监控困难等挑战。甘特图作为一种经典项目管理工具,通过任务可视化、资源优化、实时监控和跨部门协作等功能,助力企业高效应对这些难题,推动智能化、数据化变革。本文深入探讨甘特图的应用价值及其在制造业、零售业和金融业的实际案例,帮助企业顺利完成数字化转型。
215 12
数字化转型的关键工具:甘特图的应用与优势
|
10月前
|
开发工具 git
git分支管理master/hotfix/develop/feature/release
采用合理的Git分支管理模型可以显著提升团队协作效率和代码管理的质量。本文介绍的 `master`、`develop`、`feature`、`release`和 `hotfix`分支模型是一个行之有效的方法,适用于大多数软件开发项目。通过清晰地划分各个分支的职责,团队成员可以更专注于各自的开发任务,同时确保代码库的稳定性和可维护性。
794 2
|
SQL Java 数据库连接
Hibernate 批量操作来袭!掌握最佳实践,轻松应对数据洪流,开启高效开发新时代
【9月更文挑战第3天】在软件开发中,高效数据操作至关重要。作为流行的Java持久化框架,Hibernate提供了强大的数据库操作功能。本文探讨了Hibernate批量操作,包括批量插入、更新和删除的最佳实践,通过使用原生SQL和`Session`的`createNativeQuery()`方法,结合`addBatch()`及`executeBatch()`方法实现高效批量操作。合理设置批量大小、事务管理和性能测试是优化的关键。在实际开发中,应根据业务需求和性能要求选择合适的方法,以提升程序性能和可维护性。
632 3
|
Oracle 关系型数据库
Oracle 19c OCP 认证考试 082 题库(第20题)- 2024年修正版
这是2024年修正版的Oracle 19c OCP认证题库,包含1Z0-082科目共90题,通过分数为60%,考试时间为150分钟。本文由CUUG原创整理,解析了题库中的第20题,并解释了实体关系相关概念。获得OCP认证需通过082和083两门考试。
193 1
|
存储 监控 关系型数据库
MySQL普通表转换为分区表实战指南
MySQL普通表转换为分区表实战指南
|
存储 机器学习/深度学习 数据可视化
Python面板时间序列数据预测:格兰杰因果关系检验Granger causality test药品销售实例与可视化
Python面板时间序列数据预测:格兰杰因果关系检验Granger causality test药品销售实例与可视化
|
机器学习/深度学习 缓存 安全
基础了解:系统大页
基础了解:系统大页
218 0
|
SQL 关系型数据库 PostgreSQL
|
Web App开发 JavaScript 前端开发
html img Src base64 图片显示
大家可能注意到了,网页上有些图片的src或css背景图片的url后面跟了一大串字符。 比如:data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAA...
4967 0