执行迁移遇SQLSTATE[42000]错误:utf8mb4_unicode_ci不适用于utf8mb3
解决SQLSTATE[42000]字符集与排序规则不匹配问题
问题本质
你碰到的SQLSTATE[42000]: Syntax error or access violation: 1253 COLLATION 'utf8mb4_unicode_ci' is not valid for CHARACTER SET 'utf8mb3'错误,核心原因是字符集和排序规则不兼容——你的categories表(或name字段)用的是utf8mb3字符集,但系统试图用utf8mb4_unicode_ci这个属于utf8mb4的排序规则来处理orderBy('name')的排序操作,两者不匹配导致报错。
修复方案
1. 直接修正字段的字符集与排序规则
执行SQL语句修改name字段的字符集为utf8mb4,并匹配对应的排序规则:
ALTER TABLE categories MODIFY COLUMN name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
如果parent_id字段也存在字符集不一致的情况,同步执行:
ALTER TABLE categories MODIFY COLUMN parent_id INT NULL DEFAULT NULL CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
2. 统一整个表的字符集
为了避免后续新增字段再出问题,直接把整个表的字符集和排序规则改成utf8mb4:
ALTER TABLE categories CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
3. 修正迁移文件(Laravel项目适用)
如果是Laravel项目,检查你的迁移文件,确保创建表时指定了正确的字符集和排序规则:
Schema::create('categories', function (Blueprint $table) { $table->id(); $table->string('name'); $table->unsignedBigInteger('parent_id')->nullable(); $table->timestamps(); // 设置表的默认字符集和排序规则 $table->charset = 'utf8mb4'; $table->collation = 'utf8mb4_unicode_ci'; });
如果已经执行过迁移,就用前面的SQL语句修改表结构,不用重新跑迁移。
4. 临时应急方案(不推荐长期用)
如果暂时没法修改表结构,可以在代码里显式指定兼容的排序规则,强制MySQL用utf8mb3对应的规则排序:
public static function children($parent=null) { return Category::where('parent_id',$parent) ->orderByRaw('name COLLATE utf8mb3_unicode_ci') ->get(); }
这个方法只是临时绕开问题,长期来看还是建议统一字符集,避免后续其他操作再出类似错误。
内容的提问来源于stack exchange,提问作者kaliboba
相关产品推荐
相关产品推荐

