Reputation: 3067
I'm wondering if it's possible (and how to go about it if it is)
to partition a table in postgres 9.1 based on a date field being null or not null.
So effectively, I have a table and it gets quite large, I have a "delete_on" date in there and when items get deleted they just get tagged as deleted.
This would be ideal to archive them off and keep the active tables small.
I was thinking of a table partition and just having something like
active (delete_on = NULL)
archive (deleted_on != NULL)
Then when I do an update on a record, and set it's deleted on, it would get written to the archive table.
I could do it manually by just creating two separate tables and writing code to copy the data over, but I'd like it if I could just put it on the database directly.
Any ideas?
Edit:
Master table
CREATE TABLE my_table (
id int not null,
deleted date not null,
number1 int,
number2 int
);
Partitions
CREATE TABLE my_table_active (
CHECK (deleted IS NULL)
) INHERITS (my_table);
CREATE TABLE my_table_archive (
CHECK (deleted IS NOT NULL)
) INHERITS (my_table);
Trigger Function
CREATE OR REPLACE FUNCTION my_table_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.deleted IS NULL ) THEN
INSERT INTO my_table_active VALUES (NEW.*);
ELSE
INSERT INTO my_table_archive VALUES (NEW.*);
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
Create Trigger
CREATE TRIGGER insert_my_table_trigger
BEFORE INSERT ON my_table
FOR EACH ROW EXECUTE PROCEDURE my_table_insert_trigger();
(I've taken the above from the Postgres documentation)
How would this work if you're doing an update on a field that is already in the active table?
So I have a record in the active table (i.e. delete is null) then I set that record to be deleted (by giving it a date stamp). At that point i want it moved to the archive table.
Upvotes: 4
Views: 5829
Reputation: 324841
You can partition on IS NULL
and IS NOT NULL
.
= NULL
and != NULL
both always result in NULL
, so they conflict. You never write = NULL
in SQL, always a IS NULL
or a IS DISTINCT FROM b
.
For the details of how to set up PostgreSQL's table-inheritance based partitioning and associated constraint exclusion, see the documentation.
There's no need to "write code to copy the data over" in any case. At worst you'd need to write a simple INSERT INTO newtable SELECT * FROM oldtable WHERE somefield IS NULL;
.
Upvotes: 5