当前位置: 首页 > 面试题库 >

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

郭俊拔
2023-03-14
问题内容

我本人已经遇到了限制,但是尽管在线上有很多闲聊,但我从未见过关于TIME数据类型的上限和下限 为何
如此的解释。http://dev.mysql.com/doc/refman/5.7/en/time.html上的官方参考资料说

TIME值的范围可能是’-838:59:59’到‘838:59:59’。小时部分可能是如此之大,因为“时间”类型不仅可以用来表示一天中的某个时间(必须少于24小时),而且可以用来表示经过的时间或两个事件之间的时间间隔(可能远大于24小时,甚至是负面的)。

但是我不知道为什么不允许小时数如此之大,而是为什么它会被截断。对于几天而言,这么多小时似乎没有任何意义,或者如果我试图想象可以将整数存储多少秒的可能截止时间,则没有任何意义。那么为什么范围呢?


问题答案:

这些TIME值始终存储在MySQL中的3个字节上。但是格式在5.6.4版本上更改了。我怀疑这不是第一次改变。但是另一种变化(如果有的话)是很久以前发生的,并且没有公开的证据。GitHub上的MySQL源代码历史记录从5.5版开始(最早的提交是在2008年5月),但是我正在寻找的更改发生在2001-2002年左右的某个地方(MySQL
4在2003年发布)

如文档中所述,当前格式使用6位(秒)(可能的值:063),6位(分钟),10位(小时)(可能值:01023),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小时。

MySQL
4上有#11655错误。可以使用嵌套语句返回TIME超出-838..+838范围的值SELECT。它不是一个功能,而是一个错误,并且已得到修复。

将值限制在此范围内并主动更改任何会产生TIME超出其范围的值的代码的唯一原因是向后兼容。

我怀疑MySQL 3使用了一种不同的格式,由于数据打包的方式,将有效值限制在-838..+838小时数范围内。

通过查看当前MySQL的源代码,我发现了一个有趣的公式:

#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + TIME_MAX_SECOND)

让我们暂时忽略了 MAX
上面所用的名称的一部分,让我们只记得TIME_MAX_MINUTETIME_MAX_SECOND是之间的数字0059。该公式仅将小时,分钟和秒连接成一个整数。例如,该值170:29:45变为1702945

此公式引起以下问题:假定将TIME值存储在带符号的3个字节中,用这种方式可以表示的最大正值是多少?

我们要查找的值是0x7FFFFF十进制表示法是8388607。由于最后四位数字(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)

我确信这就是MySQL 3过去在TIME内部保留值的方式。这种格式强加了范围的限制,并且对后续版本的向后兼容性要求将这种限制传播到了我们的时代。



 类似资料:
  • 问题内容: 标题可能有些混乱,所以请允许我解释一下。我正在使用一张桌子记录我的工作日志。每天我都会创建一个条目,说明从什么时间到什么时间工作,并添加一条注释来描述我的工作。 然后,我使用查询来比较时间戳,以准确计算出当天我工作了多少小时和几分钟。此外,我使用查询来计算我全年工作的小时数和分钟数的总和。那就是我遇到问题的地方。我的查询如下。 默认情况下,MySQL TIME字段允许的时间范围为’-8

  • 问题内容: 我正在学习Java 8文档。我知道最大数组大小定义为均值2 ^ 31 – 8 = 2147483639 。然后,我集中讨论了为什么要减去8 或减去? 有些人根据文档给出了一些逻辑。因此,对于标题字,减去8。但是在这种情况下,如果标题字需要大于8,那么答案是什么? 请在此基础上澄清我。预先感谢您的合作。 问题答案: 阅读上述有关Java内存管理的文章,其中清楚指出 我认为这适用于Arra

  • 问题内容: 我刚刚发现,运行日历脚本时,PHP中的时间戳限制为2038。这实际上是什么意思?为什么是2038,而不是2050或2039?如果时间戳仅是从给定日期(1970年)起算的秒数,为什么还要设置限制? 问题答案: 该限制是由大多数C库用来表示该计数的4字节带符号整数强加的。快速数学(假设365天年,并非完全正确): 这也意味着下限约为1900。一些库已经开始引入64位纪元计数,但目前它们之间

  • NowCoder 题目描述 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。 解题思路 // java public ArrayList maxInWindows(int[] num, int size)

  • 我已经在eclipse中安装了以及用于打开IBM format堆转储的插件。 当我试图从eclipse中用打开堆转储时,我得到一个消息框错误,它说: “从'C:\UserData\heapdump.44124802.212242.6876.0003.phd'解析堆转储”过程中出现内部错误。Java堆空间

  • 问题内容: 这是 不是 增加Java的堆的最大尺寸的虚拟机启动后。技术原因是什么?垃圾回收算法是否取决于要使用固定数量的内存?还是出于安全原因,通过消耗所有可用内存来防止Java应用程序从DOS的系统中移至其他应用程序? 问题答案: 最后我知道在Sun的JVM中,必须在连续的地址空间中分配整个堆。我想对于大堆值,很难在启动后将其添加到您的地址空间中,同时又要确保它保持连续。您可能需要在启动时获取它