Rails のマイグレーションで PostgreSQL の timestamp(0) 型のカラムを作る
目次
タイトル通りですが、Ruby on Rails のマイグレーションで、PostgreSQL の timestamp(0) with time zone
型のカラムを作成する方法を紹介します。普通にやると timestamp with time zone
型になってしまいます。
やり方
まずはやり方ですが、以下のようなマイグレーションファイルを作成し、普通に実行すれば良いです。
class AddColumn1ToTable1 < ActiveRecord::Migration[6.0]
def change
change_table :table1 do |t|
t.datetime :column1, precision: 0
end
end
end
解説・補足
0 って何?
そもそも、 timestamp(0)
の「0」って何かというと、(上のマイグレーションファイルを見れば想像つくかと思いますが)精度です。以下、PostgreSQL のドキュメントから引用します。
ここで、オプションである精度の指定 p は秒フィールドの小数点以下の桁数に一致した整数です。精度は time、timestamp、および interval に対して設定できます。
日付/時刻データ型
ちょっと日本語が分かりにくいので補足すると、
timestamp(0)
は秒までの精度、つまり hh:mm:sstimestamp(3)
は秒以下、小数点3桁までの精度、つまり hh:mm:ss.sss という形でミリ秒までの精度
という感じです。
なぜ精度を指定したいか
なぜ精度を指定したいかという理由ですが、主に以下の2つの理由が考えられます。
- 容量を節約
- 他のアプリケーションとの互換性
前者ですが、精度が低く設定した方がその分データの容量が少なくなるため、レコード数が多いテーブルの場合などは必要な精度を指定した方が良いでしょう。
後者ですが、今回の件で調査しているときに、Laravel と Rails で同じ DB を共有する際に問題となり得る事を知りました(Rails、Laravel、DBMS の種類・バージョンによって、異なる問題がありました)。それらのうちのいくつかの問題を防ぐための方法として、精度を0に指定するというのが挙げられていました。
Rails 6 では、precision: 6 がデフォルトになった
Rails 6 では、precision: 6 がデフォルトになりました。日本語だと以下のページが参考になります。
なぜRails6.0でprecision: 6が追加されたのか? – Qiita
ちなみに、:precision
が設定できるようになったのは、以下を見る限り Rails 4 からのようです。
Allow precision option for postgresql datetimes by tonywok · Pull Request #6821 · rails/rails
MySQL では 5.6.4 から小数点以下がサポートされるようになった
MySQL では、5.6.4 で timestamp 型などで小数点以下の精度がサポートされるようになりました。当初はデフォルトの精度は0ですが、その後しばらく経った後でにデフォルトが6に変更されています。
MySQL :: MySQL 5.6 Release Notes :: Changes in MySQL 5.6.4 (2011-12-20, Milestone 7)
まとめ
RDBMS の timestamp 型は(古い MySQL などを除き)小数点以下の値も保持できます。Rails のマイグレーションで timestamp 型のカラムを作ると、デフォルトでは precision: 6
(精度6桁)が設定されるので、小数点以下の6桁、つまりマイクロ秒まで保存できます。
ただ、秒より小さい値は必要無いユースケースも多いと思いますので、その場合は precision: 0
を明示的に指定することをお勧めします。
コメントを残す