2959

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

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

4

39 に答える 39

1998

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

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

于 2009-01-03T16:26:17.313 に答える
1010

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

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

于 2009-03-02T11:49:07.727 に答える
588

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

MySQLのドキュメントに記載されているように:

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

..。

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

一般的に使用されているタイムスタンプの下限に達する可能性が非常に高くなります。たとえば、誕生日の保存などです。

于 2009-01-04T04:26:29.780 に答える
361

以下の例は、変更されていない場所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:日時とタイムスタンプのデータ型を見つけられるように、回答を記事に変換しました。

于 2011-08-21T08:45:29.977 に答える
215

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

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

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

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

于 2010-01-14T14:26:35.403 に答える
135

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

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

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

于 2009-01-03T17:11:46.193 に答える
133

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 と同じように「日時」を理解するわけではありません。これらのカスタム データ型を使用している場合、Hibernate で java.sql.TimeStamp または java.util.Date オブジェクトを使用する必要があるかどうかを試してみてください。基本データ型を使用すると、サードパーティのツールを簡単に使用できます。

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

于 2014-06-11T23:02:10.827 に答える
105

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

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

しかし、scronideが言ったように、1970年の下限があります.将来起こる可能性のあるものには素晴らしいです;)

于 2009-01-04T09:00:36.573 に答える
54

本当に、アプリケーションに依存します。

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

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

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

タイムスタンプもデータベース上で軽量であり、インデックス作成が高速です。

于 2010-10-26T21:07:28.183 に答える
44

ない。DATETIMEand型は、TIMESTAMP一般的なユース ケースでは根本的に壊れています。MySQL は将来それらを変更します。BIGINT他の何かを使用する特別な理由がない限り、UNIX タイムスタンプを使用する必要があります。

特殊なケース

選択がより簡単で、この回答の分析と一般的な推奨事項が必要ない特定の状況を次に示します。

  • 日付のみ— 日付のみ (次の旧正月の日付、2022 年 2 月 1 日など) を気にし、その日付が適用されるタイムゾーンを明確に理解している場合 (または、次の場合のように気にしない場合)旧正月の)DATE列タイプを使用します。

  • 挿入時間を記録する— データベース内の行の挿入日時をログに記録していて、アプリケーションが今後 17 年以内に壊れてもかまわない場合TIMESTAMPは、デフォルト値の を使用してCURRENT_TIMESTAMP()ください。

なぜTIMESTAMP壊れているのですか?

TIMESTAMPタイプは UTC タイムゾーンでディスクに保存されます。これは、サーバーを物理的に移動しても壊れないことを意味します。いいですよね✅。ただし、現在定義されているタイムスタンプは、2038 年には完全に機能しなくなります❌。

INSERT INTOあなたまたは列SELECT FROMのたびTIMESTAMPに、クライアント/アプリケーション サーバーの物理的な場所 (つまり、タイムゾーンの構成) が考慮されます。アプリケーション サーバーを移動すると、日付が壊れます ❌。

なぜVARCHAR壊れているのですか?

このVARCHAR型を使用すると、非ローカルの日付/時刻/両方を ISO 8601 形式で明確に保存でき、2037 年以降の日付に対しても機能します。Zulu 時刻を使用するのが一般的ですが、ISO 8601 では任意のオフセットをエンコードできます。MySQL の日付と時刻の関数は、日付/時刻/両方が予期される場所の入力として文字列をサポートしますが、入力がタイムゾーン オフセットを使用する場合、結果は正しくないため、これはあまり役に立ちません。

またVARCHAR、余分なバイト数のストレージも使用します。

なぜDATETIME壊れているのですか?

aDATETIMEは aDATEと aTIMEを同じ列に格納します。タイムゾーンが理解されない限り、これらのことはどちらも意味がなく、タイムゾーンはどこにも保存されません❌。タイムゾーンはデータと密接に関連しているため、目的のタイムゾーンをコメントとして列に入力する必要があります。列コメントを使用する人はほとんどいないため、これは発生するのを待っている間違いです。私はアリゾナからサーバーを継承したので、常にすべてのタイムスタンプをアリゾナ時間から別の時間に変換する必要があります。

(更新 2021-12-08 何年にもわたる稼働時間の後にサーバーを再起動し、データベース クライアント (アップグレードあり) が UTC にリセットされました。つまり、アプリケーションはリセットの前後の日付を異なる方法で処理する必要があります。ハードコード!)

DATETIMEaが正しい唯一の状況は、次の文を完成させることです。

あなたの 2020 年の太陽の新年はちょうど に始まりますDATETIME("2020-01-01 00:00:00")

sには他に良い使い方はありませんDATETIME。おそらく、デラウェア州の市政府の Web サーバーを想像するでしょう。確かに、このサーバーとこのサーバーにアクセスするすべての人々のタイムゾーンは、東部タイムゾーンのデラウェアにあると暗示される可能性がありますよね? 違う!このミレニアムでは、サーバーは「クラウド」に存在すると考えられています。したがって、サーバーはいつか移動するため、特定のタイムゾーンでサーバーを考えるのは常に間違っています.

注: MySQLはリテラルでタイム ゾーン オフセットをサポートするようになりました ( @Marko に感謝します)。これにより、 s の挿入がより便利になるかもしれませんが、データの不完全で無用な意味には対応していません。この致命的な問題は、上記の ("❌") を識別します。DATETIMEDATETIME

使い方はBIGINT

定義:

CREATE TEMPORARY TABLE good_times (
    a_time BIGINT
)

特定の値を挿入します。

INSERT INTO good_times VALUES (
    UNIX_TIMESTAMP(CONVERT_TZ("2014-12-03 12:24:54", '+00:00', @@global.time_zone))
);

またはもちろん、これは次のようにアプリケーションからはるかに優れています。

$statement = $myDB->prepare('INSERT INTO good_times VALUES (?)');
$statement->execute([$someTime->getTimestamp()]);

選択する:

SELECT a_time FROM good_times;

ここでの範囲を超えて、相対的な時間 (過去 30 日以内の投稿を選択し、登録から 10 分以内に購入したユーザーを見つける) をフィルタリングする手法があります。

于 2019-12-23T18:56:35.603 に答える
43

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

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

于 2010-08-25T23:21:57.363 に答える
41

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

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

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

于 2009-01-03T16:21:04.190 に答える
35

DATETIME、TIMESTAMP、DATE の比較

ここに画像の説明を入力

[.fraction] とは何ですか?

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

ソース:

于 2017-08-11T09:53:30.207 に答える
29

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

on update CURRENT_TIMESTAMP

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

于 2012-01-06T23:04:05.227 に答える
27

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

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

于 2009-01-03T16:18:25.520 に答える
20

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

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

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

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
于 2012-02-06T03:34:03.820 に答える
17

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

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

詳細については、ブログ投稿Timestamp Vs Datetimeを参照してください。

于 2012-12-20T08:48:36.037 に答える
16

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

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

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

于 2012-01-05T02:50:33.843 に答える
12

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

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

于 2011-11-01T19:42:18.347 に答える
10

主な違いは

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

于 2014-03-07T12:09:05.187 に答える
10

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

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

タイムゾーンなしで日時を使用すると、アプリケーションが 1 つのタイムゾーンのみを処理することになりますが、タイムスタンプを使用するとdatetime、異なるタイムゾーンで正確に同じ時点を表示できるという利点と柔軟性が得られます。

datetime使用を後悔し、タイムスタンプでデータを保存したいと思ういくつかのケースを次に示します。

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

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

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

要するに

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

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


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

于 2019-02-05T19:18:27.107 に答える
9

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

于 2014-01-19T11:06:09.197 に答える
8

私はタイムスタンプを使用することを好みます。これにより、すべてを 1 つの一般的な生の形式に保ち、データを PHP コードまたは SQL クエリでフォーマットすることができます。コード内ですべてを数秒で保持できると便利な場合があります。

于 2009-01-04T07:49:18.933 に答える
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);
于 2011-04-28T17:34:02.793 に答える
3

これまで言及されていなかったのは、DEFAULT CURRENT_TIMESTAMP は Timestamp でのみ機能し、DateTime タイプのフィールドでは機能しないということです。

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

于 2016-11-03T19:27:00.107 に答える
3

ここでの多くの回答は、明確に定義された時点を表す必要がある場合に備えて、タイムスタンプとして保存することを提案しています。ただし、慣例によりすべてを UTC で保存する場合は、datetime で特定の時点を持つこともできます。

于 2016-06-28T07:50:40.287 に答える
3

BIGINTUTCの保存中に署名なしを使用するだけです...

その後、PHP で現地時間に調整することができます。

DATETIME選択しFROM_UNIXTIME( integer_timestamp_column )ます。

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

于 2016-05-23T11:20:02.590 に答える