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 表的方式实现:

  1. 根据表 tb_test_bigserial 复制出相同表结构的表 tb_test_bigserial_new
  2. 对 tb_test_bigserial_new 进行 DDL 或 大量 DML
  3. 将 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 的日常工作,学习实用数据库技术干货!

公众号优质文章推荐

PostgreSQL VACUUM 之深入浅出

华山论剑之 PostgreSQL sequence

[PG Upgrade Series] Extract Epoch Trap

[PG Upgrade Series] Toast Dump Error

GitLab supports only PostgreSQL now

MySQL or PostgreSQL?

PostgreSQL hstore Insight

ReIndex 失败原因调查

PG 数据导入 Hive 乱码问题调查

PostGIS 扩展创建失败原因调查

华山论剑之 PostgreSQL sequence (二)的更多相关文章

  1. 华山论剑之 PostgreSQL sequence (一)

    前言 本文是 sequence 系列继三大数据库 sequence 之华山论剑 (Oracle PostgreSQL MySQL sequence 十年经验总结) 之后的第二篇,主要分享一下 Post ...

  2. SpringBoot整合MybatisPlus3.X之Sequence(二)

    数据库脚本 DELETE FROM user; ​ INSERT INTO user (id, name, age, email) VALUES (, , 'test1@baomidou.com'), ...

  3. postgresql【二】postgresql强制删除数据库

    SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE datname='db_name' AND ...

  4. 三大数据库 sequence 之华山论剑 (上篇)

    前言 本文将基于以下三种关系型数据库,对 sequence (序列) 展开讨论. Oracle - 应用最广泛的商用关系型数据库 PostgreSQL - 功能最强大的开源关系型数据库 MySQL - ...

  5. PostgreSQL VACUUM 之深入浅出 (二)

    AUTOVACUUM AUTOVACUUM 简介 PostgreSQL 提供了 AUTOVACUUM 的机制. autovacuum 不仅会自动进行 VACUUM,也会自动进行 ANALYZE,以分析 ...

  6. 三大数据库 sequence 之华山论剑 (中篇)

    sequence 用法四 AUTO INCREMENT 通过 DEFAULT 还是需要手动创建 sequence.有没有更简单的用法呢? 当然,就是通过 AUTO INCREMENT 方式,自动创建 ...

  7. 三大数据库 sequence 之华山论剑 (下篇)

    MySQL 5.7 MYISAM ENGINE 以下是 MySQL 5.7 MYISAM ENGINE 中的运行结果 mysql> CREATE TABLE tb_test5 ( -> t ...

  8. PostgreSQL VACUUM 之深入浅出 (一)

    前言 VACUUM 是 PostgreSQL MVCC (Multiversion concurrency control) 实现的核心机制之一,是 PostgreSQL 正常运行的重要保证.本文将通 ...

  9. PostgreSQL VACUUM 之深入浅出 (三)

    VACUUM 相关参数 对 VACUUM 有了一定的了解之后,下面系统介绍下 VACUUM 相关参数. VACUUM 相关参数主要分为三大类. 第一类 与资源相关参数 #--------------- ...

随机推荐

  1. docker daemon

    docker启动最先加载Docker Daemon. Docker Daemon的启动文件放在/etc/systemd/system/docker.service.d目录中,如果没有则手工创建该目录并 ...

  2. 统信UOS系统部署.Net Core 5.0

    平时很少用Linux,需要的时候才查资料,记录下遇到的问题和解决办法.这次部署的系统是统信UOS,arm64位CPU 第一步:安装.Net Core 5.0运行环境 统信UOS是基于Debian 10 ...

  3. JFrame实现圆角窗体

    感谢大佬:https://blog.csdn.net/Mr_Pang/article/details/47808299?utm_source=blogxgwz0 注:使用AWTUtilities类跨平 ...

  4. 【转载】Nginx简介及使用Nginx实现负载均衡的原理

    原文地址:http://blog.csdn.net/u014749862/article/details/50522276 是什么? Nginx 这个轻量级.高性能的 web server 主要可以干 ...

  5. LNMP平台的redis对接安装

    LNMP平台的redis对接安装 目录 LNMP平台的redis对接安装 一.安装LNMP的各个组件 二.安装redis服务 三.安装redis扩展 四.修改php配置文件 五.测试连接 一.安装LN ...

  6. 按照递推的思想求解next[]数组

    按照递推的思想求解next[]数组 根据定义next[0]=-1,假设next[j]=k, 即P[0...k-1]==P[j-k,j-1] 若P[j]P[k],则有P[0..k]P[j-k,j],很显 ...

  7. 人工智能——CNN卷积神经网络项目之猫狗分类

    首先先导入所需要的库 import sys from matplotlib import pyplot from tensorflow.keras.utils import to_categorica ...

  8. Solution -「JOISC 2021」「LOJ #3495」聚会 2

    \(\mathcal{Description}\)   Link.   给定一棵含 \(n\) 个结点的树.称点集 \(S\) 到结点 \(u\) 的会合距离为 \(\sum_{v\in S}\ope ...

  9. suse 12 二进制部署 Kubernetets 1.19.7 - 第00章 - 环境准备

    文章目录 0.环境准备 0.0.修改主机名 0.1.添加hosts解析 0.2.配置ssh免密 0.3.发送hosts解析文件到其他节点,并修改hostname 0.4.更新PATH变量 0.5.安装 ...

  10. c++ 汇编代码看内存分配

    汇编代码看内存分配 (1). 程序运行时分为存储区域分为 存储区域 存储内容 extra 代码区 存放代码指令,包括除字符串常量的字面值 静态存储区 存放静态变量和全局变量 执行main之前就分配好了 ...