【PostgreSQL】PostgreSQL ~ テーブル情報を取得するには ~

■ はじめに

 システムの マイグレーションを行っているのだが、
PostgreSQL 互換の AWS Redshift のテーブル情報の一覧が欲しい
とのことなので調べてみた。

目次

【1】システムが保持しているビュー
 0)information_schemaスキーマ内のビュー
 1)pg_namespace
 2)pg_class
 3)pg_tables
 4)pg_stat_user_tables
【2】使用上の注意
【3】サンプル
 例1:テーブル一覧(行数&サイズ付き)
 例2:ユーザテーブルを行数が多いごとに表示
【4】補足:Redshift について
 1)Redshiftのブロック数「relpages」
 2)Redshift の システムビュー

【1】システムが保持しているビュー

* 以下も読んでおくと面白いかも。

https://amg-solution.jp/blog/23077

PostgreSQL のシステムカタログ一覧
https://www.postgresql.jp/document/14/html/catalogs.html

0)information_schemaスキーマ内のビュー

* PostgreSQL/Redshiftだけでなく、他のDBでも使えるらしい

https://www.postgresql.jp/document/8.1/html/information-schema.html




1)pg_namespace

名前空間を保存

主な項目

* それ以外は、以下のサイトを参照。

https://www.postgresql.jp/document/9.4/html/catalog-pg-namespace.html

名前 説明 備考
oid 行識別子 「2)pg_class」の「relnamespace」とJOIN可能
nspname 名前空間の名前

2)pg_class

* テーブルやインデックスなど、リレーションの情報が格納

主な項目

* それ以外は、以下のサイトを参照。

https://www.postgresql.jp/document/9.6/html/catalog-pg-class.html

名前 説明 備考
oid 行識別子 「3)pg_stat_user_tables」の「relid」とJOIN可能
relname テーブルを持つスキーマ
relnamespace リレーションを持つ名前空間のOID 「1)pg_namespace」の「oid」とJOIN可能
relpages ブロック数 サイズ(容量)に使用。bytes に変換する際は 8192(8K) をかける
reltuples テーブル内の行数
relpersistence pは永続テーブル、uはログを取らないテーブル、tは一時テーブルを表す
relkind rは通常のテーブル、iはインデックス、Sはシーケンス、vはビュー、mはマテリアライズドビュー、cは複合型、tはTOASTテーブル、fは外部テーブルを表します 普通のテーブル取りたいなら、relkind = 'r'

3)pg_tables

データベース内の各テーブル情報を保持
 => テーブル一覧だけでよければ、こいつをSELECTしてあげるだけでいい

主な項目

* それ以外は、以下のサイトを参照。

https://www.postgresql.jp/document/9.6/html/view-pg-tables.html

名前 説明 備考
schemaname テーブルを持つスキーマ
tablename テーブル名

4)pg_stat_user_tables

現在のデータベースの各ユーザテーブルごとに1行の形で、
特定のテーブルへのアクセスに関する統計情報
 => pg_stat_sys_tablesはシステムテーブル、pg_stat_all_tablesは全テーブル

主な項目

* それ以外は、以下のサイトを参照。

https://www.postgresql.jp/document/9.6/html/monitoring-stats.html#pg-stat-all-tables-view

名前 説明 備考
relid テーブルのOID 「2)pg_class」の「oid」でJOIN可能
schemaname テーブルを持つスキーマ
relname テーブル名
n_live_tup 有効行の推定値 テーブルの行数

【2】使用上の注意

あくまで統計情報で実サイズとは異なっている可能性がある
(更新されていない可能性がある)
 => 更新したい場合は、ANALYZE <table_name>で統計情報を更新
 => 詳細は、以下のサイトを参照。

https://ichinari.work/postgresql_20210128/
https://www.insight-ltd.co.jp/tech_blog/postgresql/559/

【3】サンプル

例1:テーブル一覧(行数&サイズ付き)

SELECT
 n.nspname AS schema_name
 , c.relname AS table_name
 , c.reltuples  AS rows
 , (c.relpages * 8192) AS size
FROM
 pg_class AS c
JOIN
 pg_namespace AS n
ON
 c.relnamespace = n.oid
;

例2:ユーザテーブルを行数が多いごとに表示

SELECT
 n.nspname AS schema_name
 , c.relname AS table_name
 , c.reltuples::bigint  AS rows -- Cast は 指数表示防止
 , (c.relpages * 8192) AS size
FROM
 pg_stat_user_tables AS u
JOIN
 pg_class AS c
ON
 u.relid = c.oid
JOIN
 pg_namespace AS n
ON
 c.relnamespace = n.oid
ORDER BY
  c.reltuples::numeric DESC
;

補足:pg_size_pretty

* pg_size_pretty(bigint)
 => 容量単位(kB、MB、GB、もしくはTB単位)で目で見て理解できる形式に
  バイト数に領域を変換

https://www.postgresql.jp/document/8.1/html/functions-admin.html

【4】補足:Redshift について

1)Redshiftのブロック数「relpages」

* 全てのユーザテーブルで「0」だった
 => Redshift では、実データを別で保持しているのかも、、、
 => SVV_TABLE_INFO であればサイズの出力も可能(詳細は以下の関連記事を参照)

Redshift ~ システムビュー ~
https://dk521123.hatenablog.com/entry/2023/03/06/184928

2)Redshift の システムビュー

* 以下の関連記事を参照のこと。
 => SVV_TABLE_INFO でほしい情報が取れる

Redshift ~ システムビュー ~
https://dk521123.hatenablog.com/entry/2023/03/06/184928

参考文献

https://qiita.com/awakia/items/99c3d114aa16099e825d
https://tm.root-n.com/database:postgresql:etc:pages_tuples

関連記事

PostgreSQL ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2014/03/08/000100
PostgreSQL ~ 統計情報 ~
https://dk521123.hatenablog.com/entry/2024/11/14/174334
よく使う pdqlコマンド
https://dk521123.hatenablog.com/entry/2020/01/10/224818
psqlCSV出力する
https://dk521123.hatenablog.com/entry/2020/02/08/001155
Amazon Redshift ~ システムビュー ~
https://dk521123.hatenablog.com/entry/2023/03/06/184928