TIME
MySQLでは値は常に3バイトに保存されていました。ただし、バージョン5.6で形式が変更されました.4
。それが変わったのはこれが初めてではなかったと思います。しかし、他の変化があったとしても、それはずっと前に起こったものであり、それを示す公的な証拠はありません。 GitHubのMySQLソースコード履歴はバージョン5.5から始まります(最も古いコミットは2008年5月のものです)が、私が探している変更は2001年から2002年頃に発生しました(MySQL 4は2003年にリリースされました)
ドキュメントで説明されているように、現在の形式では6ビットを秒単位で使用します(可能な値:0
63
へ )、分は6ビット、時間は10ビット(可能な値:0
1023
へ )、符号用の1ビット(前述の間隔の負の値を追加)および1ビットは未使用で、「将来の拡張用に予約済み」というラベルが付けられています。
時間コンポーネント(時間、分、秒)の操作用に最適化されており、多くのスペースを浪費しません。この形式を使用すると、-1023:59:59
の間に値を保存できます。 および+1023:59:59
。ただし、MySQLは時間数を838
に制限しています 、おそらくこれが限界だと思うときに、しばらく前に作成されたアプリケーションとの下位互換性のためです。
バージョン5.6.4までは、TIME
値も3バイトに格納され、コンポーネントはdays * 24 * 3600 + hours * 3600 + minutes * 60 + seconds
としてパックされました。 。この形式は、タイムスタンプを操作するために最適化されています(実際にはタイムスタンプであったため)。この形式を使用すると、約-2330
の範囲の値を格納できます。 +2330
へ 時間。この大きな範囲の値を利用できる一方で、MySQLは値を-838
に制限していました。 +838
へ 時間。
バグ#11655
がありました MySQL4ではTIME
を返すことができました -838..+838
以外の値 ネストされたSELECT
を使用した範囲 ステートメント。これは機能ではなくバグであり、修正されました。
値をこの範囲に制限し、TIME
を生成するコードを積極的に変更する唯一の理由 それ以外の値は下位互換性がありました。
MySQL 3は、データのパック方法が原因で、有効な値を-838..+838
の範囲に制限した別の形式を使用したと思われます。 時間。
現在の
#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)
MAX
は今のところ無視しましょう 上記で使用されている名前の一部であり、TIME_MAX_MINUTE
だけを覚えておきましょう。 およびTIME_MAX_SECOND
00
の間の数字です および59
。この数式は、時、分、秒を1つの整数に連結するだけです。たとえば、値170:29:45
1702945
になります 。
この式は次の質問を提起します:TIME
値は符号付きの3バイトに格納されますが、この方法で表すことができる正の最大値はいくつですか?
探している値は0x7FFFFF
です 10進表記の場合は8388607
。最後の4桁以降(8607
)分として読み取る必要があります(86
)と秒(07
)およびそれらの最大有効値は59
、上記の式を使用して符号付きの3バイトに格納できる最大値は、8385959
です。 。これは、TIME
として は+838:59:59
。タダ!
何だと思う? C
のフラグメント 上記のコードはこれから抽出されました:
/* Limits for the TIME data type */
#define TIME_MAX_HOUR 838
#define TIME_MAX_MINUTE 59
#define TIME_MAX_SECOND 59
#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)
これがMySQL3がTIME
を維持するために使用した方法であると確信しています 内部の値。この形式は範囲の制限を課し、後続のバージョンの下位互換性要件は制限を私たちの時代に広めました。