不,没有任何保证。除非您使用ORDER BY 子句指定顺序,否则顺序完全取决于内部实现细节。 IE。任何对 RDBMS 引擎最方便的东西。
实际上,行可能以其原始插入顺序(或更准确地说是行在物理存储中存在的顺序)返回,但您不应依赖此。如果您将应用移植到另一个品牌的 RDBMS,或者即使您升级到可能以不同方式实现存储的更新版本的 MySQL,这些行可能会以其他顺序返回。
后一点适用于任何符合 SQL 的 RDBMS。
下面是我所说的行在存储中存在的顺序与它们被创建的顺序的演示:
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 行以相反的顺序插入到这些空间中,从末尾向后填充。
因此,行的存储顺序并不完全是它们插入的顺序。
更新:我在 2009 年写的这个演示是为 MyISAM 编写的。除非您使用 ORDER BY,否则 InnoDB 按索引顺序返回行。这进一步证明了答案开头的点,即默认顺序取决于实现。使用不同的存储引擎意味着不同的实现。