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
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