Предположим, что к базе данных MySQL выдается следующий запрос:
SELECT * FROM table_name;
Обратите внимание, что нет ORDER BY
пункт не дается.
Мой вопрос:
Дает ли MySQL какие-либо гарантии, в каком порядке будут переданы строки набора результатов?
Более конкретно, могу ли я предположить, что строки будут возвращены в порядке вставки?, То есть в том же порядке, в котором строки были вставлены в таблицу.
Нет, никаких гарантий нет. Если вы не укажете порядок, используя предложение ORDER BY
, порядок полностью зависит от внутренних деталей реализации. То есть что наиболее удобно для механизма РСУБД.
На практике строки могут быть возвращены в исходном порядке вставки (или, точнее, в порядке хранения строк в физическом хранилище), но вы не должны зависеть от этого. Если вы переносите приложение на другой бренд СУБД или даже если вы переходите на более новую версию MySQL, которая может реализовать хранилище по-разному, строки могут возвращаться в каком-то другом порядке.
Последняя точка верна для любой SQL-совместимой РСУБД.
Здесь показано, что я имею в виду под порядком, в котором строки хранятся в хранилище, и порядок, который они создали:
CREATE TABLE foo (id SERIAL PRIMARY KEY, bar CHAR(10));
-- create rows with id 1 through 10
INSERT INTO foo (bar) VALUES
('testing'), ('testing'), ('testing'), ('testing'), ('testing'),
('testing'), ('testing'), ('testing'), ('testing'), ('testing');
DELETE FROM foo WHERE id BETWEEN 4 AND 7;
+----+---------+
| id | bar |
+----+---------+
| 1 | testing |
| 2 | testing |
| 3 | testing |
| 8 | testing |
| 9 | testing |
| 10 | testing |
+----+---------+
Итак, теперь у нас есть шесть строк. Хранение в этой точке содержит промежуток между строками 3 и 8, оставшийся после удаления средних рядов. Удаление строк не дефрагментирует эти пробелы.
-- create rows with id 11 through 20
INSERT INTO foo (bar) VALUES
('testing'), ('testing'), ('testing'), ('testing'), ('testing'),
('testing'), ('testing'), ('testing'), ('testing'), ('testing');
SELECT * FROM foo;
+----+---------+
| id | bar |
+----+---------+
| 1 | testing |
| 2 | testing |
| 3 | testing |
| 14 | testing |
| 13 | testing |
| 12 | testing |
| 11 | testing |
| 8 | testing |
| 9 | testing |
| 10 | testing |
| 15 | testing |
| 16 | testing |
| 17 | testing |
| 18 | testing |
| 19 | testing |
| 20 | testing |
+----+---------+
Обратите внимание, что MySQL повторно использовал пробелы, открытые удалением строк, перед добавлением новых строк в конец таблицы. Также обратите внимание, что строки с 11 по 14 были вставлены в эти пространства в обратном порядке, заполняя их с конца назад.
Поэтому порядок, в котором хранятся строки, не соответствует порядку, в который они были вставлены.
Per этот поток, сортировка по умолчанию - это порядок вставки для MyISAM, а первичный ключ - для входа в InnoDB. Но я не думаю, что это гарантия, как она работает.
Нет, вы не можете.
Иногда MySQL выполняет отдельные запросы с ключами, которых вы не ожидаете. Рассмотрим эту таблицу:
CREATE TABLE `user_permissions` (
`permId` int(5) unsigned NOT NULL AUTO_INCREMENT,
`permKey` varchar(16) NOT NULL,
`permDesc` varchar(64) DEFAULT NULL,
PRIMARY KEY (`permId`),
KEY `key_lookup` (`permKey`,`permId`,`permDesc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
MySQL почти всегда будет использовать клавишу key_lookup
для выполнения любой операции выбора в этой таблице; поскольку permKey
- это первое поле, оно обычно заканчивается "сортировкой" по этому ключу (который появляется в алфавитном порядке, но не точно).
Без предложения ORDER BY
MySQL (и большинство/все RDBMS-движки) попытаются получить данные так же, как и сохранены, и как можно быстрее.
Из Извлечение данных с помощью оператора SELECT MySQL: инструкция SELECT
Отображаемые данные не упорядочены. Обычно записи извлекаются в тот же порядок, в который они были вставлены в базу данных
Да, согласно комментарию
Хотя записи обычно извлекаются в том порядке, в котором они вставляются в базу данных, вы не может полагаться на определенный порядок сохраняются. Если ваша база данных резервное копирование и восстановление, или если обслуживание выполняется на база данных MySQL может изменить порядок хранения записей внутри.
Нет, определенно нет. В зависимости от используемого вами механизма базы данных (ISAM или InnoDB) структура таблицы обычно представляет собой какое-то b-дерево, чтобы обеспечить более быструю поиск по строкам. Это не будет иметь ничего общего с порядком вставки и больше зависит от того, как база данных создает индекс на основе первичного ключа (или в случае отсутствия ключа, как хранится куча таблицы).
результаты в mysql 5.6 по умолчанию не выбираются при вставке заказа, вы можете делать обновления и т.д., и он возвращает запрос в любом порядке, который ему нравится.