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

Laravel 9迁移建表时created_at默认值错误及字符集疑问

问题解答

疑问一:建表语句为何使用utf8mb4_unicode_ci而非数据库的utf8_general_ci?

这是Laravel框架的默认配置行为:

  • 在Laravel的config/database.php配置文件中,MySQL数据库的默认字符集被设置为utf8mb4,排序规则为utf8mb4_unicode_ci。
  • 执行迁移时,Laravel会忽略数据库层面的字符集设置,直接使用配置文件中定义的参数生成建表语句,所以最终表的字符集为utf8mb4_unicode_ci。

如果需要改为和数据库一致的utf8_general_ci,有两种方式:

  1. 修改config/database.php中的mysql配置项:
'mysql' => [
    // ...其他配置
    'charset' => 'utf8',
    'collation' => 'utf8_general_ci',
],
  1. 在迁移文件中手动指定表的字符集:
Schema::create('user_meetings', function (Blueprint $table) {
    $table->charset = 'utf8';
    $table->collation = 'utf8_general_ci';
    // ...其他字段定义
});

疑问二:建表操作为何触发created_at默认值无效的错误?

问题出在MySQL的sql_mode设置和迁移字段定义上:

  • 你的created_at字段被定义为$table->timestamp('created_at');,意味着该字段非空但未设置默认值。
  • 你的MySQL服务器开启了NO_ZERO_IN_DATE或NO_ZERO_DATE的sql模式,这两个模式禁止将'0000-00-00 00:00:00'作为timestamp字段的默认值(MySQL在未指定默认值时会尝试用这个值填充非空timestamp字段),因此触发了1067 Invalid default value错误。

解决方法有两种:

  1. 修改迁移字段定义:给created_at设置默认值为当前时间,或者直接使用Laravel内置的timestamps()方法(自动处理created_at和updated_at的非空+默认规则):
// 方式一:手动设置默认值
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->nullable();

// 方式二:使用Laravel内置方法
$table->timestamps();
  1. 调整MySQL的sql_mode:去掉NO_ZERO_IN_DATE和NO_ZERO_DATE模式。在MySQL配置文件(如/etc/mysql/my.cnf)中修改:
[mysqld]
sql_mode = "ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

修改后重启MySQL服务生效。

内容的提问来源于stack exchange,提问作者mstdmstd

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:55:42