MySQLカレンダーデータタイプ:使用機能

MySQL 5には、日付と時刻を保存するためのいくつかのタイプのデータがあります。 これらは、TIMESTAMP、DATE、DATETIME、TIME、YEARです。 それらはすべて独自の特性を持っているため、特定のカレンダータイプを優先する選択は、特定の状況ごとに個別に行う必要があります。 タイムゾーンでの作業など、これらの種類の今日のミニスタディの結果を共有したいと思います。









したがって、すべてのカレンダーデータタイプについては、「10.3。 日付と時刻のタイプ »MySQLマニュアル。 また、タイムゾーンのDBMSサポートに関する重要な情報については、「9.7。 MySQLサーバータイムゾーンサポート 。」 以下はすべて、マニュアルの研究に基づいています。 同時に、このタイプまたはそのタイプを支持する選択のニュアンスのみがここに示されているため、この資料はマニュアルを置き換えるものではなく、補足するものです。



まず、各タイプの簡単な説明:



愛人のメモ 。 興味深いことに、ほとんどのプログラマーは、「タイムスタンプ」の概念がUnixの時間であると信じています。 実際、 タイムスタンプは、特定のイベントが発生した日時を示す一連の文字であるラベルです。 また、「Unix時間」またはPOSIX時間は、UTC 1970年1月1日の午前0時から経過した秒数です。 タイムスタンプの概念は、Unix時間よりも広くなっています。



上記のタイプの説明を分析した後、特定のタイプの長所と短所に関するほぼすべての結論を引き出すことができます。 すべてが非常にシンプルで明白です。



しかし、これらの型の使用について説明する前に、実際には日付と時刻を格納するために異なる型がよく使用されることに注意してください:整数値(日付を格納するため-INT(4バイト)、日付と時刻-BIGINT(8バイト))。 DATEとDATETIMEの整数型を使用する場合の唯一の違いは、出力がフォーマットされないことです。日付と時刻の計算では、整数を対応するカレンダー型に変換する必要があります。 また、保存する前に、提示された値の検証は実行されません。 並べ替えオプションが保存されます。 したがって、移植性とDBMSからの独立性を最大化するために、DATEおよびDATETIMEと同じ場合にINTおよびBIGINTを使用することは理にかなっています。 他の利点があれば、それは見当たりませんが、コメントで示すことをお勧めします。



MySQLで指定されたカレンダータイプを使用する



最も単純なタイプYEARから始めましょう。 唯一の利点は、サイズが小さいことです-1バイトのみです。 ただし、このため、有効な値の範囲には厳密な制限があります(型は255個の異なる値しか格納できません)。 年を厳密に1901から2155の範囲で保存する必要がある場合、実際の状況を想像するのは困難です。さらに、SMALLINT型(2バイト)は、ほとんどの状況で年を保存するのに十分な範囲を与えます。 また、今日、データベーステーブルの行ごとに1バイトを保存することは意味がありません。



DATEおよびDATETIMEタイプは、1つのグループに結合できます。 これらは、サーバーに設定されたタイムゾーンに関係なく、かなり広い範囲の有効な値で日付または日付と時刻を保存します。 それらの使用は間違いなく実用的です。 しかし、私たちの時代の過去の歴史的出来事の日付を保存したい場合は、他の種類のデータを選択する必要があります。 TIMESTAMPタイプの範囲を超えている可能性がある特定のイベント(誕生日、製品のリリース日、大統領選挙、宇宙ロケットの打ち上げなど)の日付を保存するには、これらのタイプが最適です。 これらのタイプを使用する場合、1つの重要なニュアンスを考慮する必要がありますが、それについては以下で詳しく説明します。



TIMEタイプは、精度が1秒未満、および829時間未満の時間間隔が必要とされない期間を格納するために使用できます。 これ以上追加するものはありません。



最も興味深いタイプは残りました-TIMESTAMP 。 DATEおよびDATETIMEと比較して考慮する必要があります。TIMESTAMPは、特定のイベントの発生日時を保存するようにも設計されています。 値の範囲における2つの重要な違い:TIMESTAMPは履歴イベント(誕生日など)の保存には適していないことは明らかですが、最新の状態(ログ、記事の公開日、製品の追加、注文の発行)および予見可能な予定将来のイベント(新しいリリース、カレンダー、スケジューラなど)。



TIMESTAMP型を使用する主な利便性は、テーブル内のこの型の列に対して、レコードを更新するときに現在の時刻を設定するだけでなく、現在の時刻の置換の形式でデフォルト値を設定できることです。 これらの機能が必要な場合、99%の確率で、TIMESTAMPがまさに必要なものです。 (これを行う方法については、マニュアルを参照してください。)



2038年に近づくと、ソフトウェアの動作が停止することを恐れないでください。 第一に、これまであなたのソフトウェアは使用されなくなる可能性が高いでしょう(特に現在作成中のバージョン)。 第二に、この日付に近づくと、MySQL開発者はソフトウェアの動作を維持するための何かを確実に思い付くでしょう。 Y2K問題だけでなく、すべてが解決されます。



そのため、TIMESTAMP型を使用して現在のイベントの日付と時刻を保存し、DATETIMEとDATEを使用して履歴イベントまたは深未来のイベントの日付と時刻を保存します。



値の範囲は、TIMESTAMP、DATETIME、およびDATE型の重要な違いですが、主なものではありません。 主なことは、TIMESTAMPが値をUTCに格納することです。 値を保存するときは、現在のタイムゾーンからUTCに転送され、読み取り時には、UTCから現在のタイムゾーンに転送されます。 DATETIMEとDATEは、タイムゾーンに関係なく、常に同じ時刻を格納および表示します。



タイムゾーン 、MySQL DBMSでグローバルに、または現在の接続に対して 設定されます。 後者は、DBMSレベルで異なるタイムゾーンの異なるユーザーの作業を保証するために使用できます 。 すべての時間値は物理的にUTCで保存され、クライアントから受信され、そのタイムゾーンの値でクライアントに提供されます。 ただし、TIMESTAMPデータ型を使用する場合のみ。 DATEとDATETIMEは常に同じ値を受け入れ、保存し、返します。



NOW()関数とその同義語は、ユーザーの現在のタイムゾーンの時間値を返します。



これらすべての状況を考えると、サーバーへの接続内でタイムゾーンを変更し、DATE型とDATETIME型を使用するときは、非常に注意する必要があります。 日付(生年月日など)を保存する必要がある場合、問題はありません。 生年月日はどのゾーンでも同じです。 つまり 1月1日0:00 UTC / GMT + 0に生まれた場合、これアメリカで12月31日に誕生日が祝われるという意味ではありません 。 ただしイベントの時刻を DATETIME列に格納することにした場合、DBMSレベルでユーザータイムゾーンを使用して作業を構築することは、単に機能しません。 例で説明します。



ユーザーXはUTC / GMT + 2ゾーンで作業し、Y-UTC / GMT + 3ゾーンで作業します。 MySQLとのユーザー接続の場合、対応する(それぞれ独自の)タイムゾーンが設定されます。 ユーザーはフォーラムにメッセージを配置します。メッセージが書かれた日付に興味があります。



オプション1:DATETIME。 ユーザーXは、14:00 UTC / GMT + 2にメッセージを書き込みます。 メッセージの「日付」フィールドの値は、NOW()関数の結果として置き換えられます-14:00。 ユーザーYは、メッセージの書き込み時間を読み取り、同じ14:00を確認します。 しかし、彼は設定にUTC / GMT + 3ゾーンがあり、メッセージはそれだけでなく1時間前に書かれたと考えています。



オプション2:TIMESTAMP。 ユーザーXは、14:00 UTC / GMT + 2にメッセージを書き込みます。 「日付」フィールドには、NOW()関数実行の結果が含まれます-この場合-12:00 UTC / GMT + 0 UserYは、メッセージの書き込み時間を読み取り、(UTC / GMT + 3)(12:00 UTC / GMT + 0)= 15:00 UTC / GMT + 3を受信します。 すべてが私たちの望むとおりになります。 そして最も重要なこととして、それを使用することは非常に便利です。カスタムタイムゾーンをサポートするために時間変換コードを記述する必要はありません。



現在の時刻を置き換えてTIMESTAMP型のタイムゾーンを操作する可能性は非常に強力であるため、特定のログに時間のない日付を保存する必要がある場合は、DATEの代わりにTIMESTAMPを使用する必要があります。 また、「00:00:00」では単に注意を払わないでください。



値の範囲が比較的狭いためにTIMESTAMPを使用できない場合(通常はサイトデータベースの10-15に対して1-2ケース)、DATETIMEを使用し、適切な場所で値を慎重に調整する必要があります(つまり、記録するとき)このフィールドでは、UTCで日付を変換し、読み取り時に-読み取りユーザーのゾーンの時間に)。 日付のみを保存する場合、ほとんどの場合、タイムゾーンは関係ありません。1月1日は現地時間で新年を祝うため、ここで何も翻訳する必要はありません。



All Articles