概要
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保存時は同一の値が入るようコード側で記載を統一しておくのが無難と感じた。