那么让我们回到MySQL。这样一个有趣的范围背后的原因是什么?MySQL内部手册说,Time类型的存储在版本5.6.4中有所更改,在此版本中获得了对小数秒的支持。对于非小数类型,它使用3个字节。现在,如果他们仅仅使用这3个字节来编码若干秒,他们将能够支持跨越2330小时的间隔,这与当前最多838小时相比已经是相当大的改进,即使在将时间跨度映射到时间跨度方面仍然有点无用。
这意味着它们的编码一定是在浪费位,可能是为了更容易使用…。不确定具体在什么情况下,但如果您的数据库管理系统(和/或您对用户将如何处理它的概念)只是喜欢字符串,并且您确实想要加速hh:mm:ss表示,则可能更有意义。所以,请看:
1位符号(1=非负,0=负) 1位未使用(为将来的扩展保留) 10位小时(0-838) 6位分钟(0-59) 6位秒(0-59) 24位=3字节。
这就解释了一切,对吧?嗯,仔细看看。每小时10位…。范围从0到838。我亲切地提醒您,210是1024,不是838。情节变得复杂起来。当然,我不是第一个对此感到疑惑的人,StackOverflow之前也问过这个问题。这个问题中被接受的答案解释了一切,但几乎没有,因为它最初认为奇怪的选择838是“与不久前编写的应用程序的向后兼容性”,直到后来才解释说,这个选择与与mysql版本…的兼容性有关。3,你知道,从Windows98还是一个新的操作系统,Linux还不到10岁的时候开始。
在MySQL3中,时间类型也使用了3个字节,但它们的用法不同。其中一位也用于符号,但剩下的23位是这样产生的整数值:小时×10000+分钟×100秒;换句话说,数字的两个最低有效小数位包含秒,接下来的两位包含分钟,其余的包含小时。223为83888608,即838:86:08,因此,此格式的最大有效时间为838:59:59。这种格式甚至比当前的格式更不易用,除了字符串格式化和解析之外,它基本上需要乘法和除法才能做任何事情-这再次表明MySQL过于重视字符串IO,而不是具有便于内部操作和非基于字符串的协议的类型。
MySQL开发人员有足够的机会修复这种类型,或者至少引入一种没有这种缩减范围的替代类型。到目前为止,他们从MySQL3两次更改了这种类型,但每次都决定保留范围,据说是出于兼容性原因。我很难想象增加类型的值范围会破坏与应用程序的兼容性的情况-MySQL中的类型是否定义了溢出行为?是否有任何理智的人在编写应用程序时依赖数据库类型的固有限制来进行验证?如果是,谁会看到这个尴尬的838小时范围,并认为这是一个适当的限制,可以不加更改地将其带入他们的应用程序的数据模型中呢?在这一点上,我甚至不想知道。
尽管在MySQL的整个生命周期中更改了两次,时间类型仍然是一个相当笨拙和有限的类型。在我看来,未使用的、“预留给未来扩展”的部分才是这里真正的阻力所在。这里希望有一天它将被用来表示“遗留”时间值,到那时,mysql和/或mariadb将支持像postgresql的Interval这样的合适类型,它的范围是+/-178000000年,精度非常合理。