开发者社区 问答 正文

PostgreSQL13.1 在有主键的前提下,根据非主键字段进行分区的问题。

PostgreSQL13.1 在有主键的前提下,根据非主键字段进行分区的问题。

CREATE table b (
  id BIGINT PRIMARY KEY,
  "name" VARCHAR(30) NOT NULL,
  "created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
) PARTITION BY RANGE ("created_at");

create table b_1 PARTITION of b for values from ('2010-1-1') to ('2011-1-1');
create table b_2 PARTITION of b for values from ('2011-1-1') to ('2012-1-1');

会失败,

如果先根据 "create_at" 进行分区,再添加主键也会失败。

是 pgsql 不支持这种使用还是有其他方法?

展开
收起
九天仙乐 2021-05-08 17:46:14 496 分享 版权
阿里云 AI 助理回答

PostgreSQL 支持基于非主键字段进行分区,但是您的例子中遇到的问题可能与分区键的选择有关。在 PostgreSQL 中,当使用 RANGE 分区时,分区键必须是整数类型、日期/时间类型或者能够隐式转换为这些类型的一个表达式。您所使用的 TIMESTAMPTZ 类型作为分区键是完全支持的。

问题可能出在尝试直接在创建表时同时定义分区和主键约束的方式上。正确的做法是先创建一个不包含分区的基表(该表可以定义主键),然后创建分区表,并且分区表继承自这个基表。请参考以下步骤:

  1. 创建未分区的基表并定义主键:

    CREATE TABLE b (
     id BIGINT NOT NULL,
     "name" VARCHAR(30) NOT NULL,
     "created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
     PRIMARY KEY (id)
    );
    
  2. 创建分区表并指定分区范围: 之后,分别创建分区表,并确保每个分区表都继承自基表 b,同时指定分区的范围。

    CREATE TABLE b_1 PARTITION OF b FOR VALUES FROM ('2010-01-01') TO ('2011-01-01');
    CREATE TABLE b_2 PARTITION OF b FOR VALUES FROM ('2011-01-01') TO ('2012-01-01');
    

这样,您就可以基于非主键字段 "created_at" 成功创建分区表了。请注意,分区键并不强制要求是主键的一部分,因此即使 "created_at" 不是主键,这样的分区策略也是可行的。

如果在执行上述步骤后仍然遇到问题,请检查 PostgreSQL 的版本是否支持您所使用的分区特性,以及是否有其他错误信息提示需要解决。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答