laravel迁移默认建表为utf8编码,需三步强制使用utf8mb4:确认mysql服务端字符集、配置database.php中charset/collation及pdo命令、迁移后执行alter table语句;同时须设置schema::defaultstringlength(191)或显式指定字符串长度以防索引超限。

在Laravel迁移中创建新表时,即使已配置数据库连接为utf8mb4,默认仍可能生成utf8编码的表结构,导致emoji和生僻中文无法正确存储——这不是配置遗漏,而是Laravel 9.x及更早版本Schema Builder的隐性行为。
强制迁移建表使用utf8mb4
第一步:确认MySQL服务端已启用utf8mb4支持
进MySQL命令行执行:SHOW VARIABLES LIKE 'character_set_server';,输出值必须为utf8mb4;若非此值,需修改my.cnf中[mysqld]段并重启服务。
第二步:在config/database.php的mysql连接配置中,显式声明charset与collation:'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci',同时追加PDO初始化命令:'options' => [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"]。
第三步:在迁移文件的Schema::create()闭包结束后,立即调用原生SQL语句升级表字符集:DB::statement("ALTER TABLE {$table_name} CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");。【这一步不可省略,仅靠配置无法覆盖Laravel默认建表行为】
避免索引长度超限(关键前置动作)
方法一:在AppServiceProvider::boot()中全局设置默认字符串长度Schema::defaultStringLength(191);——因为utf8mb4下单字符最多占4字节,InnoDB默认索引限制767字节,255字符会超限触发1071 Specified key was too long错误。
方法二:为每个string字段显式指定长度,如$table->string('title', 191),而非依赖默认255。
验证建表结果是否生效
执行迁移后,运行SQL:SHOW CREATE TABLE users;(将users替换为你的表名),检查输出中是否包含ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci。
再查字段级编码:SELECT COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME FROM information_schema.COLUMNS WHERE TABLE_NAME = 'users';,所有文本字段的CHARACTER_SET_NAME必须为utf8mb4。











