概要
LaravelにはDB保存メソッドが複数あるが、timestampの扱いが異なる。
忘れないよう自分用にまとめておく。
なぜこの記事を?
MySQLバージョンアップの検証時に困ったため。
タイムゾーン設定をどちらもJSTにすべきところ、MySQLのタイムゾーンをUTCにしてしまっていた。
その際timestamp値が既存データと異なっていたのだが、正しい時間のデータも存在してしまっており原因の特定に時間がかかってしまった。
原因はsave
ではtimestampを補完し、insert
ではtimestampを補完しないため値に差異が出てしまっていたこと。
メソッド別クエリまとめ
前提
- 対象は
name
(varchar),created_at
(timestamp)のカラムのみを持つuser
テーブルとUser
モデル - saveは以下のコードを実行する
$user = new User(['name' => 'hoge']);
$user->save();
- insertは以下のコードを実行する
$users = [
['name' => 'hoge'],
];
User::insert($users);
- タイムゾーンは以下とする
- アプリケーションサーバー: JST
- MySQLサーバー: UTC
- 実行日時はUTCの
2025-05-01 00:00:00
save
発行されるクエリ
insert into `user` (`name`, `created_at`) values (`hoge`, 2025-05-01 00:00:00)
設定がNOT NULL DEFAULT CURRENT_TIMESTAMP
created_at
にアプリケーションサーバーのタイムゾーン準拠(JST)の値が入る。
設定なし(NULL許容)
created_at
にアプリケーションサーバーのタイムゾーン準拠(JST)の値が入る。
insert
発行されるクエリ
insert into `user` (`name`) values (`hoge`);
設定がNOT NULL DEFAULT CURRENT_TIMESTAMP
created_at
に**MySQLサーバー準拠の値(UTC)**が入る。
設定なし(NULL許容)
created_at
にNULL
が入る
まとめ
(そもそもtimestamp使わないほうが良いというはなしはいったん横に置いておいて)
DB保存時は同一の値が入るようコード側で記載を統一しておくのが無難と感じた。