Monday, September 20, 2021

PostgreSQL: how to create a partitioned table using a conversion function

Consider the following table:
CREATE TABLE myuser.mytable (
    id integer NOT NULL,
    created_date timestamp without time zone NOT NULL,
    event_json text NOT NULL,
    format_version text NOT NULL,
    rep_id text NOT NULL,
    appversion text NOT NULL
);
Let's say you want to partition this table by RANGE, and you would like to use the column "created_date" which is of data type "TIMESTAMP WITHOUT TIME ZONE".
You could use a conversion function like CAST to convert the column to a partitioned one, like this:
  CREATE TABLE myuser.mytable (
    id integer NOT NULL,
    created_date timestamp without time zone NOT NULL,
    event_json text NOT NULL,
    format_version text NOT NULL,
    rep_id text NOT NULL,
    appversion text NOT NULL
)
partition by range(cast(created_date as date));
Obviously you proceed with adding your partitions the way you normally would in PostgreSQL, for example:
CREATE TABLE myuser.mytable_p_202001
 PARTITION OF myuser.mytable
 FOR VALUES FROM ('2020.01.01') TO ('2020.01.31');

CREATE TABLE myuser.mytable_p_202002
 PARTITION OF myuser.mytable
 FOR VALUES FROM ('2020.02.01') TO ('2020.02.29');

etc

CREATE TABLE myuser.mytable_p_default
 PARTITION OF myuser.mytable
 DEFAULT;

Beware: If you try to create a primary key constraint on the partition key column in this case, you will receive
DETAIL:  PRIMARY KEY constraints cannot be used when partition keys include expressions.

You are of course free to add a normal search index on the column:
CREATE INDEX myidx1 ON myuser.mytable USING btree ( cast (created_date as date) );
Read more about the CAST function in the documentation
Another good source is postgressqltutorial.com

1 comment:

  1. Vegard, your examples are very good, and your topic is spot on for what I was trying to achieve. In Oracle and DB2, a partitioning scheme derived from an expression (sometimes called function-based partitioning) is no big deal. I still don't understand WHY using one eliminates the ability to create a primary key, which is an established criteria for an acid-compliant relational model.

    ReplyDelete