You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中使用CREATE TABLE AS能否复制表的Nullable约束?

问题

我在PostgreSQL中用以下语句创建空表:

CREATE TABLE IF NOT EXISTS table_yyymmdd 
    AS TABLE parent_table 
    WITH NO DATA;

创建成功后,子表table_yyymmdd的列名和数据类型都和父表一致,但所有列的Nullable约束都丢失了(父表中大部分列是not null,子表全变成可空)。想知道能不能通过CREATE TABLE AS语句直接复制父表的Nullable约束?

父表结构:

Column        |            Type             | Collation | Nullable |         Default         
----------------------+-----------------------------+-----------+----------+-------------------------
 id                   | bigint                      |           | not null | 
 id_transaction       | text                        |           | not null | 
 id_account           | bigint                      |           | not null | 
 id_number            | bigint                      |           | not null | 
 transaction_time     | timestamp without time zone |           | not null | now()
 amount               | integer                     |           | not null | 
 fee                  | integer                     |           | not null | 
 validity             | integer                     |           | not null | 
 notification_message | text                        |           |          | 

子表结构:

Column        |            Type             | Collation | Nullable | Default 
----------------------+-----------------------------+-----------+----------+---------
 id                   | bigint                      |           |          | 
 id_transaction       | text                        |           |          | 
 id_account           | bigint                      |           |          | 
 id_number            | bigint                      |           |          | 
 transaction_time     | timestamp without time zone |           |          | 
 amount               | integer                     |           |          | 
 fee                  | integer                     |           |          | 
 validity             | integer                     |           |          | 
 notification_message | text                        |           |          | 
结论

不行,CREATE TABLE AS语句本身不支持复制原表的NOT NULL约束。这个语句的设计目标是基于查询结果创建表,只会复制列名、数据类型,以及部分由查询推导出来的属性,不会保留原表的约束(包括NOT NULL)、主键、外键、默认值(除非默认值是查询结果的一部分)等结构信息。

解决方案

方法1:使用CREATE TABLE ... LIKE(推荐)

PostgreSQL提供的LIKE语法专门用于复制表的完整结构,包括约束、默认值甚至索引:

CREATE TABLE IF NOT EXISTS table_yyymmdd 
LIKE parent_table 
INCLUDING ALL  -- 包含所有约束、默认值、索引、存储参数等
WITH NO DATA;

如果只需要NOT NULL约束和默认值,不需要索引等其他内容,可以更精准地指定:

CREATE TABLE IF NOT EXISTS table_yyymmdd 
LIKE parent_table 
INCLUDING DEFAULTS  -- 复制默认值
INCLUDING CONSTRAINTS  -- 复制约束(含NOT NULL)
WITH NO DATA;

方法2:CREATE TABLE AS + 手动添加约束

如果必须用CREATE TABLE AS,可以在创建表后手动补全NOT NULL约束和默认值:

-- 先创建空表
CREATE TABLE IF NOT EXISTS table_yyymmdd 
AS TABLE parent_table 
WITH NO DATA;

-- 添加NOT NULL约束
ALTER TABLE table_yyymmdd
ALTER COLUMN id SET NOT NULL,
ALTER COLUMN id_transaction SET NOT NULL,
ALTER COLUMN id_account SET NOT NULL,
ALTER COLUMN id_number SET NOT NULL,
ALTER COLUMN transaction_time SET NOT NULL,
ALTER COLUMN amount SET NOT NULL,
ALTER COLUMN fee SET NOT NULL,
ALTER COLUMN validity SET NOT NULL;

-- 补全默认值(比如transaction_time的now())
ALTER TABLE table_yyymmdd
ALTER COLUMN transaction_time SET DEFAULT now();

内容的提问来源于stack exchange,提问作者c0ng111

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:13:33