今まで比較的MySQLを使うことが多くて、MySQLだとパーティショニングって結構簡単にできたんですが、 PostgreSQLだと、自分でパーティション用の子テーブル作って〜とか結構めんどくさかったので、忘れないようにメモ。
元になるテーブルを作る
とりあえずよくあるユーザーテーブル的なので試す
users
CREATE TABLE users (
user_id SERIAL NOT NULL PRIMARY KEY,
mail_address TEXT NOT NULL,
name TEXT NOT NULL,
password TEXT NOT NULL,
created_at timestamp(0) without time zone default now(),
updated_at timestamp(0) without time zone default now(),
deleted_at timestamp(0) without time zone
);
こんな感じのテーブルで。
パーティション用子テーブルを作る
とりあえず4分割にしてみる。
pertition_tbls
CREATE TABLE users_par0 (
CHECK (user_id % 4 = 0)
) INHERITS (users);
CREATE TABLE users_par1 (
CHECK (user_id % 4 = 1)
) INHERITS (users);
CREATE TABLE users_par2 (
CHECK (user_id % 4 = 2)
) INHERITS (users);
CREATE TABLE users_par3 (
CHECK (user_id % 4 = 3)
) INHERITS (users);
簡単にどこで何を指定してるかまとめると、
・CHECK (user_id % 4 = 0)・・・user_idを4で割った余りが0の場合のみ、この子テーブルにデータを格納するという指定(他の子テーブルと重複がないようにする)
・INHERITS (users)・・・派生元テーブルの指定
というような感じです。
functionを定義
実際にinsert文が発行されたときに、どの子テーブルにinsertを流すかを制御するfunctionです。
function
CREATE OR REPLACE FUNCTION users_insert_trigger_func()
RETURNS trigger AS
$BODY$
DECLARE
child text;
BEGIN
child := 'users_par' || new.user_id % 4;
EXECUTE 'INSERT INTO ' || child || ' VALUES(($1).*)' USING new;
RETURN NULL;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
triggerを登録
insert文が発行されたときに、上記のfunctionが実行されるようにtriggerを作ります。
trigger
CREATE TRIGGER users_insert_trigger
BEFORE INSERT
ON users
FOR EACH ROW
EXECUTE PROCEDURE users_insert_trigger_func();
これで4分割パーティションができるはず!
それにしてももうちょっと手軽にできないのかなぁ、、、
※ついでに
上記で作ったテーブルを普通にdropしようとすると怒られるので、drop時は以下のようにする
DROP TABLE users CASCADE;
また、functionは一緒に消えてくれないので、function消す場合は以下も実行する
DROP FUNCTION users_insert_trigger_func();