Я тестировал свое приложение (ERP-систему), программируя тестер, который будет выполнять фиксированный сценарий из 30 шагов таких вещей
//pseudo code(PHP)
public function runScenario1Test(){
V2_1Tester::resetDatabase();
V2_1Tester::insert60Companies();
V2_1Tester::insert2000Items();
V2_1Tester::insert100Purchases();
V2_1Tester::insert100Sales();
//do some other stuff
V2_1Tester:checkResults();
}
Хотя каждый раз, когда я запускаю тест того же кода, одни и те же данные, все входы были одинаковыми, иногда я получал разные результаты !!!
Моя голова собиралась взорваться, и после 4 дней исследований, слез и даже плохих снов базы данных ночью, выясняется, что ошибка была в запросе, который иногда приводит к различным результатам. Это что-то вроде этого
+-----+--------------+-----------+------+--------+
| ID | date | direction | col3 | col4 |
+-----+--------------+-----------+------+--------+
| 1 | 2018-03-03 | in | 6 | 100.50 |
| 2 | 2018-03-03 | in | 6 | 350.75 |
+-----+--------------+-----------+------+--------+
-- more ~ 3000 rows
$query = "SELECT * FROM table ORDER BY date, direction, col3";
этот запрос иногда возвращает 1, затем 2 и некоторые другие 2, затем 1.
Я исправил запрос, добавив дополнительный уровень для ID
заказа
$query = "SELECT * FROM table ORDER BY date, direction, col3, ID";
Но я не понимаю, почему MySQL ведет себя так? Иными словами, каковы правила, которые MySQL будет соблюдать для строк, которые одинаковы для всех столбцов заказа? и почему он меняется?
В SQL order by
не является стабильным. Это означает, что, когда ключи одинаковы, заказ может быть в любом порядке.
Это на самом деле очевидно. Таблицы SQL представляют собой неупорядоченные множества. Нет порядка, если столбец не указывает порядок.
Итак, вы сделали правильную вещь, включив id
в качестве последнего ключа. Это гарантирует, что порядок будет хорошо определен, потому что нет дубликатов ключей.