COLUMN_DEFAULT为NULL时需结合IS_NULLABLE和建表语句区分“无默认值”与“DEFAULT NULL”;MySQL 8.0+新增GENERATION_EXPRESSION字段支持生成列查询,5.7及以前版本不兼容;SHOW CREATE TABLE适用于DDL迁移审计,information_schema.COLUMNS适用于程序化解析。

直接查 information_schema 是最可控、最可编程的方式,但必须注意字段语义歧义、版本兼容性和权限限制——它不是“万能视图”,而是元数据快照。
查列定义时为什么 COLUMN_DEFAULT 有时是 NULL,有时是字符串 'NULL'?
这个字段的值取决于建表时是否显式写了 DEFAULT NULL。如果字段定义为 name VARCHAR(50) DEFAULT NULL,COLUMN_DEFAULT 值就是 NULL(SQL NULL);如果定义为 name VARCHAR(50)(没写 DEFAULT),该字段也是 NULL,但含义不同:前者是“显式设默认为 NULL”,后者是“无默认值”。真正判断是否允许为空,得看 IS_NULLABLE = 'YES'。
- 只靠
COLUMN_DEFAULT IS NULL无法区分“未设默认”和“设了 DEFAULT NULL” - 必须结合
IS_NULLABLE和建表语句上下文才能准确还原语义 - MySQL 8.0+ 新增的
GENERATION_EXPRESSION字段可识别生成列,5.7 及以前查这个字段会报错Unknown column 'GENERATION_EXPRESSION' in 'field list'
用 SHOW CREATE TABLE 还是 information_schema.COLUMNS?
目的决定选法:SHOW CREATE TABLE 返回原始 DDL,适合迁移、审计、比对;information_schema.COLUMNS 返回结构化字段,适合程序解析、批量分析、生成文档。
- DDL 场景必用
SHOW CREATE TABLE `db_name`.`table_name`(反引号+全库名,防关键字和上下文切换问题) - 返回结果第二列字段名固定是
Create Table,不是小写或下划线变体 - 该语句不走查询缓存,但高频调用可能触发元数据锁等待,线上避免每秒多次执行
- 想查索引、主键、外键,
COLUMNS表完全不够——得分别查STATISTICS(索引结构)、KEY_COLUMN_USAGE(约束映射)
为什么查不到主键?常见误判点在哪?
很多人在 STATISTICS 表里看到 INDEX_NAME = 'PRIMARY' 就以为找到了主键,但漏掉了关键过滤条件。
- 真正主键的判定条件是:
INDEX_NAME = 'PRIMARY'且NON_UNIQUE = 0 -
SEQ_IN_INDEX = 1只表示字段在索引中的顺序,不能用来判断是否为主键 - 复合主键会有多行记录,需按
SEQ_IN_INDEX排序后拼接字段名 - 要查外键关联目标,必须查
KEY_COLUMN_USAGE表,并过滤REFERENCED_TABLE_NAME IS NOT NULL
自动化脚本里最容易忽略的三个细节
写 Python 或 Shell 批量查元数据时,以下三点不处理,轻则结果错乱,重则 SQL 报错或权限拒绝。
- 数据库名、表名必须用反引号包裹,否则遇到
order、group这类关键字直接语法错误 - 连接用户必须有
SELECT权限 oninformation_schema.*,仅SELECTon 某个业务库是不够的 - MySQL 5.7 默认开启
sql_mode=STRICT_TRANS_TABLES,若脚本里用GROUP_CONCAT拼接字段但没设group_concat_max_len,超长字段会被截断且无提示
元数据不是静态文档,它是实时读取的数据字典快照。任何自动化逻辑都得把版本差异、权限边界、字段语义模糊性当作前提来设计,而不是当成例外去兜底。


















