MySQL 5.7修改VARCHAR字段长度是否锁表取决于字节长度是否跨越255字节边界:utf8mb4下VARCHAR(60)→(64)因240→256字节导致长度字节从1升为2,必须COPY重建表并全程持表级写锁。

替换 CREATE TABLE 语句中的 ENGINE=InnoDB 为 ENGINE=MyISAM
直接在 Sublime Text 中用正则批量改表引擎,最怕误伤注释、字符串或已带条件的 ENGINE 子句。关键不是“能不能换”,而是“只换该换的地方”。
推荐用这个正则表达式:
ENGINE\s*=\s*InnoDB(?!\s*COMMENT)(?![^;]*')(?![^;]*")
说明:ENGINE\s*=\s*InnoDB 匹配基本形式;(?!\s*COMMENT) 排除后面紧接 COMMENT 的情况(避免改 ENGINE=InnoDB COMMENT 'xxx');(?![^;]*') 和 (?![^;]*") 是简单防止单/双引号内匹配(虽不完美但比没有强)。
- 务必勾选 Regex 和 Match Case(InnoDB 大小写敏感)
- 替换为:
ENGINE=MyISAM(保持空格一致,避免格式错乱) - 先
Find All看匹配结果,确认没命中CREATE TABLE ... SELECT或嵌套子查询里的字符串
把所有 VARCHAR(255) 改成 VARCHAR(191),但跳过主键和索引定义行
MySQL 5.7+ 配合 utf8mb4 时,常需缩窄字段长度以适配索引长度限制。但 PRIMARY KEY (xxx) 或 KEY idx_xxx (xxx) 行里的 VARCHAR(255) 是索引定义,不能动。
用这个正则精准定位字段定义行:
^\s*(?:`[^`]+`|[\w]+)\s+VARCHAR\s*\(\s*255\s*\)(?!\s+NOT\s+NULL\s+AUTO_INCREMENT)(?![^;]*PRIMARY\s+KEY)(?![^;]*KEY\s+\w+)
说明:以行首开始(^),匹配字段名 + VARCHAR(255),然后用否定前瞻排除掉主键、普通 KEY、以及自增主键常见组合。
- 替换为:
$1 VARCHAR(191)(注意:实际需用\1 VARCHAR(191),因为前面捕获了字段名) - 必须开启 Wrap around 和 Whole Word 不要勾——这里需要跨行控制,但 Whole Word 会干扰括号匹配
- 如果脚本里有反引号包裹的字段名(如
`name` VARCHAR(255)),正则中(?:`[^`]+`|[\w]+)已覆盖
给所有 datetime 字段补 DEFAULT CURRENT_TIMESTAMP
不是所有 DATETIME 都该加默认值——比如更新时间字段通常用 ON UPDATE CURRENT_TIMESTAMP,而创建时间才加 DEFAULT CURRENT_TIMESTAMP。Sublime 无法语义判断,所以得靠上下文特征辅助过滤。
推荐分两步操作:
- 先找可能的创建时间字段:用正则
`created_at`\s+DATETIME(?![^;]*ON\s+UPDATE),确认后替换为`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP - 再检查是否已有
DEFAULT:加一个查找`created_at`\s+DATETIME\s+DEFAULT,避免重复添加 - 注意大小写:
DATETIME在 MySQL 脚本里常全大写,正则要关掉 Match Case 或统一写成[dD][aA][tT][eE][tT][iI][mM][eE]
替换失败后发现多了 \n\n 或缩进错乱怎么办
Sublime 的正则替换不会自动保留原始换行风格,尤其当替换内容含换行或空格时,容易把 ) ENGINE=InnoDB; 拆成两行,或把多空格压成单空格。
- 替换前先
Ctrl+Shift+P→Convert Line Endings→ 统一为Unix (LF) - 避免在替换串里手敲多个空格,改用
\x20\x20(十六进制空格)或复制原文中的空白片段 - 如果原脚本用 Tab 缩进,替换后缩进异常,可在替换后全选 →
Ctrl+Shift+P→Indentation: Convert to Tabs - 最稳妥的做法:每次替换后立刻
Ctrl+Z撤销,用Find All查看高亮范围,确认无跨行、无嵌套干扰再真正替换
真正麻烦的不是正则写不对,而是脚本里混着生成器输出、手动拼接 SQL、甚至带变量插值的模板片段——这种就得先人工隔离出纯 DDL 段落再处理。











