質問

datetime または timestamp フィールドとその理由(MySQLを使用)

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

役に立ちましたか?

解決

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

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

他のヒント

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

デフォルトでは、各接続の現在のタイムゾーンはサーバーの時間です。 MySQLサーバーのタイムゾーンサポート

行のメタデータ(作成日または変更日)以外には、常に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の下限に達する可能性が非常に高くなります。生年月日を保存します。

次の例は、 time-zoneを 'america / new_york' where DATETIME に変更した後、 TIMESTAMP 日付タイプが値をどのように変更したかを示しています変更されていません。

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:日時とタイムスタンプのデータ型

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

したがって、—または、将来的には—タイムゾーン間でクラスターを同期します。

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

TIMESTAMPが使用されるべきであったDATETIMEが使用されている素晴らしい例はFacebookであり、彼らのサーバーはタイムゾーンを越えて何が起こったかを完全に確信していません。メッセージが実際に送信される前に、メッセージに返信しているという時間の会話がありました。 (もちろん、これは、時刻が同期ではなく投稿されていた場合、メッセージングソフトウェアのタイムゾーン変換が不適切だったために発生した可能性もあります。)

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

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

日付/時刻を任意に設定および変更できる場合、日時フィールドを使用します。たとえば、ユーザーが後で変更予定を保存できる場合。

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

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

しかし、scronideが1970年の下限を持っていると言ったように、それは将来起こるかもしれないものには素晴らしい;)

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ドル)をデータベースに保存する方法と密接に関連しています。 Decimal、データベースのMoneyタイプ、または最悪のDoubleを使用する必要がありますか?上記の同じ理由の多くのため、これらの3つのオプションはすべてひどいものです。解決策は、BIGINTを使用して金額をセント単位で保存し、ユーザーに値を表示するときにセントをドルに変換することです。データベースの仕事はデータを保存することであり、そのデータを解釈することではありません。データベース(特にOracle)で見られるこれらすべての素晴らしいデータ型はほとんど追加せず、ベンダーロックインへの道を歩み始めます。

  1. TIMESTAMPは、DATETIMEの8バイトに対して4バイトです。

  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設定の影響を受けます。

実際にはアプリケーションに依存します。

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

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

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

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

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

timestamp フィールドは、 datetime フィールドの特殊なケースです。 timestamp 列を作成して、特別なプロパティを設定できます。作成および/または更新のいずれかで自身を更新するように設定できます。

"より大きな"データベース用語、 timestamp にはいくつかの特殊なケースのトリガーがあります。

正しいものは、何をしたいかによって完全に異なります。

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

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

DATETIME、TIMESTAMP、DATEの比較

ここに画像の説明を入力

その[.fraction]とは

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

出典:

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

on update CURRENT_TIMESTAMP

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

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

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

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

たとえば、登録日フィールドを持つ user テーブルを考えてみましょう。その user テーブルで、特定のユーザーの最後にログインした時間を知りたい場合は、 timestamp タイプのフィールドに移動して、フィールドが更新されるようにします。

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

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

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

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

詳細については、ブログ投稿 タイムスタンプと日付時刻をご覧ください。

多くの日時情報を扱う場合、特にタイムゾーンの調整、日付の追加/減算などを行う場合は、単に単純にUnixタイムスタンプを使用します。タイムスタンプを比較するとき、これはタイムゾーンの複雑な要素を除外し、より重い日時の加算/減算ではなく軽量演算を使用するため、サーバー側の処理(アプリケーションコードまたはデータベースクエリ)でリソースを節約できます関数。

検討する価値があるもう1つのこと:

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

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

UPDATE table
SET age = 30

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

この記事からの参照:

主な違い:

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′

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

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

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

つまり、要約すると、タイムスタンプのこの利点を高く評価しています:

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

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

主な違いは

こちらをご覧ください投稿して日時インデックスの問題を確認

タイムスタンプと日時のもう1つの違いはタイムスタンプにあり、デフォルト値をNULLにすることはできません。

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

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

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

+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       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.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

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

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

TIMESTAMPは、タイムゾーンの異なるさまざまな国からの訪問者がいる場合に便利です。 TIMESTAMPを任意の国のタイムゾーンに簡単に変換できます

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top