1つ前のPostgreSQLについてのブログ記事でついでに調べた内容です。そのまま記述すると長文になりそうでしたので分割しました。 PostgreSQLも掘り下げれば掘り下げる程、本当に奥が深い世界だと実感しますね😑
TOASTについて調べた発端
前回の記事で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文字列の実体を分割して格納してくれていました。