在 Yii 框架迁移中,创建带 created_at 时间戳字段的表应优先使用 $this->timestamp()->defaultExpression('CURRENT_TIMESTAMP'),并设 notNull()、加索引;多数据库兼容推荐 integer + UNIX_TIMESTAMP() 配 TimestampBehavior。

在 Yii 框架中,通过迁移创建带 created_at 时间戳字段的表时,关键在于正确设置字段类型、默认值和自动行为,尤其要注意数据库引擎(如 MySQL)对 TIMESTAMP 和 DATETIME 的支持差异。
使用 timestamp() 并设默认值为当前时间
Yii 2.0+ 的迁移语法中,推荐用 $this->timestamp() 创建 created_at 字段,并配合数据库原生默认值(如 CURRENT_TIMESTAMP),确保插入时自动填充:
$this->createTable('{{%post}}', [
'id' => $this->primaryKey(),
'title' => $this->string()->notNull(),
'created_at' => $this->timestamp()->defaultExpression('CURRENT_TIMESTAMP'),
]);
- MySQL 5.6.5+ 支持
TIMESTAMP或DATETIME的CURRENT_TIMESTAMP默认值 - 若用
$this->dateTime(),需显式写defaultExpression('NOW()'),但语义不如timestamp()清晰 - 避免仅用
defaultExpression('0000-00-00 00:00:00')—— 这不触发自动赋值
兼容多数据库的写法(推荐)
为适配 PostgreSQL、SQLite 等,可改用 Yii 的抽象表达式 time(),由框架转换为对应数据库的当前时间函数:
'created_at' => $this->integer()->notNull()->defaultValue(new \yii\db\Expression('UNIX_TIMESTAMP()')),
- 存为整型(Unix 时间戳),跨库兼容性最强
- 需在模型中配合
behaviors()自动填充,例如:'timestamp' => ['class' => TimestampBehavior::className(), 'createdAtAttribute' => 'created_at'] - 注意:此方式不依赖数据库默认值,而是靠 Yii 在
beforeInsert时赋值
添加索引与非空约束
created_at 常用于排序或范围查询,建议加上索引;同时设为 notNull() 防止空值干扰:
'created_at' => $this->timestamp()->notNull()->defaultExpression('CURRENT_TIMESTAMP'),
- 后续可用
$this->createIndex()单独添加索引,例如:$this->createIndex('idx-post-created_at', '{{%post}}', 'created_at'); - 若字段已存在,用
alterColumn()补约束和默认值
区分 created\_at 和 updated\_at
若还需更新时间戳,可一并定义,并让 updated_at 支持自动更新(MySQL 中用 ON UPDATE CURRENT_TIMESTAMP):
'created_at' => $this->timestamp()->defaultExpression('CURRENT_TIMESTAMP'),
'updated_at' => $this->timestamp()->defaultExpression('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
- 注意:MySQL 要求
TIMESTAMP类型才支持ON UPDATE,DATETIME需 MySQL 5.6.5+ - PostgreSQL 不支持该语法,此时应统一用整型 +
TimestampBehavior更稳妥











