You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel迁移修改字符集排序规则失败问题排查

Laravel迁移重命名列后排序规则被重置的问题

问题原因

Laravel的Schema::renameColumn()方法执行时,会继承当前表的默认字符集与排序规则,而非保留被重命名列(如name_new)的原有属性。这是因为Laravel构建重命名SQL时,没有完整携带原列的字符集和排序规则配置,而是依赖表的默认设置。而直接在PhpMyAdmin中重命名时,数据库会自动保留原列的所有属性,因此不会出现规则被重置的情况。

解决方案

方案一:使用原生SQL执行重命名(推荐)

绕过Laravel Schema的限制,直接用原生SQL语句完成重命名,同时显式指定字符集和排序规则:

// 1. 创建带目标排序规则的新列
Schema::table('your_table', function (Blueprint $table) {
    $table->string('name_new')->charset('utf8')->collation('utf8_bin')->nullable();
});

// 2. 迁移原列数据到新列
DB::table('your_table')->update(['name_new' => DB::raw('name')]);

// 3. 删除原name列
Schema::table('your_table', function (Blueprint $table) {
    $table->dropColumn('name');
});

// 4. 用原生SQL重命名并保留属性
DB::statement('ALTER TABLE your_table CHANGE name_new name VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_bin NULL');

方案二:先修改表的默认排序规则

如果希望后续所有列都使用UTF8排序规则,可以先修改表的默认配置,再执行重命名:

// 1. 修改表的默认字符集和排序规则
Schema::table('your_table', function (Blueprint $table) {
    $table->charset = 'utf8';
    $table->collation = 'utf8_bin';
});

// 2. 创建新列并迁移数据
Schema::table('your_table', function (Blueprint $table) {
    $table->string('name_new')->charset('utf8')->collation('utf8_bin')->nullable();
});
DB::table('your_table')->update(['name_new' => DB::raw('name')]);
Schema::table('your_table', function (Blueprint $table) {
    $table->dropColumn('name');
});

// 3. 现在重命名会继承表的新默认规则
Schema::table('your_table', function (Blueprint $table) {
    $table->renameColumn('name_new', 'name');
});

注意事项

  • 替换代码中的your_table为实际表名,根据原列的类型(如string长度、是否可为空)调整SQL中的字段定义。
  • 若使用Laravel 9+版本,可直接在列定义中用->collation('utf8_bin'),无需额外指定charset(部分数据库中charset与collation关联)。

内容的提问来源于stack exchange,提问作者Styl Bandeira de Amorim Coelho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 05:10:51