mariadb/mysql NOW() 和 TIMESTAMPDIFF 行为 - 这是设计使然吗?



只是将一些代码从OracleDB移植到MariaDB中,并将一些OracleDB表达式(如SYSDATE - ? / 1440(转换为MariaDB表示法(这似乎很合适:NOW() - interval 60 * ? second(。

偶然发现了我怀疑是已知错误或记录的行为(请帮助(,同时调试以下行为不端的表达式(基本上比较 2 个历史"锁"的持续时间(

WHERE (a.expirationDt - a.acquisitionDt) > (b.expirationDt - b.acquisitionDt)

在 OracleDB 中 - 此表达式一致/可靠地工作。 在MariaDB中 - 它似乎取决于减去的时间戳是否属于同一分钟(然后减去会产生正确的秒数(,或者这些时间戳是否来自两个不同的分钟(然后减法结果似乎被填充/四舍五入到最接近的分钟(,从而产生违反直觉的结果。

这里有一个小演示(基本上使用now()和"20 秒前"(:

root@localhost> maria "select now(), now() - interval 60 * 1/3 second,  now() - interval 60000000 * 1/3 microsecond, now() - (now() - interval 60 * 1/3 second), now() - (now() - interval 60000000 * 1/3 microsecond), TIMESTAMPDIFF( second,  now() - interval 60 * 1/3 second, now()) from dual"
2020-02-03 13:51:59.0
2020-02-03 13:51:39.0
2020-02-03 13:51:39.0
20.0000
20.000000
20
root@localhost> maria "select now(), now() - interval 60 * 1/3 second,  now() - interval 60000000 * 1/3 microsecond, now() - (now() - interval 60 * 1/3 second), now() - (now() - interval 60000000 * 1/3 microsecond), TIMESTAMPDIFF( second,  now() - interval 60 * 1/3 second, now()) from dual"
2020-02-03 13:52:02.0
2020-02-03 13:51:42.0
2020-02-03 13:51:42.0
60.0000
60.000000
20

我知道TIMESTAMPDIFF看起来不错,可以相应地重写 SQL(只需要确保如何以亚秒精度正确工作,因为"20.4 秒> 20.2 秒"将在四舍五入到 1 秒精度后返回false(。

我的主要问题 - 我的 MariaDB 设置有问题吗?还是特定MariaDB版本中的已知错误?还是设计使然?

这是设计使然。 MariaDB/MySQL 中的 DATETIME 算术不会达到您的预期。

表示 YYYY-MM-DD HH:MM:SS 的 DATETIME 值被强制转换为表示为 YYYYMMDDHHMMSS 的十进制数(例如,用零值填充缺失秒数(。

MySQL的一个例子:

mysql> SELECT CAST('2020-02-02 00:01' AS DATETIME) - CAST('2020-02-02 00:00:01' AS DATETIME),
-> 20200202000100 - 20200202000001 G
*************************** 1. row ***************************
CAST('2020-02-02 00:01' AS DATETIME) - CAST('2020-02-02 00:00:01' AS DATETIME): 99
20200202000100 - 20200202000001: 99
1 row in set (0.00 sec)

正如您所发现的,您必须使用特定于日期/时间操作的函数来进行此类算术。

您是否连续两次运行相同的查询,并返回时间戳差异的不同结果?

MariaDB 确实有一条处理微秒的途径,如果这是你要问的。

https://mariadb.com/kb/en/microseconds-in-mariadb/

最新更新