MySQL Information Schema完全指南(实战)
Information Schema 做什么用的?
Information Schema 是 MySQL 提供的一个系统数据库,包含了数据库服务器的所有元数据信息(metadata)。它就像是 MySQL 的”数据字典”或”目录”,记录了所有数据库、表、列、索引、权限等对象的详细信息。
核心特点
1 | 1. 只读数据库 : 所有表都是视图,不能直接修改 |
Information Schema vs Performance Schema
| 特性 | Information Schema | Performance Schema |
|---|---|---|
| 用途 | 元数据查询(表结构、索引、权限等) | 性能监控(SQL执行、锁等待、I/O等) |
| 数据类型 | 静态元数据 | 动态运行时数据 |
| 数据来源 | 数据字典 | 运行时收集 |
| 典型查询 | “这个库有哪些表?” | “哪些SQL最慢?” |
| 使用频率 | 高(日常查询结构) | 中(性能调优时) |
| 性能开销 | 极小 | 可配置(默认小) |
Information Schema 的核心表
Information Schema 包含约 60+ 张视图,按功能分为以下几类:
1 | 1. 数据库与表信息 |
一、数据库与表信息
1. SCHEMATA - 数据库信息
作用: 查询所有数据库的基本信息。
1 | -- 查看所有数据库 |
重要字段:
| 字段 | 说明 |
|---|---|
SCHEMA_NAME |
数据库名称 |
DEFAULT_CHARACTER_SET_NAME |
默认字符集 |
DEFAULT_COLLATION_NAME |
默认排序规则 |
SQL_PATH |
SQL 路径(通常为 NULL) |
2. TABLES - 表信息
作用: 查询所有表的详细信息,包括表类型、存储引擎、行数、数据大小等。
1 | -- 查看某个数据库的所有表,表的记录数等信息 |
重要字段:
| 字段 | 说明 |
|---|---|
TABLE_SCHEMA |
数据库名 |
TABLE_NAME |
表名 |
TABLE_TYPE |
表类型: BASE TABLE(普通表), VIEW(视图), SYSTEM VIEW |
ENGINE |
存储引擎: InnoDB, MyISAM, MEMORY 等 |
VERSION |
表的版本号 |
ROW_FORMAT |
行格式: Dynamic, Compact, Redundant, Compressed |
TABLE_ROWS |
表行数(估算值,InnoDB 不准确) |
AVG_ROW_LENGTH |
平均行长度(字节) |
DATA_LENGTH |
数据大小(字节) |
MAX_DATA_LENGTH |
最大数据大小 |
INDEX_LENGTH |
索引大小(字节) |
DATA_FREE |
碎片空间(字节) |
AUTO_INCREMENT |
下一个自增值 |
CREATE_TIME |
创建时间 |
UPDATE_TIME |
最后更新时间 |
CHECK_TIME |
最后检查时间(MyISAM) |
TABLE_COLLATION |
表的排序规则 |
CHECKSUM |
校验和 |
CREATE_OPTIONS |
创建选项 |
TABLE_COMMENT |
表注释 |
注意事项:
TABLE_ROWS 不准确: InnoDB 的
TABLE_ROWS是估算值,误差可能达到 40-50%1
2-- 要获取准确行数,需要 COUNT(*)
SELECT COUNT(*) FROM your_table;DATA_FREE 表示碎片: 如果
DATA_FREE很大,说明表有很多碎片,可以优化:1
OPTIMIZE TABLE your_table;
3. COLUMNS - 列信息
作用: 查询表的所有列的详细信息。
1 | -- 查看某个表的所有列 |
重要字段:
| 字段 | 说明 |
|---|---|
TABLE_SCHEMA |
数据库名 |
TABLE_NAME |
表名 |
COLUMN_NAME |
列名 |
ORDINAL_POSITION |
列的位置(从1开始) |
COLUMN_DEFAULT |
默认值 |
IS_NULLABLE |
是否允许 NULL: YES, NO |
DATA_TYPE |
数据类型: int, varchar, datetime 等 |
COLUMN_TYPE |
完整类型: int(11), varchar(255) 等 |
CHARACTER_MAXIMUM_LENGTH |
字符最大长度 |
CHARACTER_OCTET_LENGTH |
字符字节长度 |
NUMERIC_PRECISION |
数值精度 |
NUMERIC_SCALE |
数值小数位数 |
DATETIME_PRECISION |
日期时间精度 |
CHARACTER_SET_NAME |
字符集 |
COLLATION_NAME |
排序规则 |
COLUMN_KEY |
键类型: PRI(主键), UNI(唯一), MUL(索引) |
EXTRA |
额外信息: auto_increment, on update CURRENT_TIMESTAMP |
PRIVILEGES |
权限 |
COLUMN_COMMENT |
列注释 |
GENERATION_EXPRESSION |
生成列表达式(MySQL 5.7+) |
4. STATISTICS - 索引信息
作用: 查询表的所有索引和统计信息。
1 | -- 查看某个表的所有索引 |
重要字段:
| 字段 | 说明 |
|---|---|
TABLE_SCHEMA |
数据库名 |
TABLE_NAME |
表名 |
NON_UNIQUE |
是否非唯一: 0(唯一), 1(非唯一) |
INDEX_SCHEMA |
索引所在数据库 |
INDEX_NAME |
索引名称 |
SEQ_IN_INDEX |
列在索引中的位置(从1开始) |
COLUMN_NAME |
列名 |
COLLATION |
排序方式: A(升序), D(降序), NULL |
CARDINALITY |
基数(不重复值的估计数量) |
SUB_PART |
前缀索引的长度 |
PACKED |
是否压缩 |
NULLABLE |
列是否允许 NULL |
INDEX_TYPE |
索引类型: BTREE, HASH, FULLTEXT, SPATIAL |
COMMENT |
索引注释 |
INDEX_COMMENT |
索引注释 |
实战案例: 索引优化
1 | -- 1. 找出基数很低的索引(可能不高效) |
5. TABLE_CONSTRAINTS - 约束信息
作用: 查询表的所有约束(主键、外键、唯一约束等)。
1 | -- 查看某个表的所有约束 |
约束类型:
| CONSTRAINT_TYPE | 说明 |
|---|---|
PRIMARY KEY |
主键约束 |
FOREIGN KEY |
外键约束 |
UNIQUE |
唯一约束 |
CHECK |
检查约束(MySQL 8.0.16+) |
6. KEY_COLUMN_USAGE - 约束列信息
作用: 查询约束涉及的具体列,特别是外键关系。
1 | -- 查看外键关系 |
7. REFERENTIAL_CONSTRAINTS - 外键详细信息
作用: 查询外键的更新和删除规则。
1 | -- 查看外键的级联规则 |
级联规则:
| 规则 | 说明 |
|---|---|
CASCADE |
级联操作(删除父记录时删除子记录) |
SET NULL |
设置为 NULL |
RESTRICT |
拒绝操作(默认) |
NO ACTION |
无操作(同 RESTRICT) |
SET DEFAULT |
设置为默认值(MySQL 不支持) |
二、权限与用户信息
1. USER_PRIVILEGES - 用户全局权限
作用: 查询用户的全局权限。
1 | -- 查看所有用户的全局权限 |
2. SCHEMA_PRIVILEGES - 数据库权限
作用: 查询用户对特定数据库的权限。
1 | -- 查看某个数据库的权限分配 |
3. TABLE_PRIVILEGES - 表权限
作用: 查询用户对特定表的权限。
1 | -- 查看某个表的权限分配 |
4. COLUMN_PRIVILEGES - 列权限
作用: 查询用户对特定列的权限。
1 | -- 查看某个表的列权限 |
三、存储程序信息
1. ROUTINES - 存储过程和函数
作用: 查询所有存储过程和函数的定义。
1 | -- 查看所有存储过程和函数 |
2. PARAMETERS - 存储过程参数
作用: 查询存储过程和函数的参数信息。
1 | -- 查看存储过程的参数 |
参数模式:
| PARAMETER_MODE | 说明 |
|---|---|
IN |
输入参数 |
OUT |
输出参数 |
INOUT |
输入输出参数 |
3. TRIGGERS - 触发器
作用: 查询所有触发器的定义。
1 | -- 查看所有触发器 |
触发器时机和事件:
| ACTION_TIMING | 说明 |
|---|---|
BEFORE |
操作前触发 |
AFTER |
操作后触发 |
| EVENT_MANIPULATION | 说明 |
|---|---|
INSERT |
插入时触发 |
UPDATE |
更新时触发 |
DELETE |
删除时触发 |
4. EVENTS - 事件调度器
作用: 查询所有定时事件的信息。
1 | -- 查看所有事件 |
事件类型:
| EVENT_TYPE | 说明 |
|---|---|
ONE TIME |
一次性事件 |
RECURRING |
周期性事件 |
四、字符集与排序规则
1. CHARACTER_SETS - 字符集
作用: 查询所有支持的字符集。
1 | -- 查看所有字符集 |
常用字符集:
| 字符集 | 说明 | maxlen |
|---|---|---|
utf8mb4 |
UTF-8 完整支持(推荐) | 4 |
utf8 |
UTF-8(不支持表情符) | 3 |
latin1 |
西欧字符集 | 1 |
gbk |
简体中文 | 2 |
2. COLLATIONS - 排序规则
作用: 查询所有支持的排序规则。
1 | -- 查看所有排序规则 |
常用排序规则:
| 排序规则 | 说明 |
|---|---|
utf8mb4_general_ci |
通用排序,不区分大小写(性能好) |
utf8mb4_unicode_ci |
Unicode 标准排序,不区分大小写(准确) |
utf8mb4_bin |
二进制排序,区分大小写 |
utf8mb4_0900_ai_ci |
MySQL 8.0 默认,支持 Unicode 9.0 |
五、存储引擎信息
1. ENGINES - 存储引擎
作用: 查询所有支持的存储引擎。
1 | -- 查看所有存储引擎 |
支持级别:
| SUPPORT | 说明 |
|---|---|
YES |
支持 |
DEFAULT |
默认引擎 |
NO |
不支持 |
DISABLED |
已禁用 |
2. PLUGINS - 插件信息
作用: 查询所有已安装的插件。
1 | -- 查看所有插件 |
六、连接与进程信息
1. PROCESSLIST - 当前连接
作用: 查看当前所有连接和正在执行的 SQL。
1 | -- 查看所有连接 |
重要字段:
| 字段 | 说明 |
|---|---|
ID |
进程 ID(可用于 KILL) |
USER |
用户名 |
HOST |
客户端主机 |
DB |
当前数据库 |
COMMAND |
命令类型: Query, Sleep, Connect 等 |
TIME |
命令执行时间(秒) |
STATE |
执行状态 |
INFO |
正在执行的 SQL 语句 |
注意: MySQL 8.0 推荐使用 performance_schema.threads 代替 information_schema.PROCESSLIST。
七、InnoDB 专用信息
1. INNODB_TABLES - InnoDB 表信息
1 | -- 查看 InnoDB 表的详细信息 |
2. INNODB_TABLESPACES - 表空间信息
1 | -- 查看所有表空间 |
3. INNODB_BUFFER_PAGE - Buffer Pool 页信息
1 | -- 查看 Buffer Pool 中缓存最多的表 |
4. INNODB_TRX - 当前事务
1 | -- 查看当前活跃的事务 |
5. INNODB_LOCKS - 锁信息 (MySQL 5.7)
注意: MySQL 8.0 已弃用,使用 performance_schema.data_locks 代替。
1 | -- MySQL 5.7: 查看当前锁 |
6. INNODB_LOCK_WAITS - 锁等待 (MySQL 5.7)
注意: MySQL 8.0 已弃用,使用 performance_schema.data_lock_waits 代替。
1 | -- MySQL 5.7: 查看锁等待关系 |
八、文件与分区信息
1. FILES - 表空间文件
作用: 查询 InnoDB 表空间文件的物理存储信息。
1 | -- 查看所有表空间文件 |
2. PARTITIONS - 分区信息
作用: 查询表的分区详细信息。
1 | -- 查看分区表的信息 |
实战场景: 数据库诊断与管理
场景 1: 数据库健康检查
1 | -- 1. 检查没有主键的表(必须修复) |
场景 2: 生成表结构文档
1 | -- 生成 Markdown 格式的表结构文档 |
场景 3: 数据库迁移检查
1 | -- 迁移前检查清单 |
场景 4: 生成数据库克隆脚本
1 | -- 生成创建数据库的 SQL |
场景 5: 找出相似的表结构
1 | -- 查找列数相同的表(可能是分表) |
常见问题与注意事项
1. Information Schema 的查询性能
问题: 查询 Information Schema 有时很慢。
原因:
- Information Schema 的表是视图,查询时实时从数据字典读取
- 某些查询需要扫描大量元数据
- 某些查询会触发表的打开操作
优化建议:
1 | -- ❌ 慢: 查询所有数据库的表 |
2. TABLE_ROWS 不准确
问题: TABLES.TABLE_ROWS 的值不准确。
原因:
- InnoDB 的
TABLE_ROWS是估算值(基于统计信息) - 估算误差可达 40-50%
解决方案:
1 | -- 方法 1: 使用 COUNT(*) (准确但慢) |
3. 权限问题
问题: 普通用户查询 Information Schema 时看不到所有表。
原因: 用户只能看到自己有权限的对象。
解决方案:
1 | -- 授予查看所有表的权限(谨慎使用) |
4. MySQL 8.0 的变化
MySQL 8.0 对 Information Schema 进行了重构:
改进:
- 查询性能显著提升(基于数据字典)
- 支持更多新特性(CTE、窗口函数等)
废弃的表:
INNODB_LOCKS→ 使用performance_schema.data_locksINNODB_LOCK_WAITS→ 使用performance_schema.data_lock_waits
5. 查询 ROUTINES 返回乱码
问题: 查询 ROUTINES.ROUTINE_DEFINITION 时返回乱码。
原因: 字符集不匹配。
解决方案:
1 | SET NAMES utf8mb4; |
Information Schema vs MySQL 8.0 数据字典
MySQL 8.0 的数据字典改进
MySQL 8.0 引入了事务性数据字典,替代了旧的文件系统元数据:
旧版本(MySQL 5.7):
1 | 元数据存储: |
新版本(MySQL 8.0):
1 | 统一数据字典: |
性能对比:
| 操作 | MySQL 5.7 | MySQL 8.0 |
|---|---|---|
| 查询 TABLES | 慢(需要打开表) | 快(直接读数据字典) |
| 查询 COLUMNS | 慢 | 快 |
| 查询 STATISTICS | 慢 | 快 |
Information Schema 是 MySQL 管理和监控的重要工具,熟练掌握它可以帮助我们更好地理解和管理数据库结构。
