华山论剑之 PostgreSQL sequence (二)
rename 对 sequence 的影响
关联列与 sequence 后,即 sequence 属于该列后,drop 表或列时会自动 drop 相关 sequence。
但如果对表或列 rename 后,甚至 rename sequence后,会发生什么呢?
我们来做一下实验。
创建测试表 tb_test_sequence_rename
alvindb=>
CREATE TABLE tb_test_sequence_rename (
test_id BIGSERIAL PRIMARY KEY,
create_time TIMESTAMP DEFAULT clock_timestamp()
);
CREATE TABLE
查看表与 sequence:
alvindb=> \d tb_test_sequence_rename
Table "alvin.tb_test_sequence_rename"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------------
test_id | bigint | | not null | nextval('tb_test_sequence_rename_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_sequence_rename_pkey" PRIMARY KEY, btree (test_id)
alvindb=> \d tb_test_sequence_rename_test_id_seq
Sequence "alvin.tb_test_sequence_rename_test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_sequence_rename.test_id
alvindb=>
对表进行 rename :
alvindb=> ALTER TABLE tb_test_sequence_rename RENAME TO tb_test_sequence_rename2;
ALTER TABLE
通过如下结果,我们可以看到, rename 表后 'Owned by' 也会随之自动变化。
alvindb=> \d tb_test_sequence_rename2
Table "alvin.tb_test_sequence_rename2"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------------
test_id | bigint | | not null | nextval('tb_test_sequence_rename_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_sequence_rename_pkey" PRIMARY KEY, btree (test_id)
alvindb=> \d tb_test_sequence_rename_test_id_seq
Sequence "alvin.tb_test_sequence_rename_test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_sequence_rename2.test_id
alvindb=>
我们再 rename 列试一下,
alvindb=> ALTER TABLE tb_test_sequence_rename2 RENAME test_id TO test_id2;
ALTER TABLE
通过如下结果,我们可以看到, rename 列后 'Owned by' 也会随之自动变化。
alvindb=> \d tb_test_sequence_rename2
Table "alvin.tb_test_sequence_rename2"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------------
test_id2 | bigint | | not null | nextval('tb_test_sequence_rename_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_sequence_rename_pkey" PRIMARY KEY, btree (test_id2)
alvindb=> \d tb_test_sequence_rename_test_id_seq
Sequence "alvin.tb_test_sequence_rename_test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_sequence_rename2.test_id2
alvindb=>
我们来 rename 一下 sequence,
alvindb=> ALTER SEQUENCE tb_test_sequence_rename_test_id_seq RENAME TO tb_test_sequence_rename_test_id_seq2;
ALTER SEQUENCE
通过如下结果,我们可以看到, rename sequence 后 'Owned by' 也会随之自动变化,并且 Default 中的 sequence 也会随之变化。
alvindb=> \d tb_test_sequence_rename2
Table "alvin.tb_test_sequence_rename2"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+-----------------------------------------------------------
test_id2 | bigint | | not null | nextval('tb_test_sequence_rename_test_id_seq2'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_sequence_rename_pkey" PRIMARY KEY, btree (test_id2)
alvindb=> \d tb_test_sequence_rename_test_id_seq2
Sequence "alvin.tb_test_sequence_rename_test_id_seq2"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_sequence_rename2.test_id2
alvindb=>
通过以上三个 rename 实验,可以发现,正常 rename 不会对 sequence 的使用产生影响。
无论是 rename 表名,列名,还是 sequence 的名字,如我们所期望,PostgreSQL 都会智能地作出相应的修改。
复制表或迁移表时 sequence 的相关操作
以下表为例,
alvindb=> \d tb_test_bigserial
Table "alvin.tb_test_bigserial"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------
test_id | bigint | | not null | nextval('tb_test_bigserial_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_bigserial_pkey" PRIMARY KEY, btree (test_id)
alvindb=> \d tb_test_bigserial_test_id_seq
Sequence "alvin.tb_test_bigserial_test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_bigserial.test_id
在一些情况下,为避免 DDL 或大量 DML 对表 tb_test_bigserial
的影响,我们可以通过 RENAME 表的方式实现:
- 根据表
tb_test_bigserial
复制出相同表结构的表tb_test_bigserial_new
- 对
tb_test_bigserial_new
进行 DDL 或 大量 DML - 将
tb_test_bigserial_new
RENAME 回tb_test_bigserial
根据表 tb_test_bigserial
复制出相同表结构的表 tb_test_bigserial_new
:
alvindb=> CREATE TABLE tb_test_bigserial_new (LIKE tb_test_bigserial INCLUDING ALL);
CREATE TABLE
alvindb=> \d tb_test_bigserial_new
Table "alvin.tb_test_bigserial_new"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------
test_id | bigint | | not null | nextval('tb_test_bigserial_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_bigserial_new_pkey" PRIMARY KEY, btree (test_id)
对 tb_test_bigserial_new
进行 DDL 或 大量 DML 后,将 tb_test_bigserial_new
RENAME 回 tb_test_bigserial
:
alvindb=> BEGIN;
BEGIN
alvindb=> ALTER TABLE tb_test_bigserial RENAME TO tb_test_bigserial_old;
ALTER TABLE
alvindb=> ALTER TABLE tb_test_bigserial_new RENAME TO tb_test_bigserial;
ALTER TABLE
alvindb=> END;
COMMIT
这时,查看新表结构:
alvindb=> \d tb_test_bigserial
Table "alvin.tb_test_bigserial"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------
test_id | bigint | | not null | nextval('tb_test_bigserial_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_bigserial_new_pkey" PRIMARY KEY, btree (test_id)
此处,我们只关注 sequence。上述的索引的名字可以根据需要决定是否需要 RENAME 回原来的名字。
查看 sequence,
alvindb=> \d tb_test_bigserial_test_id_seq
Sequence "alvin.tb_test_bigserial_test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_bigserial_old.test_id
从以上 'Owned by' 可以看出,sequence tb_test_bigserial_test_id_seq
还是归旧表 tb_test_bigserial_old
的列所有。
从上文“rename 对 sequence 的影响”我们知道,这是正常的。
此时 DROP 旧表,会提示新表 tb_test_bigserial
还在依赖 sequence tb_test_bigserial_test_id_seq
。
alvindb=> DROP TABLE tb_test_bigserial_old;
ERROR: cannot drop table tb_test_bigserial_old because other objects depend on it
DETAIL: default value for column test_id of table tb_test_bigserial depends on sequence tb_test_bigserial_test_id_seq
HINT: Use DROP ... CASCADE to drop the dependent objects too.
alvindb=>
以下 RENAME 表时关键的一步:
alvindb=> ALTER SEQUENCE tb_test_bigserial_test_id_seq OWNED BY tb_test_bigserial.test_id;
ALTER SEQUENCE
通过上述 SQL,sequence tb_test_bigserial_test_id_seq
就归新表的列所有了。
在日常操作中,我们有可能忘记修改 sequence 的所属关系。以致后来 DROP 老表时加了 CASCADE,将 sequence 也一起 DROP 掉了,从而引发问题。
此时 DROP 表就不报错了:
alvindb=> DROP TABLE tb_test_bigserial_old;
DROP TABLE
以下是 RENAME 后所期望的结果(注意 sequence 的 'Owned by'):
alvindb=> \d tb_test_bigserial
Table "alvin.tb_test_bigserial"
Column | Type | Collation | Nullable | Default
-------------+-----------------------------+-----------+----------+----------------------------------------------------
test_id | bigint | | not null | nextval('tb_test_bigserial_test_id_seq'::regclass)
create_time | timestamp without time zone | | | clock_timestamp()
Indexes:
"tb_test_bigserial_new_pkey" PRIMARY KEY, btree (test_id)
alvindb=> \d tb_test_bigserial_test_id_seq
Sequence "alvin.tb_test_bigserial_test_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
--------+-------+---------+---------------------+-----------+---------+-------
bigint | 1 | 1 | 9223372036854775807 | 1 | no | 1
Owned by: alvin.tb_test_bigserial.test_id
公众号
关注 DBA Daily 公众号,第一时间收到文章的更新。
通过一线 DBA 的日常工作,学习实用数据库技术干货!
公众号优质文章推荐
[PG Upgrade Series] Extract Epoch Trap
[PG Upgrade Series] Toast Dump Error
GitLab supports only PostgreSQL now
华山论剑之 PostgreSQL sequence (二)的更多相关文章
- 华山论剑之 PostgreSQL sequence (一)
前言 本文是 sequence 系列继三大数据库 sequence 之华山论剑 (Oracle PostgreSQL MySQL sequence 十年经验总结) 之后的第二篇,主要分享一下 Post ...
- SpringBoot整合MybatisPlus3.X之Sequence(二)
数据库脚本 DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES (, , 'test1@baomidou.com'), ...
- postgresql【二】postgresql强制删除数据库
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE datname='db_name' AND ...
- 三大数据库 sequence 之华山论剑 (上篇)
前言 本文将基于以下三种关系型数据库,对 sequence (序列) 展开讨论. Oracle - 应用最广泛的商用关系型数据库 PostgreSQL - 功能最强大的开源关系型数据库 MySQL - ...
- PostgreSQL VACUUM 之深入浅出 (二)
AUTOVACUUM AUTOVACUUM 简介 PostgreSQL 提供了 AUTOVACUUM 的机制. autovacuum 不仅会自动进行 VACUUM,也会自动进行 ANALYZE,以分析 ...
- 三大数据库 sequence 之华山论剑 (中篇)
sequence 用法四 AUTO INCREMENT 通过 DEFAULT 还是需要手动创建 sequence.有没有更简单的用法呢? 当然,就是通过 AUTO INCREMENT 方式,自动创建 ...
- 三大数据库 sequence 之华山论剑 (下篇)
MySQL 5.7 MYISAM ENGINE 以下是 MySQL 5.7 MYISAM ENGINE 中的运行结果 mysql> CREATE TABLE tb_test5 ( -> t ...
- PostgreSQL VACUUM 之深入浅出 (一)
前言 VACUUM 是 PostgreSQL MVCC (Multiversion concurrency control) 实现的核心机制之一,是 PostgreSQL 正常运行的重要保证.本文将通 ...
- PostgreSQL VACUUM 之深入浅出 (三)
VACUUM 相关参数 对 VACUUM 有了一定的了解之后,下面系统介绍下 VACUUM 相关参数. VACUUM 相关参数主要分为三大类. 第一类 与资源相关参数 #--------------- ...
随机推荐
- Java架构系列问题合集-目录
接下来会做一个系列, 分类说明关于Java项目研发和架构工作需要了解的问题 Java语法 Java语法专题1: 类初始化的构造顺序 https://www.cnblogs.com/milton/p/1 ...
- synchronized、ReentrantLock、volatile
名词解释 synchronized 是Java中的关键字,是一种同步锁,可以修饰代码块,方法,静态的方法,类.synchronized(Object) 不能用String常量.Integer. Lon ...
- Tomcat启动报错org.apache.catalina.core.StandardContext listenerStart
感谢原文作者:西北码农 原文链接:https://blog.csdn.net/bitree1/article/details/72236633 解决方法: 1.检查配置信息有无异常:如 web.xml ...
- document对象常用属性
转载请注明来源:https://www.cnblogs.com/hookjc/ 注:页面上元素name属性和JavaScript引用的名称必须一致包括大小写 否则会提示你一个错误信息 " ...
- 开源项目(asyncHttpClient) get post 方式提交
get方式: 1 public static void requestNetForGetLogin(final Context context,final Handler handler ,final ...
- Java线程--Phaser使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11867895.html Java线程--Phaser使用, 代码里头有详细注释: packag ...
- 【BZOJ2820】YY的GCD(莫比乌斯反演 数论分块)
题目链接 大意 给定多组\(N\),\(M\),求\(1\le x\le N,1\le y\le M\)并且\(Gcd(x, y)\)为质数的\((x, y)\)有多少对. 思路 我们设\(f(i)\ ...
- 私有化轻量级持续集成部署方案--03-部署web服务(下)
提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 配置接口代理 前后端分离情况下,前端请求后端接口最常用的一种方式就是使用反向代理,反向代理会让浏览器认为是同源路径, ...
- Node 模块规范鏖战:难以相容的 CJS 与 ESM
自 13.2.0 版本开始,Node.js 在保留了 CommonJS(CJS)语法的前提下,新增了对 ES Modules(ESM)语法的支持. 天下苦 CJS 久已,Node 逐渐拥抱新标准的规划 ...
- netty系列之:channel,ServerChannel和netty中的实现
目录 简介 channel和ServerChannel netty中channel的实现 AbstractChannel和AbstractServerChannel LocalChannel和Loca ...