MySQLで日時またはタイムスタンプのデータ型を使用する必要がありますか?


2686

日時フィールドまたはタイムスタンプフィールドを使用することをお勧めしますか、そしてその理由(MySQLを使用する)は?

サーバー側でPHPを使用しています。


1
これにはいくつかの関連情報がありますcodeproject.com/Tips/1215635/MySQL-DATETIME-vs-TIMESTAMP
Waqleh

2038年2月にアプリケーションを破壊したい場合は、タイムスタンプを使用します。日付範囲を確認してください。
Wilson Hauck

回答:


1830

MySQLのタイムスタンプは、通常、レコードへの変更を追跡するために使用され、レコードが変更されるたびに更新されることがよくあります。特定の値を保存する場合は、日時フィールドを使用する必要があります。

UNIXタイムスタンプとネイティブMySQL日時フィールドのどちらを使用するかを決定したい場合は、ネイティブ形式を使用してください。その方法でMySQL内で計算を行うことができます。PHPで 操作したい場合、レコードをクエリするときに("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")値の形式をUNIXタイムスタンプ("SELECT UNIX_TIMESTAMP(my_datetime)")に変更するのは簡単です。


981
重要な違いはDATETIME、日付(カレンダーにある)と時刻(壁掛け時計で確認できる)をTIMESTAMP表し、明確に定義された時点を表すことです。アプリケーションがタイムゾーンを処理する場合、これは非常に重要です。「2010-09-01 16:31:00」はどれくらい前ですか?それはあなたがどのタイムゾーンにいるかに依存します。私にとってそれはほんの数秒前でした、あなたにとってそれは将来の時間を表すかもしれません。'1970-01-01 00:00:00 UTC'から1283351460秒と言うと、私がいつ話しているのか正確にわかります。(以下のNirの優れた答えを参照してください)。[欠点:有効範囲]。
MattBianco

121
もう1つの違い:「ネイティブ」の日時を持つクエリはキャッシュされませんが、タイムスタンプを持つクエリはキャッシュされます。
OZ_

39
「MySQLのタイムスタンプは通常、レコードへの変更を追跡するために使用されます」これは良い答えとは思わないでください。タイムスタンプは、マットビアンコとニールが言ったように、それよりもはるかに強力で複雑です。しかし、答えの2番目の部分は非常に良いです。blivetが言ったことは本当であり、良いアドバイスです。
サンティアゴバスルト

10
また、1つの重要な注意として、DATETIMEとTIMESTAMPはデフォルト値としてCURRENT_TIMESTAMP、NOW()をそれぞれ使用できますが、たとえばDATEはデフォルトで「0000-00-00」を使用するため、使用できません。そのテーブルへの独自のトリガー。DATEmysqlタイプを使用してフィールド/列に現在の日付(時間なし)を挿入します。
Arthur Kushman、

14
@DavidHarkness:ドキュメントは、「デフォルトのCURRENT_TIMESTAMPとON UPDATE CURRENT_TIMESTAMP条項を使用し、自動プロパティを指定するには」と言うdev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
PLAP

917

MySQL 5以降では、TIMESTAMP値は現在のタイムゾーンからUTCに変換されて格納され、取得のためにUTCから現在のタイムゾーンに変換されます。(これは、TIMESTAMPデータ型でのみ発生し、DATETIMEなどの他の型では発生しません。)

デフォルトでは、各接続の現在のタイムゾーンはサーバーの時間です。時間帯は、MySQLサーバーの時間帯サポートで説明されているように、接続ごとに設定できます。


11
このOReillyのプレゼンテーションは、このトピックのための非常に良いです(PDF申し訳ありません)cdn.oreillystatic.com/en/assets/1/event/36/...
GCB

13
また、イベントの性質について:-ビデオ会議(タイムスタンプ)。すべてのアテンダントは、そのタイムゾーンに調整された絶対時刻の参照を参照する必要があります。-ローカルタスク時間(DATETIME)、私がこのタスクを2014/03/31 9:00 AMに行う必要があります。その日がニューヨークまたはパリで働いているかどうかは関係ありません。その日の現地時間の午前8時に仕事を始めます。
yucer 2013

1
したがって、サーバーのタイムゾーンを変更した場合、TIMESTAMPの値は同じままになるか、それとも変更されますか?
Andrew

3
@AndrewはUTCなので、UTCのままです。ただし、逆変換は「新しい」サーバーのタイムゾーンに変更されます。
nembleton 2017

@yucer-そのように考えることはお勧めしません。グローバル経済における最も一貫した使用法は、すべての日時をUTCに変換して保存することです。慣例により、日時はUTCフィールドとして扱います。これは、日時を入力してUTCに変換するすべてのタスクに負担をかけますが、長期的にはよりクリーンな設計です。もちろん、現在の設定に基づいてユーザーに情報を提示します。ユーザーが「パリの09:00」と入力する場合は、パリ時間を設定してから09:00と入力します。その後、ニューヨークにある誰でも簡単に会議に、自分の時間で、彼らが目を覚ましする必要が何時に見つけることができます。
ToolmakerSteve

524

行のメタデータ(作成または変更された日付)以外には常にDATETIMEフィールドを使用します。

以下のように述べた MySQLのマニュアルに:

DATETIMEタイプは、日付と時刻の両方の情報を含む値が必要な場合に使用されます。MySQLは 'YYYY-MM-DD HH:MM:SS'形式でDATETIME値を取得して表示します。サポートされる範囲は「1000-01-01 00:00:00」から「9999-12-31 23:59:59」です。

...

TIMESTAMPデータ型の範囲は、 '1970-01-01 00:00:01' UTCから '2038-01-09 03:14:07' UTCです。MySQLのバージョンとサーバーが実行されているSQLモードに応じて、さまざまなプロパティがあります。

一般的に使用されているTIMESTAMPの下限に達する可能性が非常に高くなります(たとえば、誕生日の保存など)。


195
あなたもヒットすることができ、上側あなたは、銀行や不動産にある場合は簡単に... 30年の住宅ローンが2038を越えて行くの制限を
キップ

16
もちろん、64ビットのUnixタイムスタンプを使用してください。たとえば、Javaではnew Date().getTime()、64ビットの値がすでに提供されています。
osa

5
DATETIMEの+1:購入と請求のためにフィジカルストアのSQL ServerからWebページの仮想ストアのMySQLサーバーに転送されるデータフローでは、このデータ型はTransactにも存在するため、変更日時にはDATETIMEの方が適しています-SQL。しかし、TIMESTAMPはTransact-SQLの他のことを意味します。これはROWVERSIONのようなバイナリですが、MySQL TIMESTAMPはDateTimeに似ています。したがって、2つのDBの互換性のためにTIMESTAMPを使用しないようにします。
jacouh 2013年

10
わからない それはちょうどMySQLのよりもはるかに大きな問題だと簡単な修正はありません:en.wikipedia.org/wiki/Year_2038_problem私は、MySQLがちょうどタイムスタンプは今、64ビットを宣言し、すべてがうまくなりますと仮定することができます信じていません。彼らはハードウェアを制御しません。
scronide、2015

5
私の場合と同じように、誕生日を知っていれば、誕生日はDATETIMEになります。
クリスクレイグ

322

次の例はTIMESTAMPtime-zone to 'america/new_york'where DATETIMEが変更されていない後に日付タイプが値を変更した方法を示しています。

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

私は私の回答を記事に変換したので、より多くの人がこの便利なMySQLを見つけることができます:日時とタイムスタンプのデータ型


55
実際、DATETIMEタイムゾーンの変更に伴って有効時間は変更されましたが、変更されTIMESTAMPませんでしたが、人間の表現は変更されました。
flindeberg 14

3
このコマンドはMySQL 5.6では機能しないよう set time_zone="america/new_york"です。
Manjunath Reddy 2016

これは、time_zoneの設定に関する問題の答えです。stackoverflow.com/questions/3451847/mysql-timezone-change
Manjunath Reddy

2
@flindebergに同意します。タイムスタンプは、タイムゾーンの変更後の日付時刻ではなく正しい時刻を表します
Nitin Bansal 2016年

193

主な違いは、TIMESTAMPがtime_zone設定の影響を受ける一方で、DATETIMEは定数であることです。

したがって、タイムゾーン間でクラスターを同期している場合、または将来的には同期している場合にのみ問題になります。

簡単に言えば、オーストラリアにデータベースがあり、そのデータベースのダンプを取得してアメリカのデータベースに同期またはデータを取り込む場合、TIMESTAMPは新しいタイムゾーンのイベントのリアルタイムを反映するように更新され、DATETIMEはまだauタイムゾーンのイベントの時刻を反映しています

TIMESTAMPが使用されているはずのDATETIMEの使用例はFacebookにあります。Facebookのサーバーでは、タイムゾーン全体で発生した時刻が不明です。メッセージが実際に送信される前に、メッセージに返信していると言った会話がありました。(もちろん、これは、時刻が同期されているのではなく投稿されていた場合、メッセージングソフトウェアのタイムゾーン変換が悪いために発生した可能性もあります。)


83
これは良い考えではないと思います。すべての日付をUTCで保存して処理し、フロントエンドが指定されたタイムゾーンに従って日付を表示することを確認します。このアプローチはシンプルで予測可能です。
Kos

8
@コス:すべての日付をUTCで保存および処理しているのは、TIMESTAMPが内部で行っていることとまったく同じではありませんか?(その後、ローカルのタイムゾーンを表示するように変換しますか?)
カルボカチオン

10
私のローカルタイムゾーン?DBはどのようにして私のタイムゾーンを認識しますか?;-)通常、データベースとユーザーインターフェースの間にはかなりの処理があります。ローカリゼーションは、すべての処理の後にのみ行います。
Kos

3
@コズ:私のデータベースはデータベースのタイムゾーンを知りません:!しかし、それはタイムスタンプを知っています。データベースは独自のタイムゾーン設定を認識しており、タイムスタンプを解釈/表すときにそれを適用します。2013年12月11日の午前1時01分、中国の北京は、オーストラリアのシドニーでの2013年12月11日の午前1時1分と同じ時刻ではありません。Google:「タイムゾーン」と「本初子午線」。
ekerner 2013

2
MySQLは、TIMESTAMP値を現在のタイムゾーンからUTCに変換して格納し、取得のためにUTCから現在のタイムゾーンに戻します。(これは、DATETIMEなどの他のタイプでは発生しません。)dev.mysql.com/doc/refman/5.5/en/datetime.html
Mahdyfo

125

この決定はセマンティックベースで行います。

(多かれ少なかれ)一定の時点を記録する必要がある場合は、タイムスタンプを使用します。たとえば、レコードがデータベースに挿入されたときや、ユーザーアクションが発生したときなどです。

日時を任意に設定・変更できる場合は日時フィールドを利用しています。たとえば、ユーザーが後で変更予定を保存できる場合です。


タイムスタンプ-固定時刻、協定世界時の日付時刻-視点からの、時間参照(ejタイムゾーン現地時間)との相対..現地時間の調整?
yucer 2013

110

DATETIMEフィールドもTIMESTAMPフィールド使用しないことをお勧めします。特定の日全体(誕生日など)を表す場合は、DATE型を使用しますが、それよりも具体的である場合は、単位の単位ではなく実際の瞬間を記録することにおそらく興味があります。時間(日、週、月、年)。DATETIMEまたはTIMESTAMPを使用する代わりに、BIGINTを使用し、エポック(Javaを使用している場合はSystem.currentTimeMillis())以降のミリ秒数を格納します。これにはいくつかの利点があります。

  1. ベンダーロックインを回避します。ほとんどすべてのデータベースは、比較的類似した方法で整数をサポートしています。別のデータベースに移動したいとします。MySQLのDATETIME値の違いとOracleがそれらをどのように定義するかについて心配したいですか?MySQLのバージョンが異なる場合でも、TIMESTAMPSの精度レベルは異なります。MySQLがタイムスタンプでミリ秒をサポートしたのはつい最近のことです。
  2. タイムゾーンの問題はありません。さまざまなデータタイプのタイムゾーンで何が起こるかについて、洞察に満ちたコメントがいくつかあります。しかし、これは共通の知識であり、あなたの同僚全員がそれを学ぶために時間をかけますか?一方、BigINTをjava.util.Dateに変更するのはめちゃくちゃ難しいです。BIGINTを使用すると、タイムゾーンに関する多くの問題が発生します。
  3. 範囲や精度についての心配はありません。将来の日付範囲によって何が短縮されるかについて心配する必要はありません(TIMESTAMPは2038にしか行きません)。
  4. サードパーティツールの統合。整数を使用することで、サードパーティツール(EclipseLinkなど)がデータベースとやり取りするのは簡単です。すべてのサードパーティツールがMySQLと同じように「日時」を理解するわけではありません。これらのカスタムデータ型を使用している場合、java.sql.TimeStampまたはjava.util.Dateオブジェクトを使用する必要があるかどうかをHibernateで試してみてください。基本データ型を使用すると、サードパーティのツールで簡単に使用できます。

この問題は、金額(1.99ドル)をデータベースに保存する方法と密接に関連しています。あなたは10進数、またはデータベースのマネータイプ、またはすべての最悪のダブルを使用する必要がありますか?上記の同じ理由の多くのために、これらの3つのオプションはすべてひどいものです。解決策は、BIGINTを使用して金銭の価値をセントで保存し、ユーザーに値を表示するときにセントをドルに変換することです。データベースの仕事はデータを保存することであり、そのデータを解釈することではありません。データベース(特にOracle)に見られるこれらすべての派手なデータ型はほとんど追加せず、ベンダーロックインへの道のりを開始します。


12
私はこのソリューションが好きです。2038年にTIMESTAMPが期限切れになるのは大きな問題です。それはそれほど遠くないです!
チャーリーダルサス

4
@CharlieDalsassあなたは現在のソフトウェアがその時そこにあると思いますか:-P
Habeeb Perwad

13
ミリ秒単位でデータが保存されている場合、日付でデータをクエリするのが難しくなります
Ali Saeed

4
これは、複数のタイムゾーンでの移植性とユーザーの処理、またはユーザーとは異なるタイムゾーンでのデータベースの処理に関心がある場合、本当に最良のソリューションです。TIMESTAMPは、設計上の欠陥がない場合に最適な方法です。壊れたソリューションが早期に(数年!)投稿されたため、投票数が増えたのは残念です。
ドイツ

4
優れたソリューション!そして、あなたはまさに「閉じ込められている」ことを正しく理解しています。あなたが他の人に「あなたのために仕事をさせる」習慣をつけると、あなたはあなたをプログラマーにするための細かい部分を失い始めます。
fmc

98

DATETIMEのTIMESTAMPは4バイト対8バイトです。

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

しかし、scronideが言ったように、1970年の下限はあります。ただし、将来発生する可能性のあるすべてのことには最適です;)


185
未来は2038-01-19 03:14:07 UTCに終了します。
MattBianco、2010

5
それは愚かです。TIMESTAMPタイプは比較的新しいので、「将来の準備ができている」と思いました。異なるタイムゾーンで作業するときに、日付時刻をUTCに変換したり、毎回元に戻したりする必要はありません。TIMESTAMPを大きくする必要があります。少なくとも1バイト大きくする必要があります。さらに68 * 255 = 17340年追加されます... 32ビットで整列されませんが。
NickSoft 2012年

10
TIMESTAMPが2038年に終了する理由を知っていますか?それは整数であり、整数には2147483647の制限があります。これが理由だと思います。彼らがそのタイプをvarcharに変更し、それを操作する方法を変更する場合、それは「将来の準備」になるでしょう。
vinsa 2015年

6
@vinsa、それまでに将来の準備ができるとは思いません。Y2Kバグを覚えていますか?2038年が来ています。
Pacerier、2015

2
2038年までに、MySQL(まだ存在する場合)は、4バイトを超えるようにTIMESTAMPフィールドを更新し、より広い範囲を許可します
the_nuts

95
  1. TIMESTAMPは4バイトですが、DATETIMEでは8バイトです。

  2. タイムスタンプもデータベース上で軽くなり、インデックスが速くなります。

  3. DATETIMEタイプは、日付と時刻の両方の情報を含む値が必要な場合に使用されます。MySQLは 'YYYY-MM-DD HH:MM:SS'形式でDATETIME値を取得して表示します。サポートされる範囲は「1000-01-01 00:00:00」から「9999-12-31 23:59:59」です。

TIMESTAMPデータ型の範囲は、 '1970-01-01 00:00:01' UTCから '2038-01-09 03:14:07' UTCです。MySQLのバージョンとサーバーが実行されているSQLモードに応じて、さまざまなプロパティがあります。

  1. DATETIMEは定数ですが、TIMESTAMPはtime_zone設定の影響を受けます。

6
#4を明確にする必要があります。保存されたタイムスタンプは一定で、タイムゾーンに対して非相対(完全に不可知)ですが、取得時に表示される出力は、要求しているセッションのタイムゾーンの影響を受けます。DATETIMEは常に、それが記録されたタイムゾーンに相対的であり、常にそのコンテキストで考慮される必要があります。現在の責任はアプリケーションにあります。
Christopher McGowan

1
すばらしい答えです。この回答に追加するには、「2038-01-09 03:14:07」を超える値を保存しようとすると、エラーが発生するか、「0000-00-00 00:00:00」として保存されます。(暗号化の目的で)タイムシフトされた値があるため、データベースでこのエラーが発生しました。
KarthikS 2017

また、5.5より前のバージョンのmysqlでは、DEFAULT値を含むDATETIMEに問題があります。dba.stackexchange.com/questions/132951/...
Velaro

47

本当にアプリケーション次第です。

Sanghaiでの予定のために、ニューヨークのサーバーにユーザーがタイムスタンプを設定することを検討してください。ユーザーがSanghaiで接続すると、東京のミラーサーバーから同じ予定のタイムスタンプにアクセスします。彼は東京時間の予定を、最初のニューヨーク時間からオフセットして見るでしょう。

したがって、予定やスケジュールなどのユーザーの時間を表す値の場合は、datetimeの方が適しています。サーバーの設定に関係なく、ユーザーは希望する正確な日付と時刻を制御できます。設定時刻は設定時刻であり、サーバーのタイムゾーン、ユーザーのタイムゾーン、または夏時間の計算方法の変更による影響はありません(変更されます)。

一方、支払いトランザクション、テーブル変更、ロギングなどのシステム時間を表す値には、常にタイムスタンプを使用します。サーバーを別のタイムゾーンに移動したり、異なるタイムゾーンのサーバー間を比較したりしても、システムは影響を受けません。

タイムスタンプもデータベース上で軽くなり、インデックスが速くなります。


アプリケーションはサーバーのタイムゾーンに依存しないでください。アプリケーションは常に、クエリを発行する前に、使用するデータベース接続のセッションでタイムゾーンを選択する必要があります。接続が複数のユーザー間で共有されている場合(例:webapp)、UTCを使用し、レンダリング側でタイムゾーン変換を行います。
ドルメン

42

2016 +:私のアドバイスは、MysqlタイムゾーンをUTCに設定し、DATETIMEを使用することです。

最近のフロントエンドフレームワーク(Angular 1/2、react、Vueなど)では、UTCの日時を現地時間に簡単かつ自動的に変換できます。

さらに:

(サーバーのタイムゾーンを変更する可能性が高い場合を除く)


AngularJsの例

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

ここで利用可能なすべてのローカライズされた時刻形式:https : //docs.angularjs.org/api/ng/filter/date


8
サーバーのタイムゾーン設定にデータを添付しないでください。たぶん、机の下にMySqlボックスが1つあれば問題なく動作します
Jin

@Jin UTCは、TIMESTAMPのようなタイムゾーンがないことを意味します。すべてのサーバーがUTCである場合、問題はありません。たぶん、2000年代の設定を持っているなら、それはあなたのために働いていません。
Sebastien Horin 2016年

TIMESTAMPは、将来64ビット値にアップグレードされる可能性があります。その後、問題はありません。
twicejr

このようなものをキャッチするためにサードパーティのライブラリ全体をロードすることも、パフォーマンスにとってそれほど優れているとは言えませんか?それがクライアント側であり、データベースに影響を与えないことを考えると...それでも、フロントエンドで行うことはすべて、サーバー側のチェックが必要になります。だから、のことを考えて、完全な絵、それは実際の速度の問題を助けていますか?-ちなみに、これらのベンチマークは少し奇妙だと思います。クエリで文字列を使用してタイムスタンプフィールドを比較することも、かなり奇妙に感じられます。それもパフォーマンスに悪影響を与えるに違いありません。
NoobishPro 2017

1
アプリケーションをサーバーのtime_zoneに依存しないでください。代わりに、各データベース接続で使用するtime_zoneを定義します(SET time_zone = '+0:00';UTCの場合)。
ドルメン

37

timestampフィールドには、特殊なケースであるdatetimeフィールド。timestamp特別なプロパティを持つ列を作成できます。作成時または更新時に自身を更新するように設定できます。

「より大きな」データベース用語でtimestampは、それにいくつかの特別なケースのトリガーがあります。

どれが正しいかは、あなたが何をしたいかに完全に依存します。


6
いいえ、違いは単なる「特別なケース」ではありません。値を設定/照会するセッションのタイムゾーンが異なるため、値の関係が異なります。
ドルメン

「何が正しいかはあなたが何をしたいかに完全に依存する」とあなたが入れてうれしい。SEには、「Xを実行してはならない」または「常に Y 実行する必要がある」という十分な正当性がない状態での回答が多すぎます。
Agi Hammerthief

37

TIMESTAMPは常にUTC(つまり、1970-01-01からの経過秒数、UTC)であり、MySQLサーバーはそれを接続タイムゾーンの日付/時刻に自動変換します。長期的には、時間データは常にUTCになることがわかっているため、TIMESTAMPが適しています。たとえば、別のサーバーに移行したり、サーバーのタイムゾーン設定を変更したりしても、日付が台無しになることはありません。

注:デフォルトの接続タイムゾーンはサーバーのタイムゾーンですが、セッションごとに変更することができます(推奨)(を参照SET time_zone = ...)。


29

DATETIME、TIMESTAMP、DATEの比較

ここに画像の説明を入力してください

[.fraction]とは何ですか?

  • DATETIMEまたはTIMESTAMP値には、マイクロ秒(6桁)までの精度で後続の小数秒の部分を含めることができます。特に、DATETIME列またはTIMESTAMP列に挿入された値の小数部分は、破棄されるのではなく保存されます。これはもちろんオプションです。

出典:


24

MySQLとPHPを使用する場合は、常にUnixタイムスタンプを使用します。これの主な理由は、PHPのデフォルトの日付メソッドがタイムスタンプをパラメーターとして使用するため、解析は必要ありません。

PHPで現在のUnixタイムスタンプを取得するにはtime();
、MySQLで行いますSELECT UNIX_TIMESTAMP();


6
-1私は実際には以下の答えの方が良いと思います-datetimeを使用すると、日付処理のロジックをMySQL自体にプッシュできるため、非常に便利です。
Toby Hede

MySQLでのソートがphpよりも遅いことを示すベンチマークはありませんか?
sdkfasldf 2010年

状況によって異なりますが、strtotimeを使用したくない場合に使用するとよい場合があります。(php5.3 dep)
アダムラマダン

必要に応じてFROM_UNIXTIMEを使用するだけで、ロジックをmysqlにプッシュできます
inarilo

私はPHPアプリケーションとMySQLですべてのUnixタイムスタンプを使用していましたが、MySQLに日付と時刻をネイティブの日付/時刻型として保存する方がはるかに便利であることがわかりました。これは、レポート作成やデータセットの閲覧に特に役立ちます。時間の経過とともに、Unixタイムスタンプをコピー/貼り付けしなければならないことに苛立ちを感じ、切り替えを開始しました。パフォーマンスや他の長所/短所があることは確かですが、ユースケースによっては、かなり微細な最適化よりも利便性の方が重要な場合があります。
DavidScherer、

24

MySQLでは、テーブルカラムを作成するときに以下の行に沿って何かを使用できることに注意してください。

on update CURRENT_TIMESTAMP

これにより、行を変更する各インスタンスの時刻が更新され、保存されている最終編集情報に非常に役立つことがあります。ただし、これはタイムスタンプでのみ機能し、日時では機能しません。


17

私の経験から、挿入が1回だけ行われる日付フィールドが必要で、その特定のフィールドで更新やその他のアクションを実行したくない場合は、日付時刻を使用します。

たとえばuserREGISTRATION DATEフィールドを持つテーブルを考えてみます。そのuserテーブルで、特定のユーザーが最後にログインした時刻を知りたい場合は、タイムスタンプタイプのフィールドを使用して、フィールドが更新されるようにします。

phpMyAdminからテーブルを作成している場合、デフォルト設定では、行の更新が発生したときにタイムスタンプフィールドが更新されます。タイムスタンプフィールドが行更新で更新されない場合は、次のクエリを使用して、タイムスタンプフィールドを自動更新できます。

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

15

タイムスタンプデータ型は日付と時刻を格納しますが、datetimeのように現在のタイムゾーン形式ではなくUTC形式で格納します。そして、データをフェッチすると、timestampは再びそれを現在のタイムゾーン時間に変換します。

たとえば、米国にいて、米国のタイムゾーンを持つサーバーからデータを取得するとします。次に、米国のタイムゾーンに従って日付と時刻を取得します。タイムスタンプデータタイプの列は、行が更新されると常に自動的に更新されます。そのため、特定の行が最後に更新された日時を追跡すると便利です。

詳細については、ブログ投稿Timestamp Vs Datetimeをご覧ください


SET time_zone = '+0:00';から取得/設定するTIMESTAMP値を確認し、変更される可能性のあるサーバーのtime_zoneのデフォルトに依存しないようにするために、(ここではUTC )を使用して、常にセッションレベルでタイムゾーンを定義できます(推奨)。
ドルメン

14

私は常にUnixタイムスタンプを使用しています。これは、多くの日時情報を扱う場合、特にタイムゾーンの調整や日付の追加/減算などを行う場合に、正気を保つためです。タイムスタンプを比較する場合、これによりタイムゾーンの複雑な要素が除外され、サーバー側の処理(アプリケーションコードでもデータベースクエリでも)でリソースを節約できるため、より重い日付/時刻の加算/減算ではなく、軽量の計算を利用できます。機能。

考慮に値するもう1つのこと:

アプリケーションを構築している場合、データを将来どのように使用する必要があるかはわかりません。たとえば、データセット内の一連のレコードを、たとえば、サードパーティのAPIからの一連のアイテムと比較し、時系列順に並べる必要がある場合は、次のようになります。行のUnixタイムスタンプ。MySQLタイムスタンプを使用する場合でも、保険としてUnixタイムスタンプを保存してください。


14

私の場合、システム、データベースサーバーなど、可能な限りすべての時間帯としてUTCを設定しています。顧客が別のタイムゾーンを必要とする場合は、アプリでそれを構成します。

タイムスタンプには暗黙的にタイムゾーンが含まれるため、ほとんどの場合、日時フィールドではなくタイムスタンプを使用します。そのため、さまざまなタイムゾーンのユーザーからアプリにアクセスし、ローカルタイムゾーンの日付と時刻を表示したいとき、このフィールドタイプを使用すると、データが日時フィールドに保存されている場合よりも簡単に実行できます。 。

さらに、データベースを別のタイムゾーンのシステムに移行する場合は、タイムスタンプを使用する方が自信があります。シュマー時間の変化があり、1時間以下の精度が必要な2つの瞬間間の差を計算する場合に起こり得る問題は言うまでもありません。

要約すると、私はこのタイムスタンプの利点を評価します:

  • 国際(マルチタイムゾーン)アプリですぐに使用できます
  • タイムゾーン間の簡単な移行
  • 差分の計算はかなり簡単です(両方のタイムスタンプを引くだけです)
  • 夏期の日付の出入りの心配はありません

このすべての理由から、可能な場合はUTCおよびタイムスタンプフィールドを選択します。そして私は頭痛を避けます;)


2038年1月20日が到着すると、タイムスタンプデータはアプリケーションをサポートする人にとって楽しいものになります。tick tock tick tock
Wilson

次に、タイムスタンプタイプを少し増やし、可能な値を2倍にします。
ロジャーカンパネラ

2038年2月1日を正常に保存し、MySQLで取得できるかどうかを理論的にテストして「少しずつ増やす」。終了したらテーブル定義を見てみましょう。あなたはおそらく、2038
Wilson

1
@WilsonHauckとにかく、2038年よりずっと前にMySQLバージョンをアップグレードする必要があります。そして、その拡張されたTIMESTAMPは、マイグレーションによって処理されます。また、住宅ローンを処理することを除いて、いくつかのアプリケーションは、現在2038について気にする必要があります。
ドルメン、

@dolmenプロ仕様の工具や材料の多くには、20年以上の保証が付いています。したがってwarranties.expires_at、今日のようなものはMySQLタイムスタンプにすることはできません。
alexw

13

テーブルでUPDATEステートメントを実行するときは、タイムスタンプの変更に注意してください。'Name'(varchar)、 'Age'(int)、 'Date_Added'(timestamp)の列を持つテーブルがあり、次のDMLステートメントを実行した場合

UPDATE table
SET age = 30

次に、 'Date_Added'列のすべての値が現在のタイムスタンプに変更されます。


3
テーブルの設定方法に基づいて、この動作を制御できます。見dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html
チャールズFaiga

5
@CharlesFaigaデフォルトの動作では、他の列が更新されるとタイムスタンプが更新されます。あなたはタイムスタンプが元の値を保持したい場合は、明示的にこれをオフにする必要がある
ロイド・バンクス

それは何ですか ?!timstamp列を次のように設定する必要がありますON UPDATE CURRENT_TIMESTAMP
Accountantم

これは、テーブルを作成するときに明示的に有効にする必要がある機能です。
ドルメン、

13

この記事からの参照:

主な違い:

TIMESTAMPは、レコードへの変更を追跡し、レコードが変更されるたびに更新するために使用されます。DATETIMEは、レコードの変更の影響を受けない特定の静的な値を格納するために使用されます。

TIMESTAMPは、異なるTIME ZONE関連の設定の影響も受けます。DATETIMEは定数です。

TIMESTAMPは、現在のタイムゾーンを内部的にUTCに変換して保存し、取得時に現在のタイムゾーンに変換し直しました。DATETIMEはこれを行うことができません。

TIMESTAMPでサポートされている範囲: '1970-01-01 00:00:01' UTCから '2038-01-19 03:14:07' UTC DATETIMEでサポートされている範囲: '1000-01-01 00:00:00'から '9999 -12-31 23:59:59 ′


11
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.    | DATETIME supported range: 1000-01-01 00:00:00 to 9999-12-31 23:59:59 |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

10

TimestampとDatetimeのもう1つの違いは、Timestampのデフォルト値をNULLにできないことです。


8
それは明らかに間違っています。次に例 CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);を示します。最初の列はNULL値を受け入れることができます。
Ormoz

10

不要なトリガーを使用せずに現在の時刻に基づいて自動更新するTIMESTAMPの機能には、比類のない有用性があることがわかりました。TIMESTAMPは言われているようにUTCですが、それは私だけです。

さまざまなタイムゾーンにまたがって追跡できるため、たとえば相対時間を表示する必要がある場合は、UTC時間が必要です。


9

主な違いは

この投稿を見て、日時インデックスの問題を確認してください


6
列の値に基づく関数で選択している場合、両方に同じ問題があり、両方にインデックスを付けることができます。
Marcus Adams、

4
インデックスはタイムスタンプで機能し、日時では機能しませんか?あなたはそれらの投稿から間違った結論を導き出しました。
Salman A

9

datetimeタイムゾーンに関連する多くの問題やバグに直面した後、アプリケーションでの使用をやめました。私見の使用timestampdatetimeほとんどの場合よりも優れていますます。

何時ですか?答えは「2019-02-05 21:18:30」のようなもので、別の部分が欠けているため、未完成、未定義の回答、どのタイムゾーンですか?ワシントン?モスクワ?北京?

タイムゾーンなしで日時を使用すると、アプリケーションは1つのタイムゾーンしか処理しませんが、タイムスタンプには次の利点があります datetime異なるタイムゾーンで同じ正確な時点を表示あります。

使用を後悔しdatetime、タイムスタンプにデータを保存したい場合があります。

  1. クライアントが快適に過ごせるようにするには、計算を行わず、時間を意味のあるタイムゾーンに変換せずに、希望するタイムゾーンに基づいて時間を表示する必要があります。必要なのはタイムゾーンを変更することだけで、すべてのアプリケーションコードは同じになります。(実際には、アプリケーションの開始時に常にタイムゾーンを定義するか、PHPアプリケーションの場合はリクエスト処理を行う必要があります)

    SET time_zone = '+2:00';
  2. 滞在する国を変更し、別のタイムゾーンでデータを見ながら(実際のデータを変更せずに)データを維持する作業を続けます。

  3. 世界中のさまざまなクライアントからのデータを受け入れ、それぞれが自分のタイムゾーンに時刻を挿入します。

要するに

datetime =アプリケーションは1つのタイムゾーンをサポート(挿入と選択の両方)

timestamp =アプリケーションは任意のタイムゾーンをサポート(挿入と選択の両方)


この回答は、タイムゾーンに関してタイムスタンプの柔軟性と使いやすさを強調するためのものであり、列のサイズや範囲、割合などの他の違いについては説明していません。


を使用するフィールドがdateあり、他のフィールドtimestampが1つのテーブルで使用している場合はどうなりますか。フィルタリングされたデータがwhereタイムゾーンの変更に準拠していないため、新しい問題が発生すると思います。
Erlang P

@ErlangPその場合、アプリケーションはdateクエリを送信する前に列のタイムゾーンの問題を修正する必要があります。
会計士

7

タイムスタンプを使用してすべてを1つの共通の未加工形式で保持し、データをPHPコードまたはSQLクエリでフォーマットすることを好みます。すべてを単純な秒単位で維持することがコードで便利な場合があります。



6

Unixタイムスタンプが好きです。数値に変換して、その数値を気にするだけだからです。さらに、期間を加算/減算して取得します。その後、結果を任意の形式で日付に変換します。このコードは、ドキュメントのタイムスタンプと現在の時刻の間に経過した分数を調べます。

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);

4
または、人間が読み取り可能なネイティブのMySQL日時を使用し、ネイティブのMySQL関数を使用して日時を追加/減算します。
ジュリアンパラード2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.