エンジニアのはしがき

プログラミングの日々の知見を書き連ねているブログです

PostgreSQLのTOASTって何だろう

1つ前のPostgreSQLについてのブログ記事でついでに調べた内容です。そのまま記述すると長文になりそうでしたので分割しました。 PostgreSQLも掘り下げれば掘り下げる程、本当に奥が深い世界だと実感しますね😑

TOASTについて調べた発端

tm-progapp.hatenablog.com

前回の記事でPostgreSQLのストレージ容量をSQLで出力し、その際にpg_classテーブルからtoast_bytesを出力しました。これは各サイトを巡って調べたSQL文を抜粋したものなのですが、toastが実際に何を指しているのかは理解しておらず、疑問に感じていました。

TOASTとは

まず原則としてPostgreSQLではデフォルトで1行のデータをブロックサイズ(8KB)に収めようとする仕組みがあります。このブロックサイズを超過するようなデータを直接格納することはできません。

では大きなサイズのデータはどう格納するのかというと、PostgreSQLはデータを小さな断片に分割してTOASTテーブルに格納します。TOASTテーブルはPostgreSQL側で自動生成されますので開発者が意識することはありません。これはデフォルトで有効化されている仕組みとなります。

TOASTテーブルにデータを分割して格納したとしても、データサイズの最大値は1GBと決まっているようです。通常、そのような巨大なデータをPostgreSQLに格納するケースは無いとは思いますが……。無理やりバイナリを突っ込むような構成は避けた方が良いということですね😓

なお、TOASTテーブルはpg_toastスキーマに所属しており、pg_toast.pg_toast_*****(****は元のテーブルのoid=オブジェクト識別子データ型)をFROM句に指定してSELECTすることで参照できます。(ただし参照する権限が必要)

TOASTテーブルが作成される条件

TOASTは可変長(varlena)表現を持つデータ型のみ適用されます。具体的にはtext型などが該当します。

私の場合では、text型のカラムにサイズの大きいJSON文字列を突っ込んでいたので、PostgreSQLがTOASTテーブルへJSON文字列の実体を分割して格納してくれていました。

参考

wiki.postgresql.org

tech-blog.rakus.co.jp

gigazine.net