回答

收藏

为什么MySQL最大时限为838:59:59?

技术问答 技术问答 472 人阅读 | 0 人回复 | 2023-09-14

我已经遇到了限制,但是虽然网上聊天很多,但是我从来没有见过关于它的事情TIME数据类型的上下限 为何: x+ \$ O9 n8 u( O4 n( u, s+ `! ^: t
这样的解释。http://dev.mysql.com/doc/refman/5.7/en/time.html官方参考资料说
# _# T2 j8 X4 C5 BTIME值的范围可能是’-838:59:59’到‘838:59:59’。小时可能这么大,因为时间类型不仅可以用来表示一天中的某个时间(必须小于24小时),还可以用来表示两个事件之间的时间间隔(可能远远大于24小时甚至负面)。
' U" B2 n) ]# H$ y3 H) c& s
但我不知道为什么小时数不允许这么大,但为什么它被切断了。对于几天来说,这么多小时似乎毫无意义,或者如果我试图想象整数可以存储多少秒,那就毫无意义了。那么为什么呢?4 W. ], P, C) v4 j8 t
                                                                2 d3 j7 f1 M, c: z
    解决方案:                                                                + U' \2 |) W7 J5 J: Z% n+ Q" X
                                                                这些TIME始终存储值MySQL中间的三个字节。但是格式是5.6.4版本发生了变化。我怀疑这不是第一次改变。但另一个变化(如果有的话)发生在很久以前,没有公开证据。GitHub上的MySQL源代码历史记录从5开始.5版开始(最早的提交是在2008年5月),但是我正在寻找的更改发生在2001-2002年左右的某个地方(MySQL, g6 C/ z' P2 n1 b  |- R* [
4在2003年发布)
. y+ t+ o" O; [# _6 ~+ S$ [, `7 [如文档所述,当前格式为6位(秒)(可能值:0-63)、6位(分钟)、10位(小时)(可能值:0-1023)、1位(符号)(加上现有负值)。提到的间隔)和1位未使用,并标记为保留未来的扩展。' `3 o4 c3 |) p6 z* N: @' O  G' i* k
经过优化,可以处理时间组件(小时、分钟、秒),不会浪费太多空间。可以使用这种格式-1023:59:59和存储值 1023:59:59。MySQL将小时限制为838,可能是为了与前段时间编写的应用程序兼容,但我认为这是极限。, j7 E3 s  p$ F& p( b8 M
在5.6.在4版之前,这些TIME值也存储在三个字节中,组件包装days * 24 * 3600   hours * 3600   minutes* 60  seconds。该格式优化了使用时间戳(因为它实际上是时间戳)。使用此格式,可以存储大约-2330到 2330小时的值。虽然有很多可用值,但是MySQL仍将值限制-838为 838小时。
* b* _+ b0 C% b0 _* e/ QMySQL% X6 I. \& H* l# ]8 r' Y- n! r
4上有#11655错误。您可以使用嵌套句返回TIME超出-838.. 838范围的值SELECT。它不是一个功能,而是一个错误,已经修复。
$ z5 s- _* c* d4 z  M# C将值限制在此范围内并主动更改任何会产生TIME代码超出其范围的唯一原因是向后兼容。
5 @3 W7 M8 a+ [, x2 I$ Z我怀疑MySQL 3采用不同的格式,由于数据包装,有效值限制在-838.. 838小时范围内。5 O/ L' \- r% }* p/ ]
看现在MySQL我发现了一个有趣的公式:
. @0 [* O7 X& {% A0 Q$ r( g#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000   TIME_MAX_MINUTE*100   TIME_MAX_SECOND)让我们暂时忽略 MAX# G" ^5 u2 h; O
我们只记得上面使用的名称的一部分TIME_MAX_MINUTE和TIME_MAX_SECOND是之间的数字00和59。该公式仅将小时、分钟和秒连接成一个整数。例如,该值从170:29:45变为1702945。4 _9 }. Q% ~- e3 j7 h& u
该公式会导致以下问题:假设TIME存储在带有符号的三个字节中的值是多少?+ q, @4 L+ K* l* D4 P' D! [
我们要找的值是0x7FFFFF十进制表示838607。由于最后四位数字(8607)应该读成分钟(86)和秒(07),最大有效值为59,上述公式可以用来存储三个符号字节的最大值为8385959。哪一个?TIME是 838:59:59。-
# o  D8 E! p7 p! ?8 g你猜怎么了?C从上面列出的代码片段中提取:9 ^2 Y2 Q7 r: s
/* 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)我相信这是MySQL 3过去在TIME内部保留值的方式。这种格式强加了范围限制,后续版本的向后兼容性要求将这种限制传播到我们的时代。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则