PostgreSQL 动态表复制(CREATE TABLE ASCREATE TABLE LIKE)

项目中有表复制的需求,而且是动态复制,即在存储过程里根据参数数组的值循环复制n张结构(约束、索引等)等一致的一组表,PostgreSQL提供了两种语法来进行表复制,分别是:

CREATE TABLE AS

CREATE TABLE LIKE

下面就通过一个例子来看看究竟哪一种更好或者说更符合我们的需求。

CREATE TABLE AS

首先看看CREATE TABLE AS的用法,在这之前结合一个具体的例子看看,我们需要复制的是这样一张表:

这里写图片描述

如上图所示,在PowerDesigner的物理模型(pdm)中我们可以看到这张表定义了主键和一个外键,再看看它的ddl语句:

drop table t_key_event_file_student; /*==============================================================*/ /* Table: t_key_event_file_student */ /*==============================================================*/ create table t_key_event_file_student ( id SERIAL not null, key_event_score_student_id INT4 not null, file_name varchar(100) not null, file_path varchar(100) not null, constraint PK_T_KEY_EVENT_FILE_STUDENT primary key (id) ); comment on table t_key_event_file_student is '关键事件业务表(附件)'; comment on column t_key_event_file_student.id is '主键'; comment on column t_key_event_file_student.key_event_score_student_id is '关键事件录入ID'; comment on column t_key_event_file_student.file_name is '附件文件名称'; comment on column t_key_event_file_student.file_path is '附件文件路径'; alter table t_key_event_file_student add constraint FK_T_KEY_EV_REF16_T_KEY_EV foreign key (key_event_score_student_id) references t_key_event_score_student (id) on delete restrict on update restrict;

如上所示,首先理一下这张表都包含了什么东西,我们复制表的同时应带上什么东西。
首先,id定义成了SERIAL类型,那就意味着建表的同时会为我们自动创建一个序列,那么这个序列在表复制的时候是肯定不能copy的,因为那样的话将意味着原表和复制的表公用一个序列,明显不合理。其次是约束,我们可以看到上面的DDL语句中出现了三种约束,分别是:主键(Primary Key)约束、外键(Foreign Key)约束以及非空(Not Null)约束,很显然,表复制的同时这三种约束都应存在,中间的语句还有若干条comment(注释),理论上注释内容在表复制的同时也应该存在,所以简单总结一下我们做表复制的取舍:

所有约束、索引和注释在复制时都应被拷贝。

序列不应拷贝,应当为每一张复制的表单独创建一个新的序列。

搞清楚这些问题后接下来看看PostgreSQL的相关支持能为我们实现什么,首先看一下CREATE TABLE AS,官方是这样描述的:

这里写图片描述

如上图所示,CREATE TABLE AS主要做两件事情,分别是建表(CREATE DATA)和填充数据(FILL DATA),下面我们就通过CREATE TABLE AS复制一张表试试看。本篇blog的示例都会用t_key_event_file_student这张表,首先给这张表插入3条数据:

这里写图片描述

接下来运行CREATE TABLE AS来复制该表:

create table t_key_event_file_student_100 as select * from t_key_event_file_student;

创建成功后看看它的DDL语句:

这里写图片描述

再看一下这张表的数据:

这里写图片描述

如上图,首先第一张图可以看到拷贝后的表结构,那我们再回头看看原始表的表结构好做对比:

这里写图片描述

如上图,这样一比较发现差距还挺大的,CREATE TABLE AS复制出来的表,所有约束、注释和序列都没有被拷贝,但数据成功拷贝了,就如同官方文档中的描述,显而易见,这与我们的预期相差甚远,所以就不做过多考虑了,接下来看看第二种复制方式——CREATE TABLE LIKE。

CREATE TABLE LIKE

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/f9706631385d2e4e4139a57f02e0d2ef.html