web-dev-qa-db-ja.com

MySQLではdatetimeまたはtimestampデータ型を使うべきですか?

datetime または timestamp フィールドを使用することをお勧めしますか。その理由(MySQLを使用)。

私はPHPをサーバ側で使っています。

2490
karlipoppins

MySQLのタイムスタンプは一般にレコードへの変更を追跡するために使用され、レコードが変更されるたびに更新されることがよくあります。特定の値を保存したい場合は、datetimeフィールドを使うべきです。

UNIXのタイムスタンプとMySQLのネイティブのdatetimeフィールドのどちらを使用するかを決めたい場合は、ネイティブフォーマットを使用してください。 MySQL内でそのように計算を行うことができます。 ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")であり、レコードを照会するときにPHPで操作する場合は、値の形式をUNIXタイムスタンプ("SELECT UNIX_TIMESTAMP(my_datetime)")に変更するのが簡単です。

1654
blivet

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

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

851
Nir

私は常にDATETIMEフィールドを行メタデータ(作成日または修正日)以外に使用します。

言及された としてMySQLのドキュメントで:

DATETIME型は、日付と時刻の両方の情報を含む値が必要なときに使用されます。 MySQLはDATETIME値を取得して 'YYYY-MM-DD HH:MM:SS'の形式で表示します。サポートされている範囲は「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の下限にぶつかる可能性が高いです。誕生日を保存します。

467
scronide

以下の例は、TIMESTAMPが変更されていないtime-zone to 'america/new_york'を変更した後に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:日付とタイムスタンプのデータ型

299
mr_eclair

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

したがって、時間帯をまたがってクラスタを同期化した場合、または将来同期化する可能性がある場合にのみ重要です。

簡単に言うと、 オーストラリアにデータベースがあり、そのデータベースのダンプを取ってアメリカのデータベースを同期/設定すると、TIMESTAMPは新しいタイムゾーンのイベントのリアルタイムを反映するように更新されますDATETIMEはそれでもauタイムゾーンのイベントの時刻を反映します

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

182
ekerner

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

(多かれ少なかれ)定点を記録する必要があるときは、タイムスタンプを使います。たとえば、レコードがデータベースに挿入されたとき、またはユーザーの操作が行われたときなどです。

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

115
unbeknown

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

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

しかしscronideが言ったようにそれは1970年の下限を持っていると言いました。

92
Alex
  1. TIMESTAMPは、DATETIMEでは4バイト対8バイトです。

  2. タイムスタンプもデータベース上で軽量化され、より高速に索引付けされます。

  3. DATETIME型は、日付と時刻の両方の情報を含む値が必要なときに使用されます。 MySQLはDATETIME値を「YYYY-MM-DD HH:MM:SS」形式で取得して表示します。サポートされている範囲は「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. TIMESTAMPがtime_zone設定によって影響を受ける間、DATETIMEは一定です。
89
Vivek S

どちらも使用しないことをお勧めします DATETIMEまたはTIMESTAMPフィールド。特定の日を全体として(誕生日のように)表現したい場合は、DATE型を使用しますが、それより具体的な場合は、実際の瞬間を記録することに興味があるでしょう。時間(日、週、月、年)。 DATETIMEまたはTIMESTAMPを使用する代わりに、BIGINTを使用し、Epoch(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ドル)をデータベースに格納する方法と密接に関係しています。 Decimal、データベースのMoneyタイプ、または最悪のDoubleのいずれを使用する必要がありますか?上記の同じ理由の多くのために、これらのオプションの3つすべてがひどいです。解決策は、BIGINTを使用してお金の価値をセントで格納し、その値をユーザーに表示するときにセントをドルに変換することです。データベースの仕事はデータを保存することであり、そのデータを解釈しないことです。データベース(特にOracle)に見られるこれらの空想的なデータ型はすべて、ほとんど追加されず、ベンダーのロックインへの道を切り開きます。 

88
user64141

本当にアプリケーションによります。

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

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

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

タイムスタンプもデータベース上で軽量化され、より高速に索引付けされます。

41
ianaré

2016 +:MysqlのタイムゾーンをUTCに設定してDATETIMEを使用することをお勧めします。

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

さらに:

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


AngularJを使った例

// 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

37
Sebastien Horin

timestampフィールドはdatetimeフィールドの特殊なケースです。特別なプロパティを持つためにtimestampカラムを作成することができます。作成時および/または更新時に自分自身を更新するように設定できます。

「より大きな」データベースの用語では、timestampには2つの特別な場合のトリガーがあります。

正しいものは、あなたがやりたいことに完全に依存します。

32
Jeff Warnica

TIMESTAMPは常にUTC(つまり、1970-01-01からの経過秒数、UTC)であり、MySQLサーバーはそれをサーバータイムゾーンの日付/時刻に自動変換します。長期的に見れば、TIMESTAMPはあなたの一時的なデータが常にUTCであることを知っているので行く道です。たとえば、別のサーバーに移行した場合や、サーバーのタイムゾーン設定を変更した場合は、日付がおかしくなることはありません。

28
Sobes

DATETIME、TIMESTAMP、およびDATEの比較

enter image description here

それは何ですか?

  • DATETIMEまたはTIMESTAMP値には、末尾の小数秒を最大でマイクロ秒(6桁)の精度で含めることができます。 特に、DATETIME またはTIMESTAMP列に挿入された値の小数部は、破棄されずに格納されます。これはもちろんオプションです。

出典:

24
jdc91

MySQLでは、テーブルカラムを作成するときに、以下の行に沿って何かを使用することができます。

on update CURRENT_TIMESTAMP

これにより、行を変更するたびに時間が更新され、保存されている最後の編集情報に非常に役立ちます。これはタイムスタンプでのみ機能し、datetimeでは機能しません。

21
leejmurphy

MySQLとPHPを扱うときは、常にUnixタイムスタンプを使用します。これがPHPのデフォルトの date メソッドである主な理由は、パラメータとしてタイムスタンプを使用するため、解析は不要です。

PHPで現在のUnixタイムスタンプを取得するには、time();を実行してください。
そしてMySQLではSELECT UNIX_TIMESTAMP();を行います。

20
Mark Davidson

私の経験上、挿入が1回だけ行われる日付フィールドが必要で、その特定のフィールドに対して更新やその他のアクションを実行したくない場合は、 date time を使用してください。

たとえば、 REGISTRATION DATE フィールドを持つuserテーブルを考えます。そのuserテーブルで、特定のユーザーが最後にログインした時刻を知りたい場合は、 timestamp typeのフィールドに移動してフィールドを更新します。

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

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

タイムスタンプデータ型は日付と時刻を格納しますが、UTC形式で格納されます。datetimeのように現在のタイムゾーン形式では格納されません。そしてデータを取得すると、タイムスタンプはそれを現在のタイムゾーンの時間に変換します。

アメリカにいて、アメリカのタイムゾーンがあるサーバーからデータを取得しているとします。その後、米国のタイムゾーンに従って日付と時刻を取得します。タイムスタンプデータ型の列は、行が更新されると必ず自動的に更新されます。そのため、特定の行が最後に更新された時期を追跡するのに役立ちます。

詳細については、ブログ記事タイムスタンプと日付時刻を参照してください。

13
Arvind

この記事からの引用文献:

主な違い:

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'

12
Anvesh

テーブルに対してUPDATE文を実行すると、タイムスタンプが変わることに注意してください。列が「Name」(varchar)、「Age」(int)、および「Date_Added」(タイムスタンプ)の表があり、次のDML文を実行すると

UPDATE table
SET age = 30

それから、あなたの 'Date_Added'カラムのすべての値は現在のタイムスタンプに変更されます。 

12
Lloyd Banks

私はいつもUnixタイムスタンプを使います。多くの日時情報を扱うとき、特にタイムゾーンの調整をするとき、日付の加減算をするときなどに、単に健全性を保つためです。タイムスタンプを比較するとき、これはタイムゾーンの複雑な要素を排除し、より重い日時の加減算ではなく軽量の算術演算を使用するという点で、サーバーサイドの処理(アプリケーションコードかデータベースクエリか)にリソースを浪費させます関数。 

考慮する価値があるもう一つのこと:

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

12
Oliver Holmberg

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

タイムスタンプには暗黙のうちにタイムゾーンが含まれるため、私はほとんどの場合、日時フィールドよりもタイムスタンプを好みます。そのため、アプリが異なるタイムゾーンのユーザーからアクセスされ、現地のタイムゾーンで日付と時刻を表示したいという瞬間から、このフィールドタイプはデータがdatetimeフィールドに保存されている場合よりも簡単にできます。 。

さらに、データベースを別のタイムゾーンを持つシステムに移行する場合は、タイムスタンプを使用するほうが自信があります。 2つの瞬間の間の時間差が2つの瞬間の間の差を計算し、1時間以下の精度を必要とするときに考えられる問題は言うまでもありません。

要約すると、タイムスタンプの利点は次のとおりです。

  • 国際(マルチタイムゾーン)アプリで使用する準備ができて
  • タイムゾーン間の簡単な移行
  • 差を計算するのはとても簡単です(両方のタイムスタンプを引くだけです)。
  • 夏時間の内外の日付について心配する必要はありません。

これらすべての理由から、可能な限りUTCとタイムスタンプフィールドを選択します。そして頭痛を避けます;)

11
rogerpro

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

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

10
Marc DiMillo

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

10
ecleel
10
Charles Faiga

タイムスタンプを使用して、すべてを1つの共通の未加工形式に保ち、データをPHPコードまたはSQLクエリでフォーマットすることをお勧めします。あなたのコードでは、すべてを簡単な時間で管理するのに便利な場合があります。

8
Hans
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       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.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
8
Premraj

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);
7
user723220

TIMESTAMPは4バイト必要ですが、DATETIMEは8バイト必要です。

6
Mwangi Thiga

UTCを格納している間、私は単にunsigned BIGINTを使います...

それでもPHPで現地時間に調整できます。

FROM_UNIXTIME( integer_timestamp_column )で選択されるDATETIME

明らかにその列にインデックスを設定する必要があります、そうでなければ進歩はありません。

4
Martin Zeitler

これまでのところ触れられていませんが、DEFAULT CURRENT_TIMESTAMPはTimestampでのみ動作し、DateTimeタイプのフィールドでは動作しません。 

これは、DateTimeのみを使用し、Timestampを使用できないMS Accessテーブルに関連します。

4
Elliptical view

TIMESTAMPは、異なるタイムゾーンを持つ異なる国からの訪問者がいるときに役立ちます。 TIMESTAMPを任意の国のタイムゾーンに簡単に変換できます

4
Mahdi Jazini

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

何時ですか?そして、答えは「2019-02-05 21:18:30」のようなものであり、それは完了していない、定義されていない答えであり、別の部分がないため、どのタイムゾーンにありますか?ワシントン?モスクワ?北京?

タイムゾーンなしで日付時刻を使用することは、アプリケーションが1つのタイムゾーンのみを処理することを意味しますが、タイムスタンプはdatetimeの利点に加えて、異なるタイムゾーンで同じ正確な時点を表示する柔軟性を提供します。

datetimeを使用して後悔し、データをタイムスタンプに保存することを希望する場合があります。

  1. あなたのクライアントの快適さのために、あなたは彼らに彼らに数学をさせさせず、彼らの意味のある時間帯に時間を変換させることなく彼らの好みの時間帯に基づいて時間を見せたいです。必要なのはタイムゾーンを変更するだけで、アプリケーションコードはすべて同じになります。(実際には、アプリケーションの開始時に常にタイムゾーンを定義するか、PHPアプリケーション)

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

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

要するに

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

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


この回答は、タイムゾーンに関してタイムスタンプの柔軟性と使いやすさを強調するためのものであり、 列のサイズまたは範囲または分数 =。

4
Accountant م

ここでの多くの回答は、明確に定義された時点を表す必要がある場合に備えて、タイムスタンプとして保存することをお勧めします。しかし、慣例に従ってそれらすべてをUTCに格納すれば、日付と時刻の時刻を合わせることもできます。

3
Matthew

アプリケーションが2038年2月に機能しないことを保証したい場合は、TIMESTAMPを使用してください。サポートされている日付の範囲については、REFMANを参照してください。

1
Wilson Hauck

DATETIMEとTIMESTAMPの違い

  1. 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。

  2. MySQL 5.6.4より前では、TIMESTAMPはデータを格納するのに4バイト(小数秒で+ 3バイト)を必要とし、DATETIMEは8バイト(小数秒で+ 3バイト)を必要とします。

  3. MySQL 5.6.4以降、DATETIMEでは小数秒のデータ格納に5バイト+ 3追加バイトが必要です。

    4. MySQL 5+では、TIMESTAMP値は現在時刻からUTCに、またはその逆に変換されますが、DATETIMEは変換を行いません。

  4. TIMESTAMPは現在のタイムゾーン設定とは異なり、DATETIMEは一定のままです。 TIMESTAMPデータは索引付けできますが、DATETIMEデータはできません。

  5. DATETIMEを持つクエリはキャッシュされませんが、TIMESTAMPを持つクエリはキャッシュされます。

0

timestamp Network Time Protocol(NTP) によってコンピュータによって記録されたイベントの現在時刻です。

datetimeは、 _ php _ 設定で設定されている現在のタイムゾーンです。

0
curiosity