タイトル: カラム定義の確認
SEOタイトル: DB カラム定義確認完全ガイド (MySQL/PG/Oracle/SQL Server)
| この記事の要点 |
|
カラム定義確認の概要
テーブルにどんなカラムが定義されているか(カラム名・データ型・NULL 可否・デフォルト値・コメント等)を確認する方法は、DB ごとに方言が分かれます。本記事では主要 4 種 DB と代表 ORM での確認方法をまとめます。
MySQL / MariaDB
DESCRIBE / SHOW COLUMNS
-- 最短: DESCRIBE
DESCRIBE users;
DESC users; -- 短縮形
-- SHOW COLUMNS (同等)
SHOW COLUMNS FROM users;
SHOW FULL COLUMNS FROM users; -- コメント列も表示
-- 結果イメージ
-- +-------+--------------+------+-----+---------+----------------+
-- | Field | Type | Null | Key | Default | Extra |
-- +-------+--------------+------+-----+---------+----------------+
-- | id | bigint | NO | PRI | NULL | auto_increment |
-- | name | varchar(255) | NO | | NULL | |
-- | email | varchar(255) | YES | UNI | NULL | |
-- +-------+--------------+------+-----+---------+----------------+
SHOW CREATE TABLE
CREATE TABLE 文を逆生成。ENGINE / CHARSET / インデックス / 外部キーまで全て分かる最強の確認手段。
SHOW CREATE TABLE users\G
-- CREATE TABLE `users` (
-- `id` bigint unsigned NOT NULL AUTO_INCREMENT,
-- `name` varchar(255) NOT NULL,
-- `email` varchar(255) DEFAULT NULL,
-- `created_at` timestamp NULL DEFAULT NULL,
-- PRIMARY KEY (`id`),
-- UNIQUE KEY `users_email_unique` (`email`)
-- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
information_schema.COLUMNS
SELECT column_name, data_type, character_maximum_length,
is_nullable, column_default, column_comment
FROM information_schema.columns
WHERE table_schema = 'myapp'
AND table_name = 'users'
ORDER BY ordinal_position;
-- データ型が enum / set / collation を含む全件取得
SELECT column_name, column_type
FROM information_schema.columns
WHERE table_schema = DATABASE() AND table_name = 'users';
PostgreSQL
psql の \d コマンド
-- 簡易表示
mydb=# \d users
-- 拡張表示(コメント・統計を含む)
mydb=# \d+ users
-- 全テーブル一覧
mydb=# \dt
mydb=# \dt public.*
-- スキーマ別
mydb=# \dn -- スキーマ一覧
mydb=# \dt app.*
-- 索引一覧
mydb=# \di
-- 関数定義
mydb=# \df
mydb=# \sf func_name
information_schema.columns
SELECT column_name, data_type, character_maximum_length,
is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'users'
ORDER BY ordinal_position;
pg_catalog 系
SELECT a.attname AS column_name,
pg_catalog.format_type(a.atttypid, a.atttypmod) AS data_type,
a.attnotnull AS not_null,
pg_get_expr(d.adbin, d.adrelid) AS default
FROM pg_attribute a
LEFT JOIN pg_attrdef d ON d.adrelid = a.attrelid AND d.adnum = a.attnum
WHERE a.attrelid = 'public.users'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum;
Oracle
SQL*Plus DESC
SQL> DESC users
Name Null? Type
----------------- -------- ----------------
ID NOT NULL NUMBER
NAME NOT NULL VARCHAR2(255)
EMAIL VARCHAR2(255)
CREATED_AT TIMESTAMP(6)
ディクショナリビュー
-- 自スキーマのテーブル
SELECT column_name, data_type, data_length, nullable, data_default
FROM user_tab_columns
WHERE table_name = 'USERS'
ORDER BY column_id;
-- 全スキーマ (権限あるもの)
SELECT owner, table_name, column_name, data_type, nullable
FROM all_tab_columns
WHERE owner = 'APP' AND table_name = 'USERS';
-- DBA 権限あり
SELECT * FROM dba_tab_columns WHERE owner = 'APP';
-- 主キー / 索引付き列
SELECT cols.table_name, cols.column_name, cons.constraint_type
FROM user_cons_columns cols
JOIN user_constraints cons ON cols.constraint_name = cons.constraint_name
WHERE cons.constraint_type = 'P'; -- 主キー
DDL を逆生成
SET LONG 100000
SELECT DBMS_METADATA.GET_DDL('TABLE', 'USERS', 'APP') FROM dual;
SQL Server
-- sp_columns 手続き
EXEC sp_columns 'users';
EXEC sp_help 'users'; -- より詳細
-- INFORMATION_SCHEMA
SELECT column_name, data_type, character_maximum_length,
is_nullable, column_default
FROM information_schema.columns
WHERE table_schema = 'dbo' AND table_name = 'users'
ORDER BY ordinal_position;
-- sys.columns
SELECT c.name, t.name AS type, c.max_length, c.is_nullable
FROM sys.columns c
JOIN sys.types t ON c.user_type_id = t.user_type_id
WHERE object_id = OBJECT_ID('dbo.users');
-- 主キー
SELECT i.name, c.name
FROM sys.indexes i
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
WHERE i.is_primary_key = 1 AND i.object_id = OBJECT_ID('dbo.users');
SQLite
-- sqlite3 シェル
sqlite> .schema users
sqlite> .tables
sqlite> PRAGMA table_info(users);
-- SQL 経由
SELECT name, type, "notnull", dflt_value, pk
FROM pragma_table_info('users');
Laravel での確認
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
// カラム名の配列
$cols = Schema::getColumnListing('users');
// → ['id', 'name', 'email', 'password', ...]
// カラム存在チェック
if (Schema::hasColumn('users', 'email_verified_at')) { /* ... */ }
// 個別カラムの型 (Doctrine DBAL 必須)
$type = Schema::getColumnType('users', 'name'); // 'string'
// Doctrine DBAL 経由でメタ情報
$columns = DB::connection()
->getDoctrineSchemaManager()
->listTableColumns('users');
foreach ($columns as $name => $col) {
echo $name . ' : ' . $col->getType()->getName() . PHP_EOL;
}
// 生 SQL で確認
print_r(DB::select('DESCRIBE users'));
print_r(DB::select('SHOW CREATE TABLE users'));
Django / Python の場合
# Django ORM のメタ情報
from myapp.models import User
for f in User._meta.get_fields():
print(f.name, type(f).__name__, getattr(f, 'max_length', None))
# Django 管理コマンド
# python manage.py inspectdb users --table-name-filter=users
# SQLAlchemy
from sqlalchemy import inspect
inspector = inspect(engine)
for col in inspector.get_columns('users'):
print(col['name'], col['type'], col['nullable'])
用途別の早見表
| やりたいこと | MySQL | PostgreSQL | Oracle | SQL Server |
|---|---|---|---|---|
| クイック確認 | DESC users | \d users | DESC users | sp_columns 'users' |
| DDL 逆生成 | SHOW CREATE TABLE | pg_dump -t | DBMS_METADATA.GET_DDL | SSMS のスクリプト生成 |
| 標準ビュー | information_schema.columns | information_schema.columns | USER_TAB_COLUMNS | INFORMATION_SCHEMA.COLUMNS |
| システムカタログ | mysql.* / performance_schema | pg_attribute | DBA_TAB_COLUMNS | sys.columns |
FAQ
Q: information_schema と システムカタログ、どちらを使うべき?
A: 移植性を重視するなら information_schema(SQL 標準)、DB 固有機能 (PG の partial index 等) を見るならシステムカタログ。
Q: 大量のテーブルから特定の名前のカラムを横断検索したい
A: SELECT table_name FROM information_schema.columns WHERE column_name = 'user_id' で全テーブルから抽出できます。
Q: 本番でいきなり SHOW FULL COLUMNS を打って良い?
A: 軽量メタデータクエリなので影響はほぼゼロです。ただし MySQL 5.7 以前で information_schema を全テーブル走査すると重いので、WHERE table_schema = 'mydb' で絞りましょう。