华山论剑之 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_newRENAME 回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 相关参数主要分为三大类. 第一类 与资源相关参数 #--------------- ...
随机推荐
- C++ 微信多开
应用是如何判断多开 一.通过查找窗口标题或者类名来判断程序是否正在运行. 二.通过互斥对象确定程序是否运行,大多数软件都是使用CreateMutexW 判断多开的. 三.内存映射物理文件,控制多开. ...
- Ubuntu 18.04 安装教程
准备材料 Ubuntu安装U盘 足够的硬盘空间 未初始化的硬盘需要提前初始化 注意事项 Ubuntu安装盘的制作请参考我的另外一个博客,里面写清楚了怎么制作Ubuntu安装盘,步骤非常简单 请将要拿给 ...
- Activity 不只有跳转。功能篇(一)
Activity生命周期 1:activity四种启动方式 standard,SingleTask,SingleTop,SingleInstance standard:是系统默认的,每次启动该acti ...
- Android App发布遇到的问题总结【转】
感谢大佬:https://www.cnblogs.com/jeffen/p/6824722.html 问题描述(v1和v2) Android 7.0中引入了APK Signature Scheme ...
- 快速搭建ELK7.5版本的日志分析系统--搭建篇
title: 快速搭建ELK7.5版本的日志分析系统--搭建篇 一.ELK安装部署 官网地址:https://www.elastic.co/cn/ 官网权威指南:https://www.elastic ...
- Copy as Markdown - 将页面链接按照 Markdown 格式copy
将页面文字和链接组成 Markdown 格式的网址 直接对页面链接右键使用时,无法获取链接标题,只能显示 No Title 所以需要: 选中「想作为标题的部分文字」, 然后去对「页面链接」右键-> ...
- 性能测试之监控--zabbix通过jmx监控tomcat
前提: 已经安装好了zabbix server 实验环境 Centos 7 Zabbix 3.0 Tomcat 7.0 JDK 1.8 安装JDK tar -zxvf jdk-8u181-linux- ...
- Java线程--CompletionService使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871911.html Java线程--CompletionService使用 public ...
- Shell条件练习题
Shell条件练习题 目录 Shell条件练习题 1.检查用户家目录中的 test.sh 文件是否存在,并且检查是否有执行权限 2.提示用户输入100米赛跑的秒数,要求判断秒数大于0且小于等于10秒的 ...
- SpringDataJpa打印Sql详情(含参数)
Spring Data Jpa打印Sql详情(带sql参数) 这里使用的是 log4jdbc,yml配置文件里的数据源配置也要做相应的修改 pom文件引入 <dependency> < ...