PostgreSQL 9.6.3创建分区表报错:语法错误在PARTITION附近
解决PostgreSQL 9.6分区表创建报错的问题
哦,这个问题我熟!你遇到的报错是因为PostgreSQL 9.6.3还不支持你用的那种声明式分区语法——直接在CREATE TABLE后面加PARTITION BY是PostgreSQL 10才正式引入的新特性,9.6只能用继承+触发器的老方法来实现分区。下面是适配你需求的完整实现步骤:
1. 创建主表(父表)
首先创建一个不带分区语法的主表,作为所有分区的父表:
CREATE TABLE measurement ( city_id int not null, logdate date not null, peaktemp int, unitsales int );
2. 创建分区表(子表)
每个分区表都要继承自主表,并且通过CHECK约束限定该分区存储的logdate范围。比如我们按年份创建两个分区:
-- 存储2023年数据的分区 CREATE TABLE measurement_2023 ( CHECK (logdate >= '2023-01-01' AND logdate < '2024-01-01') ) INHERITS (measurement); -- 存储2024年数据的分区 CREATE TABLE measurement_2024 ( CHECK (logdate >= '2024-01-01' AND logdate < '2025-01-01') ) INHERITS (measurement);
3. 创建路由触发器函数
需要写一个PL/pgSQL函数,用来把插入到主表的数据自动路由到对应的分区:
CREATE OR REPLACE FUNCTION measurement_insert_trigger() RETURNS TRIGGER AS $$ BEGIN -- 根据logdate判断数据应该进入哪个分区 IF NEW.logdate >= '2023-01-01' AND NEW.logdate < '2024-01-01' THEN INSERT INTO measurement_2023 VALUES (NEW.*); ELSIF NEW.logdate >= '2024-01-01' AND NEW.logdate < '2025-01-01' THEN INSERT INTO measurement_2024 VALUES (NEW.*); ELSE -- 如果日期不在已定义的分区范围内,抛出异常 RAISE EXCEPTION 'Date out of range. Please update the trigger function or add a new partition!'; END IF; RETURN NULL; -- 因为数据已经插入到分区,不需要再插入主表 END; $$ LANGUAGE plpgsql;
4. 给主表绑定触发器
把上面的函数绑定到主表的插入事件上:
CREATE TRIGGER insert_measurement_trigger BEFORE INSERT ON measurement FOR EACH ROW EXECUTE PROCEDURE measurement_insert_trigger();
额外注意事项
- 尽量不要直接往主表插入数据,所有数据都会通过触发器自动路由到对应分区
- 可以给每个分区单独创建索引(比如给
logdate建索引),提升查询效率 - 如果后续需要新增分区,只要重复步骤2创建新的分区表,然后更新触发器函数里的条件分支即可
内容的提问来源于stack exchange,提问作者user2671057
相关产品推荐
相关产品推荐

