LoginSignup
5
8

More than 3 years have passed since last update.

PostgreSQLでテーブル定義を確認したい!

Last updated at Posted at 2019-01-16

「テーブル定義はあるけど、全然最新化されてねぇじゃねぇか!!」
ってこと、よくあるよね...
そんなときにSQL一発で全部のテーブル定義を抽出できるSQLをつくってみた。
※ただしPostgreSQLにかぎる

テーブル定義の確認

実際のSQL

テーブル名、列名のコメントと一緒に取ってくるようにしている。
もし作成時にコメントをつけていなかったら、pg_descriptionとinner joinしているところを変更すれば、
物理名だけで取ってこれるはず。

2020/11/19:追記
PKの情報も一緒に持ってくるようにしてみた。

WITH table_define AS(
    SELECT
        isc.ordinal_position,
        isc.table_name,
        table_pgd.description,
        isc.column_name,
        pgd.description,
        CASE
            WHEN ccu.column_name = isc.column_name THEN '○'
            ELSE NULL
        END AS is_pk,
        isc.data_type,
        isc.character_maximum_length,
        isc.column_default,
        isc.is_nullable
    FROM
        information_schema.columns isc
        INNER JOIN
            pg_stat_user_tables psut
        ON  psut.relname = isc.table_name
        AND psut.schemaname = 'スキーマ名'
        INNER JOIN
            pg_description pgd
        ON  pgd.objoid = psut.relid
        AND pgd.objsubid = isc.ordinal_position
        INNER JOIN
            information_schema.table_constraints tc
        ON  tc.table_name = isc.table_name
        AND tc.table_schema = 'スキーマ名'
        AND tc.constraint_type = 'PRIMARY KEY'
        LEFT OUTER JOIN
            information_schema.constraint_column_usage ccu
        ON  ccu.table_catalog = tc.table_catalog
        AND ccu.table_schema = tc.table_schema
        AND ccu.table_name = ccu.table_name
        AND ccu.constraint_name = tc.constraint_name
        INNER JOIN
            (
                SELECT
                    *
                FROM
                    pg_description pgd
                WHERE
                    pgd.objsubid = 0
            ) table_pgd
        ON  table_pgd.objoid = psut.relid
    WHERE
        isc.table_schema = 'スキーマ名'
)
SELECT
    *
FROM
    table_define td
ORDER BY
    td.table_name,
    td.is_pk NULLS LAST,
    td.ordinal_position

ちょっとだけ説明

・information_schema とはデータベース内の様々メタデータを取得するために標準SQLで定められているビューの集合
・pg_descriptionには、コメントが格納されている
 「objoid」でテーブルを特定し、「objsubid」でカラムを特定する。
 「information_schema.columns」から、「objsubid」は取得できる。
・テーブルは「pg_stat_user_tables」から「objoid」を取得することでコメントの取得が可能。

UNIQUEインデックスを一覧で取得するSQL

業務で必要になって使ったので追記。

select
    a2.nspname as namespase,
    a4.relname as table_name,
    a1.relname as index_name,
    a5.attname as column_name,
    position(cast(a5.attnum as text) in replace(cast(a3.indkey as text), ' ', '')) as index_position
--インデックスの定義順特定
from
    pg_class a1,
    pg_namespace a2,
    pg_index a3,
    pg_class a4,
    pg_attribute a5
where
    a1.relkind = 'i'
--インデックスのみ取得
and a1.relnamespace = a2.oid
--スキーマ(namespase)特定用
and a1.oid = a3.indexrelid
--インデックスの情報取得
and a3.indrelid = a4.oid
--インデックスが登録されているテーブルの名前特定用
and a5.attnum = any(a3.indkey)
-- インデックスのカラム特定
and a5.attrelid = a3.indrelid
and a3.indisunique = true
and a3.indisprimary = false
and a2.nspname = 'namespace'
order by
    namespase,
    table_name,
    index_name,
    index_position
    -- インデックスの定義順でソート
;

リンク

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8