MySQLで指定したカラム名を持つテーブルを検索する|information_schemaを使ったDB横断検索

運営:リナックスマスター.JP(代表 宮崎智広)
HOME > Linux技術 リナックスマスター.JP(Linuxマスター.JP) > Linuxtips > Linuxtips, MySQL, サーバー管理, データーベース管理 > MySQLで指定したカラム名を持つテーブルを検索する|information_schemaを使ったDB横断検索
「特定のカラム名を持つテーブルが、どのDBのどこに存在するかわからない」
「テーブル定義を直接見ても、目的のカラムが見つからない」
DBA経験のあるエンジニアなら一度は遭遇する場面です。

この記事では、MySQLで指定したカラム名を持つテーブルを検索する方法を、information_schemaを使った実コマンド付きで解説します。MySQL 5.7 / MySQL 8.0 / MariaDB 10.x を想定したSQLです。

この記事のポイント

・information_schema.columnsをSELECTすればMySQL内のカラム検索が一発でできる
・table_schemaを条件に加えると、特定データベースに絞った検索が可能
・LIKE演算子で部分一致検索(user_%・%_idなど)にも対応
・MariaDB / MySQL 8.0 でも同じSQLがそのまま動く(標準化済みのスキーマ)


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

MySQLで指定したカラム名を持つテーブルを検索する基本SQL

MySQLで特定のカラム名を持つテーブルがわからない場合、下記SQLを発行することで検索が行えます。

MySQLにログイン後、下記SQLを実行します。

select table_name, column_name from information_schema.columns where column_name = '検索したいカラム名';

例)site_urlというカラムを持つテーブルを検索します。

mysql> select table_name, column_name from information_schema.columns where column_name = 'site_url'; +----------------+-------------+ | table_name | column_name | +----------------+-------------+ | gl_pingservice | site_url | +----------------+-------------+ 1 row in set (0.21 sec)

gl_pingserviceテーブルにsite_urlが存在していることが分かります。

information_schemaとは何か:MySQLのメタデータが集約された仮想DB

information_schemaは、MySQLが内部的に保持する「DB/テーブル/カラム/インデックスの定義情報」を、SQLで参照できるよう仮想テーブル化したデータベースです。

標準SQLのANSI/ISO規格に準拠しているため、MySQL 5.5以降、MariaDB 5.x以降、PostgreSQL(こちらはinformation_schemaを完全サポート)でほぼ同じSQLが動きます。

主要なテーブルは以下です。

・SCHEMATA:データベース(スキーマ)一覧
・TABLES:テーブル/ビュー一覧。TABLE_ROWSで大まかな行数、DATA_LENGTHでデータサイズも確認できる
・COLUMNS:全カラム情報(型・NULL許容・デフォルト値含む)。この記事のメインテーマ
・STATISTICS:インデックス情報。未使用インデックスの棚卸しやスロークエリの原因調査に活用できる
・VIEWS:ビューの定義SQL
・TRIGGERS:トリガー定義
・PROCESSLIST:現在の接続/クエリ一覧(SHOW PROCESSLIST相当)。COMMAND / STATE / TIMEをSQLで絞り込めるため、ロック待ちやスロークエリをピンポイントで探す場面でも有効

なかでもTABLES・COLUMNS・STATISTICSは日常的な保守作業で頻出します。PROCESSLISTはサーバーが重いときの第一調査として欠かせません。

特定のデータベースに絞ってカラム検索する:table_schemaの活用

本番環境では複数DBが共存しているため、検索対象のDBを絞り込まないと無関係なテーブルがヒットします。table_schemaを条件に加えます。

mysql> select table_schema, table_name, column_name -> from information_schema.columns -> where column_name = 'user_id' -> and table_schema = 'wordpress'; +--------------+----------------+-------------+ | table_schema | table_name | column_name | +--------------+----------------+-------------+ | wordpress | wp_usermeta | user_id | | wordpress | wp_comments | user_id | | wordpress | wp_links | link_owner | +--------------+----------------+-------------+ 3 rows in set (0.03 sec)

逆に「mysql / sys / performance_schema / information_schema」のシステムDBを除外する条件もよく使います。

mysql> select table_schema, table_name, column_name -> from information_schema.columns -> where column_name = 'created_at' -> and table_schema not in ('mysql','sys','performance_schema','information_schema');

LIKE演算子で部分一致検索する:カラム名がうろ覚えの時の探し方

カラム名の正確な綴りが分からない場合は、LIKE演算子を使って部分一致検索ができます。

# 「user_」で始まるカラムをすべて検索 mysql> select table_name, column_name -> from information_schema.columns -> where column_name like 'user_%' -> and table_schema = 'wordpress'; # 「_id」で終わるカラムをすべて検索(外部キー候補の洗い出し) mysql> select table_name, column_name -> from information_schema.columns -> where column_name like '%_id' -> and table_schema = 'wordpress'; # 「mail」を含むカラムをすべて検索(個人情報棚卸し) mysql> select table_schema, table_name, column_name -> from information_schema.columns -> where column_name like '%mail%' -> and table_schema not in ('mysql','sys','performance_schema','information_schema');

最後の例は個人情報を扱うシステムの棚卸しでよく使われるテクニックです。GDPRやプライバシーポリシーの準拠確認で、メールアドレスや氏名などのPII(個人識別情報)を含むカラムをDB横断で洗い出す際にも応用できます。

カラムの型・NULL許容・デフォルト値まで含めて取得する

column_nameだけでなく、データ型・NULL許容・デフォルト値も同時に取得すると、テーブル定義の概要が一気に把握できます。

mysql> select table_name, column_name, data_type, is_nullable, column_default, column_key -> from information_schema.columns -> where column_name = 'site_url'; +----------------+-------------+-----------+-------------+----------------+------------+ | table_name | column_name | data_type | is_nullable | column_default | column_key | +----------------+-------------+-----------+-------------+----------------+------------+ | gl_pingservice | site_url | varchar | NO | NULL | PRI | +----------------+-------------+-----------+-------------+----------------+------------+ 1 row in set (0.04 sec)

column_keyの「PRI」はプライマリキー、「UNI」はユニーク制約、「MUL」は複合インデックスの一部、を示します。

column_typeを追加すると、varcharの文字数制限(varchar(255)など)やintの符号なし(int unsigned)まで確認できます。SELECT対象にordinal_positionを加えてORDER BYすれば、テーブル定義書の自動生成にも応用できます。

# column_typeまで含めた詳細な定義取得(テーブル定義書の素材として活用) mysql> select table_name, column_name, column_type, is_nullable, column_default, column_key, extra -> from information_schema.columns -> where table_schema = 'wordpress' -> order by table_name, ordinal_position;

SHOW COLUMNSとの違い:いつinformation_schemaを使うべきか

MySQLには昔から SHOW COLUMNS というコマンドがありますが、これは「1つのテーブルのカラムを一覧表示する」用途専用です。

mysql> SHOW COLUMNS FROM gl_pingservice; +-------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+-------+ | site_url | varchar(255) | NO | PRI | NULL | | | service_url | varchar(255) | YES | | NULL | | +-------------+--------------+------+-----+---------+-------+

「テーブルが分かっていてカラム一覧を見たい」場合はSHOW COLUMNSが手軽です。「カラム名は分かるがテーブルが分からない」「全DB横断で検索したい」場合はinformation_schemaが必須です。

使い分けをまとめると以下のとおりです。
状況 使うべきコマンド
テーブルが分かっていてカラム一覧を見たい SHOW COLUMNS FROM テーブル名;
カラム名からテーブルを特定したい SELECT ... FROM information_schema.columns WHERE column_name = '...';
複数DBをまたいで検索したい SELECT ... FROM information_schema.columns WHERE column_name = '...';
スクリプトやcronで結果を取得したい mysql -e "SELECT ..."(information_schema経由)

シェルから直接クエリを実行する:mysqlコマンドの-eオプション

information_schemaへのクエリは、シェルスクリプトに組み込んで自動化することが多いです。mysqlコマンドに-eオプションを渡せば、対話モードに入らずにクエリ結果を取得できます。

[root@db01 ~]# mysql -uroot -pXXXX -e "select table_schema, table_name from information_schema.columns where column_name = 'email' and table_schema not in ('mysql','sys','performance_schema','information_schema');" # CSV出力する場合は --batch --raw を併用 [root@db01 ~]# mysql -uroot -pXXXX --batch --raw -e "select table_schema, table_name from information_schema.columns where column_name = 'email';" > /tmp/email_columns.tsv

定期的な棚卸し(GDPRやプライバシー監査など)にcronで仕掛けるとミスが減ります。

【重要】information_schema検索の性能上の注意点

情報系SQLの落とし穴を3つ挙げておきます。

・巨大DBではinformation_schema.columnsが重い:テーブル数が10万を超えるような大規模DBでは、columns全件スキャンに数十秒かかります。MySQL 8.0ではdata dictionaryに改良が入り高速化されていますが、5.7では本番LATENCYに影響します。
・権限がないDBは見えない:information_schemaは「権限のあるDB」しか表示しません。rootならば全部見えますが、アプリ用ユーザーで実行すると結果が空になることがあります。
・テーブル名・カラム名の大文字小文字:Linux環境ではデフォルトで大文字小文字を区別します(lower_case_table_names=0)。site_urlとSite_URLは別物として扱われるので、BINARYやLOWER()を使う場面があります。

# 大文字小文字を無視して検索 mysql> select table_name, column_name -> from information_schema.columns -> where lower(column_name) = lower('Site_URL');

MySQL 8.0ではdata dictionaryの内部構造が刷新されており、5.7と比べてinformation_schema全般のクエリ性能が改善しています。大規模な保守作業でMySQLのバージョンを選べる状況があれば、8.0以降を選択するのが現実的です。

「ERROR 1044: Access denied」が出た時の対処

information_schemaへのアクセスでエラーが出る場合の対処を整理します。

# エラー: 権限不足 mysql> select * from information_schema.columns; ERROR 1044 (42000): Access denied for user 'app'@'localhost' to database 'information_schema' # 対処: rootで該当ユーザーに権限付与 mysql> GRANT SELECT ON information_schema.* TO 'app'@'localhost'; mysql> FLUSH PRIVILEGES; # エラー: 結果が空になる mysql> select * from information_schema.columns where column_name = 'user_id'; Empty set (0.00 sec) # 対処: そのユーザーがアクセス可能なDBにそもそもuser_idが存在しないことを確認 mysql> SHOW DATABASES;

本記事のまとめ:MySQLカラム検索SQL早見表

information_schemaを使いこなせると、巨大DBの保守・棚卸しが圧倒的に楽になります。
やりたいこと コマンド
カラム名でテーブル検索 select table_name, column_name from information_schema.columns where column_name = 'site_url';
特定DBに絞って検索 select table_name from information_schema.columns where column_name = 'user_id' and table_schema = 'wordpress';
部分一致でカラム検索 select table_name, column_name from information_schema.columns where column_name like '%mail%';
カラム型まで取得 select table_name, column_name, data_type, is_nullable from information_schema.columns where column_name = 'site_url';
システムDB除外検索 select table_schema, table_name from information_schema.columns where column_name = 'email' and table_schema not in ('mysql','sys','performance_schema','information_schema');
シェルから一発実行 mysql -uroot -pXXXX -e "select table_name from information_schema.columns where column_name = 'email';"
単一テーブルのカラム一覧 SHOW COLUMNS FROM gl_pingservice;
大文字小文字を無視して検索 select table_name from information_schema.columns where lower(column_name) = lower('Site_URL');
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、information_schemaを含むMySQLのデータベース運用・保守の実務知識を、2日間の少人数ハンズオンで習得できます。
>> Linux Master Pro Seminarの詳細はこちら

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録

運営

リナックスマスター.JP(代表 宮崎智広)

株式会社イーネットマーキュリーが運営するLinux教育サイトです。代表の宮崎智広は現役のLinuxサーバー管理者として20年以上の実務経験を持ち、累計3,100名以上のエンジニアを指導してきました。実践型のLinuxセミナーや無料マニュアルの配布を通じてLinux人材の育成に取り組んでいます。