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

PostgreSQL中如何让继承表共享自增ID列?

PostgreSQL继承表共享唯一ID失败及插入报错解决

背景与问题

表结构

CREATE TABLE A (
    ID integer PRIMARY KEY generated always as identity,
    data integer
);

CREATE TABLE B (
     other_data integer
) INHERITS (A);

CREATE TABLE C (
     other_other_data integer
) INHERITS (A);

需求

要让表B和C的ID字段全局唯一,两张表的ID不重复。

报错场景

执行插入语句:

insert into B (other_data) values (1)

触发错误:

ERROR:  null value in column "id" of relation "B" violates not-null constraint 
DETAIL:  Failing row contains (null)

你怀疑继承方式没法实现共享唯一ID,另外之前长期用serial类型,后来才在维基看到不推荐的警告,还觉得PostgreSQL文档体验不好。

问题原因

PostgreSQL的表继承机制里,父表的identity列不会自动把序列传递给子表。子表虽然继承了ID列的非空、主键约束,但没继承自增序列的默认值,所以插入时ID字段没有值,触发非空约束报错。

解决办法

方法1:用全局共享序列

放弃父表的identity定义,手动创建一个全局序列,让所有表的ID都用这个序列生成:

  1. 创建全局序列:
CREATE SEQUENCE global_id_seq;
  1. 重新创建父表A:
CREATE TABLE A (
    ID integer PRIMARY KEY DEFAULT nextval('global_id_seq'),
    data integer
);
  1. 子表B、C的继承定义不变,插入时会自动从全局序列取ID,自然保证B和C的ID不重复:
INSERT INTO B (other_data) VALUES (1);
INSERT INTO C (other_other_data) VALUES (2);

方法2:用UUID(适合不需要自增的场景)

如果不需要整数自增ID,用UUID可以天然实现全局唯一:

  1. 先启用UUID扩展:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
  1. 定义父表:
CREATE TABLE A (
    ID uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
    data integer
);
  1. 子表继承后,插入时会自动生成唯一UUID,不需要额外处理。

关于serial类型

serial是PostgreSQL早期的语法糖,本质是自动创建序列+给列加默认值,但序列和列的关联松散,删除列时序列不会自动清理;而generated always as identity是SQL标准语法,关联更严谨,所以官方推荐用后者替代serial。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 19:45:56