sql >> データベース >  >> RDS >> Mysql

PHPとmySQL:2038年バグ:それは何ですか?それを解決する方法は?

    これをコミュニティウィキとしてマークしたので、自由に編集してください。

    2038年問題とは正確には何ですか?

    「2038年問題(Y2K問題と同様にUnix Millennium Bug、Y2K38とも呼ばれます)により、一部のコンピュータソフトウェアが2038年以前または2038年に故障する可能性があります。この問題は、システム時間を署名付き32として保存するすべてのソフトウェアとシステムに影響します。 -ビット整数であり、この数値を1970年1月1日の00:00:00UTCからの秒数として解釈します。"

    なぜ発生するのですか、発生するとどうなりますか?

    2038年1月19日火曜日の03:14:07UTCを超える時間 「ラップアラウンド」され、負の数として内部に格納されます。これらのシステムは、2038年ではなく1901年12月13日の時間として解釈します。これは、UNIXエポック(1月1日)からの秒数によるものです。 1970 00:00:00 GMT)は、32ビットの符号付き整数に対するコンピューターの最大値を超えています。

    どうすれば解決できますか?

    • 長いデータ型を使用します(64ビットで十分です)
    • MySQL(またはMariaDB)の場合、時間情報が必要ない場合は、DATEの使用を検討してください。 列タイプ。より高い精度が必要な場合は、DATETIMEを使用してください TIMESTAMPではなく 。 DATETIMEに注意してください 列にはタイムゾーンに関する情報が格納されないため、アプリケーションはどのタイムゾーンが使用されたかを知る必要があります。
    • ウィキペディアに記載されているその他の可能な解決策
    • MySQL開発者がこのバグを修正するのを待ちます 10年以上前に報告されました。

    同様の問題を引き起こさない、それを使用するための可能な代替案はありますか?

    可能な限り、データベースに日付を格納するために大きな型を使用してみてください。64ビットで十分です。GNUCおよびPOSIX / SuSの長い長い型、またはsprintf('%u'...) PHPまたはBCmath拡張機能で。

    まだ2038年になっていないのに、潜在的に壊れる可能性のあるユースケースは何ですか?

    つまり、MySQL DATETIME 範囲は1000〜9999ですが、TIMESTAMPの範囲は1970〜2038のみです。システムに生年月日、将来の将来の日付(30年の住宅ローンなど)などが保存されている場合は、すでにこのバグが発生しています。繰り返しになりますが、これが問題になる場合はTIMESTAMPを使用しないでください。

    実際に発生した場合に、いわゆる問題を回避するために、TIMESTAMPを使用する既存のアプリケーションに何ができるでしょうか。

    Webはまだレガシープラットフォームではないため、予測するのは難しいですが、2038年にはまだPHPアプリケーションはほとんどありません。

    TIMESTAMPを変換するようにデータベーステーブルの列を変更するプロセスは次のとおりです。 DATETIMEへ 。一時的な列を作成することから始まります:

    # rename the old TIMESTAMP field
    ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;
    
    # create a new DATETIME column of the same name as your old column
    ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;
    
    # update all rows by populating your new DATETIME field
    UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);
    
    # remove the temporary column
    ALTER TABLE `myTable` DROP `temp_myTimestamp`
    

    リソース



    1. MySQL TRUNCATE()関数–数値を指定された小数点以下の桁数に切り捨てます

    2. Oracleの互換性レベルを確認する2つの方法(SQLclおよびSQL * Plus)

    3. データストレージ:アーカイブおよびHSMのRESTとPOSIX

    4. SQL Serverで特定の文字のUnicode値を返す方法– UNICODE()