INFORMATION_SCHEMA 是 MySQL 导出数据字典的唯一可靠来源,需组合查询 COLUMNS、KEY_COLUMN_USAGE 和 TABLE_CONSTRAINTS 视图获取完整元信息;PostgreSQL 则必须使用 pg_catalog 系统表而非 information_schema。
导出 MySQL 数据字典时,INFORMATION_SCHEMA 是唯一可靠来源
用 show create table 或客户端右键“生成建表语句”只能拿到单表结构,没法批量、统一格式导出字段注释、约束类型、索引顺序等元信息。真正要拿完整字典,必须查 information_schema —— 它是 mysql 官方维护的只读系统库,字段定义稳定,所有版本都支持(5.7+ 尤其完整)。
常见错误是直接 SELECT * FROM INFORMATION_SCHEMA.COLUMNS,结果发现 COLUMN_COMMENT 为空、EXTRA 值乱码、外键信息根本不在这个表里。这是因为字段级信息分散在多个视图中,得组合查询。
-
COLUMNS表提供字段名、类型、是否为空、默认值、注释 -
KEY_COLUMN_USAGE表补全主键/外键/索引的列顺序和引用关系 -
TABLE_CONSTRAINTS表说明约束类型(PRIMARY KEY、FOREIGN KEY、UNIQUE) - 别硬连
STATISTICS,它字段含义模糊,MySQL 8.0 后行为有变化
PostgreSQL 导出字典必须用 pg_catalog,information_schema 只能当备选
PostgreSQL 的 information_schema 虽然标准,但字段缺失严重:比如不暴露 GENERATED 列、不区分 IDENTITY 和序列、函数依赖和分区键完全不可见。真要导出生产级字典,必须查 pg_catalog 下的 pg_class、pg_attribute、pg_constraint 等原生表。
典型坑是忽略 attisdropped 字段——被 ALTER TABLE DROP COLUMN 删除但未 VACUUM 的列仍会出现在 pg_attribute 中,导致字典多出“幽灵字段”。另外,pg_get_expr 解析默认值时,对 nextval() 类函数返回的是表达式字符串,不是实际值,别误当成可执行 SQL。
- 用
pg_attribute.atttypid::regtype而非format_type()获取类型名,前者兼容自定义类型 - 外键引用目标表名藏在
pg_constraint.conrelid和conindid里,需两次关联pg_class -
pg_description存字段/表注释,但objoid对应的是pg_class或pg_attribute的oid,不是名字
导出为 Markdown 表格时,字段顺序和空值处理比语法更重要
很多人用 mysqldump --no-data 或 pg_dump -s 生成 SQL 再正则提取,结果字段顺序错乱、注释换行被截断、枚举值里的逗号破坏 CSV 格式。直接生成 Markdown 表格反而更稳,关键是控制三件事:字段排列顺序、NULL 值显式标为 NULL、长注释做 HTML 实体转义(否则 & 或 会被解析)。
示例片段(MySQL):
SELECT
CONCAT('| ', COLUMN_NAME, ' | ',
DATA_TYPE,
CASE WHEN CHARACTER_MAXIMUM_LENGTH IS NOT NULL
THEN CONCAT('(', CHARACTER_MAXIMUM_LENGTH, ')')
ELSE '' END,
' | ', IF(IS_NULLABLE = 'YES', '√', '×'), ' | ',
IFNULL(COLUMN_COMMENT, ''), ' |') AS md_row
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'your_db' AND TABLE_NAME = 'user';
- 别用
GROUP_CONCAT拼整个表,字段数一多就超长截断 -
COLUMN_COMMENT里的换行符(\n)得替换成,Markdown 表格不认原生换行 - PostgreSQL 需额外过滤
pg_attribute.attnum > 0,跳过系统字段(如tableoid)
自动化脚本里最容易漏掉权限和字符集校验
导出脚本跑在 CI 或定时任务里,常因权限不足卡在 SELECT 系统表这步,报错 Access denied for user ... to database 'INFORMATION_SCHEMA'。其实不是没权限查这个库,而是用户没被授予 SELECT 权限到具体系统表(MySQL 8.0+ 默认关闭)。另一坑是数据库字符集和终端不一致,导出的中文注释变成 ????,尤其在 Linux cron 下没设 LC_ALL。
- MySQL 检查权限:
SHOW GRANTS FOR CURRENT_USER,确保含SELECT ON INFORMATION_SCHEMA.* - PostgreSQL 需
GRANT SELECT ON pg_catalog.pg_class TO your_user等逐表授权 - 脚本开头强制设置:
export LANG=en_US.UTF-8(Linux)或chcp 65001(Windows cmd) - 导出前加一行
SELECT @@character_set_database,确认不是latin1
字段注释里带 emoji 或特殊符号时,连 MySQL 客户端的 --default-character-set=utf8mb4 都不一定够,得在连接字符串里显式加 ?charset=utf8mb4。这点很容易被跳过,等上线才发现字典里一堆豆腐块。










