【PostgreSQL 11 新機能】デフォルトパーティションを検証してみた

◆ Live配信スケジュール ◆
サイオステクノロジーでは、Microsoft MVPの武井による「わかりみの深いシリーズ」など、定期的なLive配信を行っています。
⇒ 詳細スケジュールはこちらから
⇒ 見逃してしまった方はYoutubeチャンネルをご覧ください
【4/18開催】VSCode Dev Containersで楽々開発環境構築祭り〜Python/Reactなどなど〜
Visual Studio Codeの拡張機能であるDev Containersを使ってReactとかPythonとかSpring Bootとかの開発環境をラクチンで構築する方法を紹介するイベントです。
https://tech-lab.connpass.com/event/311864/

こんにちは。サイオステクノロジー OSS サポート担当 Y です。

今回は PostgreSQL 11 (現時点ではまだ beta 版) の新機能である “デフォルトパーティション” を検証してみました。(※以下の内容は CentOS 7.5/PostgreSQL 10.5/PostgreSQL 11beta3 にて検証しています。)

■はじめに

昨年リリースされた PostgreSQL 10 の新機能である Declarative Partitioning には、いわゆる “デフォルトパーティション” の機能が存在していないのですが、PostgreSQL 11 ではこの “デフォルトパーティション” が実装される予定となっています。

今回は PostgreSQL 11beta3 を使って、このデフォルトパーティションを試してみようと思います。

■検証 (PostgreSQL 10 の動作確認)

まずは PostgreSQL 10 の動作を確認してみます。(以下の例では LIST パーティションを使用しています)

postgres=# CREATE TABLE hoge (list_key int, data text) PARTITION BY LIST (list_key);
CREATE TABLE
postgres=# CREATE TABLE hoge_child_1 PARTITION OF hoge FOR VALUES IN (1);
CREATE TABLE
postgres=# CREATE TABLE hoge_child_2 PARTITION OF hoge FOR VALUES IN (2);
CREATE TABLE
postgres=# CREATE TABLE hoge_child_3 PARTITION OF hoge FOR VALUES IN (3);
CREATE TABLE
postgres=# 
postgres=# \d+ hoge
                                     Table "public.hoge"
  Column  |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
----------+---------+-----------+----------+---------+----------+--------------+-------------
 list_key | integer |           |          |         | plain    |              | 
 data     | text    |           |          |         | extended |              | 
Partition key: LIST (list_key)
Partitions: hoge_child_1 FOR VALUES IN (1),
            hoge_child_2 FOR VALUES IN (2),
            hoge_child_3 FOR VALUES IN (3)

上記の様にパーティショニングされたテーブルにて、”条件の範囲内” の値 (上記例の場合 “1”, “2”, “3”) を INSERT すると以下の様に正常に各子テーブルにレコードが振り分けられます。

postgres=# INSERT INTO hoge VALUES (1, 'hogehoge'), (2, 'hogehoge'), (3, 'hogehoge');
INSERT 0 3
postgres=# 
postgres=# SELECT * FROM hoge;
 list_key |   data   
----------+----------
        1 | hogehoge
        2 | hogehoge
        3 | hogehoge
(3 rows)

postgres=# 
postgres=# SELECT * FROM hoge_child_1;
 list_key |   data   
----------+----------
        1 | hogehoge
(1 row)

postgres=# 
postgres=# SELECT * FROM hoge_child_2;
 list_key |   data   
----------+----------
        2 | hogehoge
(1 row)

postgres=# 
postgres=# SELECT * FROM hoge_child_3;
 list_key |   data   
----------+----------
        3 | hogehoge
(1 row)

しかし、PostgreSQL 10 で “条件の範囲外” の値 (上記例の場合 “1”, “2”, “3” 以外の値) を INSERT しようとすると、以下の様に ERROR になってしまいます。

postgres=# INSERT INTO hoge VALUES (4, 'hogehoge');
ERROR:  no partition of relation "hoge" found for row
DETAIL:  Partition key of the failing row contains (list_key) = (4).

■検証 (PostgreSQL 11 の動作確認)

それでは、PostgreSQL 11beta3 でデフォルトパーティションを試してみます。

まずは、前述した PostgreSQL 10 の検証と同じテーブルを作成します。

postgres=# CREATE TABLE hoge (list_key int, data text) PARTITION BY LIST (list_key);
CREATE TABLE
postgres=# CREATE TABLE hoge_child_1 PARTITION OF hoge FOR VALUES IN (1);
CREATE TABLE
postgres=# CREATE TABLE hoge_child_2 PARTITION OF hoge FOR VALUES IN (2);
CREATE TABLE
postgres=# CREATE TABLE hoge_child_3 PARTITION OF hoge FOR VALUES IN (3);
CREATE TABLE
postgres=# 
postgres=# \d+ hoge
                                     Table "public.hoge"
  Column  |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
----------+---------+-----------+----------+---------+----------+--------------+-------------
 list_key | integer |           |          |         | plain    |              | 
 data     | text    |           |          |         | extended |              | 
Partition key: LIST (list_key)
Partitions: hoge_child_1 FOR VALUES IN (1),
            hoge_child_2 FOR VALUES IN (2),
            hoge_child_3 FOR VALUES IN (3)

この状態で振り分け条件として設定していない値を INSERT すると PostgreSQL 10 と同じ様に ERROR になります。

postgres=# INSERT INTO hoge VALUES (4, 'hogehoge');
ERROR:  no partition of relation "hoge" found for row
DETAIL:  Partition key of the failing row contains (list_key) = (4).

しかし、PostgreSQL 11 ではデフォルトパーティションを作成することができるため、テーブル “hoge” にデフォルトパーティションを追加してみます。デフォルトパーティションを作成する場合は、CREATE TABLE 文にて “DEFAULT” を指定します。

postgres=# CREATE TABLE hoge_child_default PARTITION OF hoge DEFAULT;
CREATE TABLE
postgres=# 
postgres=# \d+ hoge
                                     Table "public.hoge"
  Column  |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
----------+---------+-----------+----------+---------+----------+--------------+-------------
 list_key | integer |           |          |         | plain    |              | 
 data     | text    |           |          |         | extended |              | 
Partition key: LIST (list_key)
Partitions: hoge_child_1 FOR VALUES IN (1),
            hoge_child_2 FOR VALUES IN (2),
            hoge_child_3 FOR VALUES IN (3),
            hoge_child_default DEFAULT

上記の様にデフォルトパーティションを追加した後に、改めて振り分け条件として設定していない値を INSERT すると、今度は ERROR にならずにデータを INSERT することができます。

postgres=# INSERT INTO hoge VALUES (4, 'hogehoge');
INSERT 0 1
postgres=# 
postgres=# SELECT * FROM hoge;
 list_key |   data   
----------+----------
        4 | hogehoge
(1 row)

この状態で子テーブル “hoge_child_default” を確認してみると、list_key に “4” を指定したレコードが格納されていることが確認できます。

postgres=# SELECT * FROM hoge_child_default;
 list_key |   data   
----------+----------
        4 | hogehoge
(1 row)

この様に、PostgreSQL 11 ではデフォルトパーティションを設定できるので、振り分け条件に合致しないレコードを INSERT した場合でも ERROR にならずにレコードを格納することができます。

■最後に

業務上規定された範囲外の値を INSERT しようとした場合には ERROR を返した方が良い等、デフォルトパーティションが不要な場合もあるとは思いますが、PostgreSQL 10 ではパーティションキーの値をアプリ側で厳密に管理する必要があったので、デフォルトパーティションが有用な場面も多いのではないでしょうか。

PostgreSQL 11 ではパーティション関連の機能を含め様々な機能が強化されているので、次回も PostgreSQL 11 の新機能の検証を実施してみようと思います。

アバター画像
About サイオステクノロジーの中の人 41 Articles
サイオステクノロジーで働く中の人です。
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

0人がこの投稿は役に立ったと言っています。


ご覧いただきありがとうございます。
ブログの最新情報はSNSでも発信しております。
ぜひTwitterのフォロー&Facebookページにいいねをお願い致します!



>> 雑誌等の執筆依頼を受付しております。
   ご希望の方はお気軽にお問い合わせください!

Be the first to comment

Leave a Reply

Your email address will not be published.


*


質問はこちら 閉じる