Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Was ist die MySQL-Zeilenreihenfolge für SELECT * FROM table_name;?

Nein, es gibt keine Garantien. Es sei denn, Sie geben eine Bestellung mit einem ORDER BY an Klausel ist die Reihenfolge vollständig von internen Implementierungsdetails abhängig. Dh was für die RDBMS-Engine am bequemsten ist.

In der Praxis könnten die Zeilen in ihrer ursprünglichen Einfügungsreihenfolge zurückgegeben werden (oder genauer gesagt in der Reihenfolge, in der die Zeilen im physischen Speicher vorhanden sind), aber Sie sollten sich nicht darauf verlassen. Wenn Sie Ihre App auf eine andere RDBMS-Marke portieren oder sogar auf eine neuere Version von MySQL aktualisieren, die den Speicher möglicherweise anders implementiert, können die Zeilen in einer anderen Reihenfolge zurückgegeben werden.

Letzteres gilt für alle SQL-kompatiblen RDBMS.

Hier ist eine Demonstration dessen, was ich mit der Reihenfolge meine, in der die Zeilen im Speicher vorhanden sind, im Vergleich zu der Reihenfolge, in der sie erstellt wurden:

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 |
+----+---------+

Jetzt haben wir also sechs Reihen. Der Speicher an diesem Punkt enthält eine Lücke zwischen den Zeilen 3 und 8, die nach dem Löschen der mittleren Zeilen übrig bleibt. Durch das Löschen von Zeilen werden diese Lücken nicht defragmentiert.

-- 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 |
+----+---------+

Beachten Sie, wie MySQL die durch das Löschen von Zeilen geöffneten Leerzeichen wiederverwendet hat, bevor neue Zeilen an das Ende der Tabelle angehängt wurden. Beachten Sie auch, dass die Zeilen 11 bis 14 in umgekehrter Reihenfolge in diese Leerzeichen eingefügt wurden und von hinten nach hinten gefüllt wurden.

Daher ist die Reihenfolge, in der die Zeilen gespeichert werden, nicht genau die Reihenfolge, in der sie eingefügt wurden.

UPDATE:Diese Demonstration, die ich 2009 geschrieben habe, war für MyISAM. InnoDB gibt Zeilen in Indexreihenfolge zurück, es sei denn, Sie verwenden ORDER BY. Dies ist ein weiterer Beweis für den Punkt am Anfang der Antwort, dass die Standardreihenfolge von der Implementierung abhängt. Die Verwendung einer anderen Speicher-Engine bedeutet eine andere Implementierung.