information_schema.COLUMNS 字段排序详解与优化
一、information_schema.COLUMNS 的排序机制
1. 默认排序原则
information_schema.columns视图的默认排序是不确定的,但通常遵循以下规律:
sql
-- 默认查询(排序不确定)
SELECT * FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database';
2. 影响排序的因素
-
表创建顺序:通常按表的物理存储顺序
-
列添加顺序:按表中列的定义顺序
-
元数据存储:依赖于底层系统表的存储结构
-
查询优化器:可能根据统计信息调整
二、查看和修改排序的方法
1. 查看当前数据库的列信息(推荐排序)
sql
-- 按数据库、表、列位置排序(最常用)
SELECT
TABLE_SCHEMA AS 数据库,
TABLE_NAME AS 表名,
COLUMN_NAME AS 列名,
ORDINAL_POSITION AS 列位置,
DATA_TYPE AS 数据类型,
COLUMN_TYPE AS 完整类型,
IS_NULLABLE AS 可空,
COLUMN_DEFAULT AS 默认值,
EXTRA AS 额外信息
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY
TABLE_SCHEMA,
TABLE_NAME,
ORDINAL_POSITION;
2. 按各种需求排序
sql
-- 1. 按列名字母顺序排序
SELECT * FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY TABLE_NAME, COLUMN_NAME;
-- 2. 按数据类型分组排序
SELECT * FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY DATA_TYPE, TABLE_NAME, ORDINAL_POSITION;
-- 3. 按可空性排序
SELECT * FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
ORDER BY IS_NULLABLE, TABLE_NAME, ORDINAL_POSITION;
-- 4. 按主键/索引优先级排序
SELECT
c.*,
CASE
WHEN k.CONSTRAINT_NAME = 'PRIMARY' THEN 1
WHEN k.CONSTRAINT_NAME LIKE '%UNIQUE%' THEN 2
WHEN k.CONSTRAINT_NAME LIKE '%KEY%' THEN 3
ELSE 4
END AS key_priority
FROM information_schema.columns c
LEFT JOIN information_schema.key_column_usage k
ON c.TABLE_SCHEMA = k.TABLE_SCHEMA
AND c.TABLE_NAME = k.TABLE_NAME
AND c.COLUMN_NAME = k.COLUMN_NAME
WHERE c.TABLE_SCHEMA = 'your_database'
ORDER BY c.TABLE_NAME, key_priority, c.ORDINAL_POSITION;
三、修改表中列顺序的方法
1. 通过 ALTER TABLE 重排列顺序
sql
-- 方法1:将列移动到首位
ALTER TABLE 表名
MODIFY COLUMN 列名 数据类型 FIRST;
-- 方法2:将列移动到指定列之后
ALTER TABLE 表名
MODIFY COLUMN 列名 数据类型
AFTER 目标列名;
-- 示例:将email列移动到name列之后
ALTER TABLE users
MODIFY COLUMN email VARCHAR(255)
AFTER name;
2. 批量重排多列顺序
sql
-- 示例:重排users表的列顺序
ALTER TABLE users
MODIFY id INT AUTO_INCREMENT FIRST,
MODIFY username VARCHAR(50) AFTER id,
MODIFY email VARCHAR(255) AFTER username,
MODIFY created_at TIMESTAMP AFTER email;
四、自动化列排序工具
1. 创建自定义排序视图
sql
-- 创建标准化列信息视图
CREATE VIEW column_info_sorted AS
SELECT
c.TABLE_CATALOG,
c.TABLE_SCHEMA,
c.TABLE_NAME,
c.COLUMN_NAME,
c.ORDINAL_POSITION,
c.COLUMN_DEFAULT,
c.IS_NULLABLE,
c.DATA_TYPE,
c.CHARACTER_MAXIMUM_LENGTH,
c.NUMERIC_PRECISION,
c.NUMERIC_SCALE,
c.DATETIME_PRECISION,
c.CHARACTER_SET_NAME,
c.COLLATION_NAME,
c.COLUMN_TYPE,
c.COLUMN_KEY,
c.EXTRA,
c.COLUMN_COMMENT,
c.GENERATION_EXPRESSION,
c.SRS_ID
FROM information_schema.columns c
WHERE c.TABLE_SCHEMA = DATABASE()
ORDER BY
c.TABLE_NAME,
CASE c.COLUMN_KEY
WHEN 'PRI' THEN 1
WHEN 'UNI' THEN 2
WHEN 'MUL' THEN 3
ELSE 4
END,
c.ORDINAL_POSITION;
2. 生成列重排SQL脚本
sql
-- 生成ALTER语句来标准化列顺序
SELECT
CONCAT(
'ALTER TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '`\n',
GROUP_CONCAT(
CONCAT(' MODIFY COLUMN `', COLUMN_NAME, '` ', COLUMN_TYPE,
IF(IS_NULLABLE = 'YES', '', ' NOT NULL'),
IF(COLUMN_DEFAULT IS NULL, '',
CONCAT(' DEFAULT ', QUOTE(COLUMN_DEFAULT))),
IF(EXTRA = '', '', CONCAT(' ', EXTRA))
ORDER BY ORDINAL_POSITION
SEPARATOR ',\n'
)
),
';'
) AS alter_statement
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
GROUP BY TABLE_SCHEMA, TABLE_NAME;
五、使用存储过程管理列顺序
1. 智能列排序存储过程
sql
DELIMITER //
CREATE PROCEDURE standardize_column_order(
IN db_name VARCHAR(64)
)
BEGIN
DECLARE done INT DEFAULT FALSE;
DECLARE table_name_var VARCHAR(64);
DECLARE column_name_var VARCHAR(64);
DECLARE column_type_var LONGTEXT;
DECLARE is_nullable_var VARCHAR(3);
DECLARE column_default_var VARCHAR(255);
DECLARE extra_var VARCHAR(255);
DECLARE column_key_var VARCHAR(3);
DECLARE ordinal_position_var INT;
-- 游标获取所有表的所有列
DECLARE column_cursor CURSOR FOR
SELECT
TABLE_NAME,
COLUMN_NAME,
COLUMN_TYPE,
IS_NULLABLE,
COLUMN_DEFAULT,
EXTRA,
COLUMN_KEY,
ORDINAL_POSITION
FROM information_schema.columns
WHERE TABLE_SCHEMA = db_name
ORDER BY
TABLE_NAME,
CASE COLUMN_KEY
WHEN 'PRI' THEN 1
WHEN 'UNI' THEN 2
WHEN 'MUL' THEN 3
ELSE 4
END,
CASE
WHEN DATA_TYPE IN ('int', 'bigint', 'tinyint') THEN 1
WHEN DATA_TYPE IN ('varchar', 'char', 'text') THEN 2
WHEN DATA_TYPE IN ('datetime', 'timestamp', 'date') THEN 3
ELSE 4
END,
ORDINAL_POSITION;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN column_cursor;
column_loop: LOOP
FETCH column_cursor INTO
table_name_var,
column_name_var,
column_type_var,
is_nullable_var,
column_default_var,
extra_var,
column_key_var,
ordinal_position_var;
IF done THEN
LEAVE column_loop;
END IF;
-- 这里可以添加修改逻辑
-- 示例:记录当前列顺序
INSERT INTO column_order_audit
(database_name, table_name, column_name, original_position, audit_time)
VALUES (db_name, table_name_var, column_name_var, ordinal_position_var, NOW());
END LOOP;
CLOSE column_cursor;
END //
DELIMITER ;
六、性能优化建议
1. 减少information_schema查询的开销
sql
-- 优化查询:只查询需要的列
SELECT
TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
IS_NULLABLE
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database';
-- 使用LIMIT和缓存
SELECT SQL_CACHE
TABLE_NAME,
COLUMN_NAME
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
LIMIT 1000;
2. 创建物化视图(MySQL 8.0+)
sql
-- 创建物化视图存储列信息
CREATE TABLE materialized_column_info AS
SELECT * FROM information_schema.columns
WHERE TABLE_SCHEMA = DATABASE();
-- 添加索引
ALTER TABLE materialized_column_info
ADD INDEX idx_table (TABLE_SCHEMA, TABLE_NAME),
ADD INDEX idx_column (COLUMN_NAME);
-- 定期刷新
TRUNCATE TABLE materialized_column_info;
INSERT INTO materialized_column_info
SELECT * FROM information_schema.columns
WHERE TABLE_SCHEMA = DATABASE();
七、实用查询示例
1. 获取表结构文档
sql
-- 生成Markdown格式的表结构文档
SELECT
CONCAT('## ', TABLE_NAME, '\n\n',
'| 列名 | 类型 | 可空 | 默认值 | 注释 |\n',
'|------|------|------|--------|------|\n',
GROUP_CONCAT(
CONCAT('| `', COLUMN_NAME, '` | `', COLUMN_TYPE, '` | ',
IS_NULLABLE, ' | ',
IFNULL(CONCAT('`', COLUMN_DEFAULT, '`'), 'NULL'), ' | ',
IFNULL(CONCAT('`', COLUMN_COMMENT, '`'), '') , ' |')
ORDER BY ORDINAL_POSITION
SEPARATOR '\n'
),
'\n\n---\n\n'
) AS markdown_doc
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
GROUP BY TABLE_NAME
ORDER BY TABLE_NAME;
2. 列顺序分析报告
sql
-- 分析列顺序模式
SELECT
TABLE_NAME,
COUNT(*) AS total_columns,
SUM(CASE WHEN COLUMN_KEY = 'PRI' THEN 1 ELSE 0 END) AS primary_keys,
SUM(CASE WHEN COLUMN_KEY = 'UNI' THEN 1 ELSE 0 END) AS unique_keys,
SUM(CASE WHEN COLUMN_KEY = 'MUL' THEN 1 ELSE 0 END) AS foreign_keys,
MIN(ORDINAL_POSITION) AS first_column_position,
MAX(ORDINAL_POSITION) AS last_column_position,
GROUP_CONCAT(COLUMN_NAME ORDER BY ORDINAL_POSITION SEPARATOR ' → ') AS column_sequence
FROM information_schema.columns
WHERE TABLE_SCHEMA = 'your_database'
GROUP BY TABLE_NAME
ORDER BY TABLE_NAME;
八、注意事项
1. 修改列顺序的潜在问题
sql
-- 1. 可能影响应用程序
-- 如果应用程序依赖SELECT *,列顺序变化可能导致问题
-- 2. 重建表可能导致锁表
ALTER TABLE ... MODIFY COLUMN ... -- 可能锁表,影响生产环境
-- 3. 外键和索引约束
-- 修改列顺序不会影响约束,但重建表可能影响性能
2. 最佳实践
-
开发环境优先:在开发环境测试列顺序修改
-
维护窗口:在生产环境的低峰期执行
-
版本控制:将表结构变更纳入版本管理
-
备份:执行前备份数据
-
测试:确保应用程序兼容性
九、总结
关键要点:
-
information_schema.columns 没有固定的默认排序,应使用 ORDER BY
-
修改列顺序只能通过 ALTER TABLE 实现
-
主键和索引列应优先排序,以提高查询效率
-
相关列应分组排列,如时间字段、状态字段等
-
保持一致性,所有表使用相同的列排序规则
推荐列排序规则:
sql
-- 推荐的列排序模板
1. 主键列 (id, 自增)
2. 业务键列 (code, uuid)
3. 外键列 (xxx_id)
4. 状态/类型列 (status, type)
5. 核心业务列
6. 时间戳列 (created_at, updated_at)
7. 软删除标志 (deleted_at)
8. 版本/乐观锁列 (version)
9. 扩展/元数据列
通过合理排序列,可以提高查询性能、增强代码可读性,并简化数据库维护工作。
想要达到字段本身的前后顺序
https://ningxiaofa.blog.csdn.net/article/details/159735428?spm=1011.2415.3001.5331
借助: ORDINAL_POSITION 字段值
