查表结构首选 information_schema.columns,需指定 table_schema 和 table_name;show create table 用于获取完整 ddl;索引和约束须结合 statistics、key_column_usage、table_constraints 查询,注意版本差异与 null 含义。

查表结构用 information_schema.columns 最直接
想看某个表字段名、类型、是否为空、默认值这些基础定义,information_schema.columns 是最常用也最稳妥的入口。它不依赖 MySQL 版本(5.7+ 和 8.0 都行),也不需要额外权限(只要对目标库有 SELECT 权限即可)。
常见错误是漏写 table_schema 条件,导致查出所有库的同名表——尤其当多个库都有 users 表时,结果会混在一起。
实操建议:
- 必须同时指定
table_schema和table_name,例如:SELECT column_name, data_type, is_nullable, column_default FROM information_schema.columns WHERE table_schema = 'mydb' AND table_name = 'user_profile';
- 注意
column_default字段对 NULL 默认值返回的是NULL(值为空),不是字符串'NULL';而显式定义DEFAULT NULL时,该字段值为NULL,但含义不同,需结合is_nullable判断 - MySQL 8.0 中新增了
generation_expression字段,可查生成列表达式;5.7 及以前版本没有这个字段,查询会报错,如需兼容就得先判断版本或忽略该字段
要看建表语句就用 SHOW CREATE TABLE
如果目标是还原 DDL(比如迁移、比对、审计),SHOW CREATE TABLE 比查 information_schema 更准——它返回的就是实际执行过的建表语句,包含引擎、字符集、索引、注释、外键等完整信息。
容易踩的坑是直接在应用代码里拼接 SQL 执行它,却没处理返回结果里的换行和引号,导致解析失败;还有人误以为它能跨库执行,其实必须先 USE db_name 或用反引号明确写全名。
实操建议:
- 推荐写法:
SHOW CREATE TABLE `mydb`.`order_log`;(用反引号避免关键字冲突,显式带库名防切换上下文出错) - 返回结果第二列是建表语句,字段名为
Create Table,注意不是create_table或其他变体 - 该语句不走查询缓存,每次都是实时读取 frm(或数据字典),性能开销极小,但频繁调用仍可能触发元数据锁等待,线上高频调用需谨慎
查索引和约束得盯紧 information_schema.statistics 和 key_column_usage
单靠 columns 表看不出哪个字段是主键、哪个加了唯一索引、外键关联到哪——这些得分别查 statistics(索引结构)和 key_column_usage(约束映射)。
典型问题是把 statistics 里的 seq_in_index = 1 当成“主键标志”,其实它只表示字段在索引中的顺序;真正判断主键得看 index_name = 'PRIMARY',且 non_unique = 0。
实操建议:
- 查主键字段:
SELECT column_name FROM information_schema.key_column_usage WHERE table_schema = 'mydb' AND table_name = 'product' AND constraint_name = 'PRIMARY';
- 查唯一索引字段(不含主键):
SELECT column_name FROM information_schema.statistics WHERE table_schema = 'mydb' AND table_name = 'product' AND index_name != 'PRIMARY' AND non_unique = 0;
- MySQL 8.0 后
statistics表部分字段(如cardinality)可能为NULL,因统计信息异步更新,不能用于判断索引有效性
别忘了 information_schema.table_constraints 是查外键关系的唯一可靠来源
外键约束的引用库、引用表、更新/删除规则这些信息,SHOW CREATE TABLE 虽然会显示,但格式不统一(比如 5.7 和 8.0 的外键语法略有差异),解析困难;而 table_constraints 和 key_column_usage 组合才是程序化读取的稳定方式。
一个常被忽略的细节:外键约束名(constraint_name)在同一个库内必须唯一,但不同库可以重名——所以查的时候 table_schema 不可省略,否则可能匹配到其他库的同名约束。
实操建议:
- 先定位外键约束:
SELECT constraint_name, constraint_type FROM information_schema.table_constraints WHERE table_schema = 'mydb' AND table_name = 'order_item' AND constraint_type = 'FOREIGN KEY';
- 再查具体列映射:
SELECT column_name, referenced_table_name, referenced_column_name FROM information_schema.key_column_usage WHERE table_schema = 'mydb' AND table_name = 'order_item' AND constraint_name = 'fk_order_item_product_id';
- 注意
referenced_table_schema字段在跨库外键中才有值,本地库外键该字段为NULL,别拿它做非空判断
table_schema、混淆 column_default 的 NULL 含义、或者把 statistics.cardinality 当实时指标用。











