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 不支持这种使用还是有其他方法?
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
PostgreSQL 支持基于非主键字段进行分区,但是您的例子中遇到的问题可能与分区键的选择有关。在 PostgreSQL 中,当使用 RANGE
分区时,分区键必须是整数类型、日期/时间类型或者能够隐式转换为这些类型的一个表达式。您所使用的 TIMESTAMPTZ
类型作为分区键是完全支持的。
问题可能出在尝试直接在创建表时同时定义分区和主键约束的方式上。正确的做法是先创建一个不包含分区的基表(该表可以定义主键),然后创建分区表,并且分区表继承自这个基表。请参考以下步骤:
创建未分区的基表并定义主键:
CREATE TABLE b (
id BIGINT NOT NULL,
"name" VARCHAR(30) NOT NULL,
"created_at" TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);
创建分区表并指定分区范围: 之后,分别创建分区表,并确保每个分区表都继承自基表 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 的版本是否支持您所使用的分区特性,以及是否有其他错误信息提示需要解决。