MySQL - information_schema.COLUMNS中字段的排序原则 以及如何修改

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. 最佳实践

  1. 开发环境优先:在开发环境测试列顺序修改

  2. 维护窗口:在生产环境的低峰期执行

  3. 版本控制:将表结构变更纳入版本管理

  4. 备份:执行前备份数据

  5. 测试:确保应用程序兼容性

九、总结

关键要点:

  1. information_schema.columns 没有固定的默认排序,应使用 ORDER BY

  2. 修改列顺序只能通过 ALTER TABLE 实现

  3. 主键和索引列应优先排序,以提高查询效率

  4. 相关列应分组排列,如时间字段、状态字段等

  5. 保持一致性,所有表使用相同的列排序规则

推荐列排序规则:

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 字段值

相关推荐
猿小喵2 小时前
MySQL数据库参数解读-第二篇
数据库·mysql
PD我是你的真爱粉2 小时前
MySQL 索引深度解析:从底层结构到实战优化
数据库·mysql
神舟之光2 小时前
Springboot+MyBatis-Plus连接MySQL初体验
spring boot·mysql·mybatis
WangJunXiang63 小时前
MySQL高可用详细解析
android·数据库·mysql
蜡台3 小时前
macOS 无法启动 MySQL服务解决
数据库·mysql·macos
执笔论英雄3 小时前
vLLM V1 Scheduler的调度逻辑&优先级分析
数据库·mysql
桌面运维家3 小时前
MySQL安全实战:慢查询诊断与SQL注入防御
sql·mysql·安全
PD我是你的真爱粉4 小时前
MySQL 索引进阶:从失效排查到架构哲学
mysql·adb·架构
wuyikeer4 小时前
docker 安装 mysql
mysql·adb·docker