Поведение mariadb / mysql NOW () и TIMESTAMPDIFF - это дизайн? - PullRequest
2 голосов
/ 03 февраля 2020

Просто перенесите некоторый код из OracleDB в MariaDB и конвертируйте некоторые выражения OracleDB (например, SYSDATE - ? / 1440) в нотацию MariaDB (это, кажется, подходит: NOW() - interval 60 * ? second).

Наткнулся на то, что я подозреваю быть известной ошибкой или документированным поведением (пожалуйста, помогите) при отладке следующего некорректно работающего выражения (в основном сравнивая продолжительность двух исторических «блокировок»)

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

В OracleDB - это выражение работало согласованно / надежно. В MariaDB - это зависит от того, принадлежат ли вычтенные временные метки одной и той же минуте (тогда вычитание дает правильное количество секунд), или если они получены из двух разных минут (тогда результаты вычитания выглядят дополненными / округленными до ближайшей минуты ), что дает нелогичный результат.

Вот небольшая демонстрация (в основном с использованием now() и "20 se c a go"):

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 se c> 20,2 se c" вернет false один раз округляется до 1-с * c точности).

Мой главный вопрос - что-то не так в моей настройке MariaDB? Или это известная ошибка в определенных версиях MariaDB? Или это по замыслу?

Ответы [ 2 ]

2 голосов
/ 03 февраля 2020

Это по замыслу. DATETIME арифметика c в MariaDB / MySQL не выполняет то, что вы ожидаете.

Значение DATETIME, представленное ГГГГ-ММ-ДД ЧЧ: ММ: СС приводится в десятичное число представляется как ГГГГММДДЧЧММСС (и дополняется нулевыми значениями для пропущенных секунд, например).

Пример из 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)

Как вы обнаружили, вы должны использовать функции, указанные c к дате / времени манипуляции для этого вида арифметики c.

0 голосов
/ 03 февраля 2020

Вы выполняли один и тот же запрос дважды подряд, и он возвращал разные результаты для различий временных меток?

У MariaDB есть возможность работать с микросекундами, если вы об этом спрашиваете.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...