Предположите, что следующий запрос выпущен к базе данных 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 были вставлены в эти пробелы в обратном порядке, заполняя их с конца таблицы в обратном порядке. Поэтому порядок хранения строк не является точно тем порядком, в который они были вставлены
.Для этого потока , по умолчанию сортировка - порядок вставки для MyISAM, а для InnoDB - возрастание первичного ключа. Но я не думаю, что это гарантия, просто как это известно работает.
Нет, определенно нет. В зависимости от используемого движка базы данных (ISAM или InnoDB), структура таблицы будет в целом представлять собой некое b-дерево для более быстрого поиска по строкам. Это не имеет никакого отношения к порядку вставки, а скорее к тому, как БД строит индекс на основе первичного ключа (или, в случае отсутствия ключа, как хранится куча таблиц)
.Нет, вы не можете.
Иногда 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 (и большинство/все движки СУБД) будут пытаться получить данные точно так же, как они хранятся, и так же быстро, как это возможно.
Из Извлечение данных с помощью оператора MySQL SELECT Statement: оператор SELECT Statement
Отображаемые данные не упорядочены. Обычно записи извлекаются в тот же порядок, в котором они были вставлены в базу данных
Да, согласно комментарию
Хотя записи, как правило, являются восстановленные в том порядке, в котором они вставляются в базу данных, вы не может полагаться на конкретный заказ сохранены. Если ваша база данных скопированный и восстановленный, или если техническое обслуживание осуществляется на база данных, MySQL может изменить порядок хранения записей внутри.