カラム情報は、実DBとモデル定義を分けて確認する
メタデータ親ページから子ページを選択できます。本記事はその実子で、対話コマンドの使い分けはテーブル定義の確認へ進めます。MySQL/MariaDBの手順を中心に、既存の他製品・ORMの比較も条件付きで保持しています。
2026-10-26にMySQL8.4.13 / MariaDB11.8.9-ubu2404、既存のLaravel13.34.0 / Django5.2.18で新規検体を確認しました。新しい依存・本番DBの権限/設定・アプリの.envは変更していません。旧版の全コードや他DB/全driverまで実行した保証ではありません。
1. schema/表を絞り、列の順序と属性を読む
以下は定義確認記事で準備した使い捨て検体用です。名前を省略して全DBを走査せず、対象と権限を先に確認します。アプリから値を渡す場合は値をバインドし、識別子との違いにも注意します。
SELECT TABLE_SCHEMA,TABLE_NAME,ORDINAL_POSITION,COLUMN_NAME,
DATA_TYPE,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,
CHARACTER_SET_NAME,COLLATION_NAME,EXTRA,COLUMN_COMMENT
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA='cwiki_w28' AND TABLE_NAME='users'
ORDER BY ORDINAL_POSITION;
検体ではid/email/display_name/no_default/blank_default/generated_lengthの6列がORDINAL_POSITION順に見えました。COLUMN_TYPEのunsigned、NULL、既定値、charset/collation、生成列のEXTRA、COMMENTをそれぞれ確認します。生成式や索引/制約の全定義までこの1照会だけで分かったとは扱いません。
列権限をid/emailだけにした接続では同じ照会が2列になりました。空欄/NULL/0件は「ない」の断定ではなく、項目の意味・製品の表示形式・権限・対象を調べます。内部のカラム名やコメント、定義全文を公開ログへそのまま出しません。
2. Laravelの現行ネイティブAPIを確認する
Laravel13にはgetColumns/getColumnType等のネイティブなSchema APIがあります。DBALを一律に必須とせず、旧getDoctrineSchemaManagerを現行版の操作としてそのまま呼びません。既存アプリでは接続alias/権限に合わせます。次は既存vendorだけを使うstandaloneの検体用コードで、本番bootstrapや資格情報を読み込みません。
新規検体のusersだけSELECTできるmetadata_readerと、一時port/passwordを実行環境に用意した場合の例です。環境変数CWIKI_METADATA_PORT / CWIKI_METADATA_PASSWORDは検体のものだけを使い、本番の.envや既存poolを変更しません。
PHPのrequireは検体用ファイル配置と既存vendorの位置を前提にしています。任意のアプリへそのまま置く完成設定ではなく、検体のautoload配置/driver/依存版も照合します。
<?php
// Standalone disposable fixture; do not load production bootstrap or credentials.
require dirname(__DIR__,4).'/vendor/autoload.php';
use Illuminate\Database\Capsule\Manager as Capsule;
$port=filter_var(getenv('CWIKI_METADATA_PORT'),FILTER_VALIDATE_INT);
$password=getenv('CWIKI_METADATA_PASSWORD');
if(PHP_SAPI!=='cli'||!$port||$port<1||$port>65535||!is_string($password)||$password==='')throw new RuntimeException('Fixture environment required');
$capsule=new Capsule;
$capsule->addConnection(['driver'=>'mysql','host'=>'127.0.0.1','port'=>$port,'database'=>'cwiki_w28','username'=>'metadata_reader','password'=>$password,'charset'=>'utf8mb4']);
$schema=$capsule->getConnection()->getSchemaBuilder();
$columns=$schema->getColumns('users');
echo json_encode(['laravel'=>Illuminate\Foundation\Application::VERSION,'database_columns'=>array_column($columns,'name'),'email_type'=>$schema->getColumnType('users','email'),'missing_column'=>$schema->hasColumn('users','missing_fixture_column')],JSON_THROW_ON_ERROR);
検体ではDB側の6列、email_typeのvarchar、存在しない列のfalseを取得しました。列名の配列や型1つだけで、全DEFAULT/生成式/複合キー/復旧用DDLを得たとは扱いません。今回は既存アプリの認証/FPMからの実操作や、旧DBAL APIの全版互換は未検証です。
3. Djangoのモデルと実DBの差を見落とさない
Model._meta.get_fields()はモデル定義の情報で、実DBへ問い合わせて一致を保証する機能ではありません。次はid/emailだけを宣言したmanaged=Falseの検体モデルと、読取専用接続による実DB introspectionを比較します。project設定を読み込まず、migrateやモデル作成は実行しません。
"""Standalone fixture, no project settings, migrations or production connection."""
import json
import os
from django.conf import settings
port=int(os.environ['CWIKI_METADATA_PORT'])
if not 1<=port<=65535 or not os.environ['CWIKI_METADATA_PASSWORD']:
raise RuntimeError('Fixture environment required')
settings.configure(INSTALLED_APPS=[],DATABASES={'default':{
'ENGINE':'django.db.backends.mysql','HOST':'127.0.0.1','PORT':port,
'NAME':'cwiki_w28','USER':'metadata_reader','PASSWORD':os.environ['CWIKI_METADATA_PASSWORD'],
}})
import django
django.setup()
from django.db import connection,models
class DeclaredUser(models.Model):
id=models.IntegerField(primary_key=True)
email=models.CharField(max_length=40)
class Meta:
app_label='isolated_metadata'
db_table='users'
managed=False
try:
model_fields=[f.name for f in DeclaredUser._meta.get_fields()]
with connection.cursor() as cursor:
database_columns=[c.name for c in connection.introspection.get_table_description(cursor,'users')]
print(json.dumps({'model_fields':model_fields,'database_columns':database_columns}))
finally:
connection.close()
モデルの項目は2つ、DBの列は6つになりました。差があることを理由にDBへ列を追加/削除せず、接続alias・既存schema・未反映変更・モデルの対象を調べます。inspectdbは別の逆生成処理で、Django5.2の対象指定は位置引数と--databaseです。旧コメントの--table-name-filterは今回のCLI parserに存在せず、そのまま実行しません。生成したモデルも完全な正本/移行計画とは扱わず確認します。
4. 他DBのコマンドや旧出力を転用しない
psql/SQL*Plus/sqlite3のプロンプトや\d/\G/SET LONG等は、それぞれのクライアント操作とSQLを区別します。SQLiteのtable_infoは生成/hidden列を全て含む照会ではなく、必要な場合は対象版のtable_xinfo等を確認します。Oracle/SQL Serverの権限やschema/列順も別です。後の元のinformation_schema.COLUMNS出力は当時の例として保持し、現行版の列数/型長が完全一致するとは主張しません。
| この記事の要点 |
|
カラム定義確認の概要
テーブルにどんなカラムが定義されているか(カラム名・データ型・NULL 可否・デフォルト値・コメント等)を確認する方法は、DB ごとに方言が分かれます。本記事では主要 4 種 DB と代表 ORM での確認方法をまとめます。
MySQL / MariaDB
DESCRIBE / SHOW COLUMNS
旧例の注意:MySQL/MariaDBの別例です。サンプル出力の列/Key/Defaultだけで全定義を判断せず、権限・対象・生成列等を確認します。
-- 最短: 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 / インデックス / 外部キー等の表定義を確認します。行/trigger/全依存の復旧や全項目の可視性を保証するものではありません。
旧例の注意:CREATEの表示例で、行/trigger/権限/全依存のbackupではありません。\Gをdriver SQLとして送らず、出力を実表へ再実行しません。
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
旧例の注意:COLUMN_TYPEだけではcollationや生成式の全情報は取得できません。schema/表/列順と必要な属性を別に照合します。
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 コマンド
旧例の注意:PGのpsqlプロンプト/メタコマンドです。そのままdriver SQLへ送らず、schema/識別子と実接続を確認します。
-- 簡易表示
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
旧例の注意:PG用の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 系
旧例の注意:PGカタログ例です。regclassの対象/権限/名前の引用と生成列等の対象版を調べ、全定義の完全再現としません。
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*Plusの表示例です。プロンプトや出力をSQLとして流しません。
SQL> DESC users
Name Null? Type
----------------- -------- ----------------
ID NOT NULL NUMBER
NAME NOT NULL VARCHAR2(255)
EMAIL VARCHAR2(255)
CREATED_AT TIMESTAMP(6)
ディクショナリビュー
旧例の注意:OracleのUSER/ALL/DBAを区別します。既存主キー照会はUSER系なので同じ所有範囲内の結合であり、他schemaを混ぜる取得とは分けます。複合列順は別途確認します。
-- 自スキーマのテーブル
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 を逆生成
旧例の注意:SQL*PlusのSET LONGはクライアント表示設定です。DBMS_METADATAの所有者/権限/出力範囲を確認し、完全復旧とは扱いません。
SET LONG 100000
SELECT DBMS_METADATA.GET_DDL('TABLE', 'USERS', 'APP') FROM dual;
SQL Server
旧例の注意:SQL Server用です。schema/対象とキー順を絞り、名前だけの一致や表示長を全製品へ転用しません。
-- 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
旧例の注意:SQLiteのシェル操作とSQLを分けます。table_infoは生成/hidden列を全て返すものではなく、対象版のtable_xinfo等を調べます。
-- 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 での確認
旧例の注意:旧Laravelの例です。現行13ではDBAL必須ではなく、旧getDoctrineSchemaManagerは利用できません。型名の表示やAPIの対象版も違うため、新しい検体のnative APIを参照します。
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 の場合
旧例の注意:モデル._metaは実DBの照会ではありません。旧inspectdbのtable-name-filterは今回5.2 parserにないオプションで、SQLAlchemyも対象接続/schema/版に合わせます。依存の追加やmigrateを診断の準備にしません。
# 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 -s -t(-tは対象、-sは定義のみ。依存範囲も確認) | DBMS_METADATA.GET_DDL | SSMS のスクリプト生成 |
| メタデータ参照(製品別) | information_schema.columns | information_schema.columns | USER_TAB_COLUMNS | INFORMATION_SCHEMA.COLUMNS |
| システムカタログ | information_schema中心。用途別のperformance_schema等と区別 | pg_attribute | DBA_TAB_COLUMNS | sys.columns |
FAQ
Q: information_schema と システムカタログ、どちらを使うべき?
A: 移植性を重視するなら information_schema(SQL 標準)、DB 固有機能 (PG の partial index 等) を見るならシステムカタログ。
Q: 大量のテーブルから特定の名前のカラムを横断検索したい
A: schema/対象/可視範囲を限定して検索し、schema名・表名・列名と列順も返します。権限で見えない対象を含む全DB/全表を取得できたとは扱いません。
Q: 本番でいきなり SHOW FULL COLUMNS を打って良い?
A: 読取でも負荷/metadata lock/対象数/権限/キャッシュと製品版を確認します。無影響/常に軽量とは断定せず、対象schema/表を限定します。確認のために設定/権限を追加しません。
元のCOLUMNS出力と検索例
元v2の2表を当時の記録として保持します。固定の出力見本を現行DBの仕様表へ読み替えません。
INFORMATION_SCHEMA.COLUMNSテーブルにカラム定義が格納されている。
旧例の注意:当時のinformation_schema.COLUMNSの出力例です。現行版の列数/型長/既定値との完全一致や、mysqlプロンプト込みのSQL実行を保証しません。
| mysql> DESC INFORMATION_SCHEMA.COLUMNS; +--------------------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +--------------------------+---------------------+------+-----+---------+-------+ | TABLE_CATALOG | varchar(512) | NO | | | | | TABLE_SCHEMA | varchar(64) | NO | | | | | TABLE_NAME | varchar(64) | NO | | | | | COLUMN_NAME | varchar(64) | NO | | | | | ORDINAL_POSITION | bigint(21) unsigned | NO | | 0 | | | COLUMN_DEFAULT | longtext | YES | | NULL | | | IS_NULLABLE | varchar(3) | NO | | | | | DATA_TYPE | varchar(64) | NO | | | | | CHARACTER_MAXIMUM_LENGTH | bigint(21) unsigned | YES | | NULL | | | CHARACTER_OCTET_LENGTH | bigint(21) unsigned | YES | | NULL | | | NUMERIC_PRECISION | bigint(21) unsigned | YES | | NULL | | | NUMERIC_SCALE | bigint(21) unsigned | YES | | NULL | | | DATETIME_PRECISION | bigint(21) unsigned | YES | | NULL | | | CHARACTER_SET_NAME | varchar(32) | YES | | NULL | | | COLLATION_NAME | varchar(32) | YES | | NULL | | | COLUMN_TYPE | longtext | NO | | NULL | | | COLUMN_KEY | varchar(3) | NO | | | | | EXTRA | varchar(30) | NO | | | | | PRIVILEGES | varchar(80) | NO | | | | | COLUMN_COMMENT | varchar(1024) | NO | | | | +--------------------------+---------------------+------+-----+---------+-------+ |
例えば、TESTと名の付くカラムを持つテーブルを検索したい場合は、以下のコマンドを実行する。
旧例の注意:schema条件のない旧検索例です。可視範囲全体を走査し得るため、新規検体でも対象schema/表を限定して確認します。
| SELECT TABLE_NAME, COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME LIKE '%TEST%'; |
確認範囲と一次資料
新規の小規模InnoDB検体と限定した読取権限で確認した範囲です。全負荷/全権限/全製品・全GUI/旧dumpの実行・本番復旧/既存アプリの全設定を保証せず、調査のために本番設定/依存/権限を追加していません。
- MySQL8.4 SHOW COLUMNS / SHOW CREATE TABLE / STATISTICS / mysqldump
- MariaDB SHOW COLUMNS / PostgreSQL18 information schema
- Laravel13のDB確認 / Django5.2モデルのmeta / inspectdb / SQLite PRAGMA
子ページはありません
同階層のページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- MySQL/MariaDBのテーブル一覧|表・ビュー・権限と絞り込み 2026-10-26 07:32:39
- MySQL/MariaDBのDB選択|USEと接続・既定DBの違い 2026-10-26 07:32:39
- MySQL/MariaDBのDB一覧|SHOW DATABASESと権限の違い 2026-10-26 07:32:39
- MySQLへの接続|接続先・認証・TLSとエラーの確認 2026-10-26 07:32:39
- MySQL/MariaDBのカラム定義確認|権限・既定値・ORMとの違い 2026-10-26 06:18:53
- MySQL/MariaDBのメタデータ|列・索引・制約の確認ガイド 2026-10-26 06:18:53
- MySQL/MariaDBのテーブル定義確認|DESC・SHOW CREATEと復旧の範囲 2026-10-26 06:18:53
- MySQL/MariaDBのAUTO_INCREMENT追加・確認|既存IDと属性の保持 2026-10-26 05:42:11
- MySQL/MariaDBのAUTO_INCREMENT|欠番・取得ID・カウンタの違い 2026-10-26 05:42:11
- MySQL/MariaDBの索引削除|不可視化・UNIQUE・外部キーの注意 2026-10-26 05:11:35
- MySQL/MariaDBの索引作成|結果比較・UNIQUE・実行計画の確認 2026-10-26 05:11:35
- MySQL/MariaDBの外部キー|制約名・参照切れ・削除と再検査 2026-10-26 04:51:08
- MySQL/MariaDBのカラム追加・削除|既存値・互換性・ロックの確認 2026-10-26 04:51:08
- MySQL/MariaDBのカラム名変更|RENAME COLUMNと利用側の確認 2026-10-26 04:24:55
- MySQL/MariaDBのカラム定義変更|MODIFYの属性保持とロック 2026-10-26 04:24:55