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

Wie Daten standardmäßig in MySql angeordnet werden

In InnoDB , Zeilen werden in der Primärschlüsselreihenfolge gespeichert. Wenn Sie LIMIT verwenden ohne ORDER BY , erhalten Sie immer die Zeilen mit den niedrigsten Primärschlüsselwerten, auch wenn Sie sie in zufälliger Reihenfolge eingefügt haben.

create table foo (id int primary key, x char(1), y int) engine=InnoDB;
insert into foo values (5, 'A', 123);
insert into foo values (9, 'B', 234);
insert into foo values (2, 'C', 345);
insert into foo values (4, 'D', 456);
insert into foo values (1, 'E', 567);
select * from foo;
+----+------+------+
| id | x    | y    |
+----+------+------+
|  1 | E    |  567 |
|  2 | C    |  345 |
|  4 | D    |  456 |
|  5 | A    |  123 |
|  9 | B    |  234 |
+----+------+------+

In MyISAM , Zeilen werden dort gespeichert, wo sie passen. Anfänglich bedeutet dies, dass Zeilen an die Datendatei angehängt werden, aber wenn Sie Zeilen löschen und neue einfügen, werden die Lücken, die durch gelöschte Zeilen hinterlassen wurden, von neuen Zeilen wiederverwendet.

create table bar (id int primary key, x char(1), y int) engine=MyISAM;
insert into bar values (1, 'A', 123);
insert into bar values (2, 'B', 234);
insert into bar values (3, 'C', 345);
insert into bar values (4, 'D', 456);
insert into bar values (5, 'E', 567);
select * from bar;
+----+------+------+
| id | x    | y    |
+----+------+------+
|  1 | A    |  123 |
|  2 | B    |  234 |
|  3 | C    |  345 |
|  4 | D    |  456 |
|  5 | E    |  567 |
+----+------+------+
delete from bar where id between 3 and 4;
insert into bar values (6, 'F', 678);
insert into bar values (7, 'G', 789);
insert into bar values (8, 'H', 890);
select * from bar;
+----+------+------+
| id | x    | y    |
+----+------+------+
|  1 | A    |  123 |
|  2 | B    |  234 |
|  7 | G    |  789 | <-- new row fills gap
|  6 | F    |  678 | <-- new row fills gap
|  5 | E    |  567 |
|  8 | H    |  890 | <-- new row appends at end
+----+------+------+

Ein weiterer Ausnahmefall bei der Verwendung von InnoDB ist, wenn Sie Zeilen aus einem sekundären Index statt aus dem primären Index abrufen. Dies geschieht, wenn Sie den Hinweis "Using index" in der EXPLAIN-Ausgabe sehen.

alter table foo add index (x);
select id, x from foo;
+----+------+
| id | x    |
+----+------+
|  5 | A    |
|  9 | B    |
|  2 | C    |
|  4 | D    |
|  1 | E    |
+----+------+

Wenn Sie komplexere Abfragen mit Joins haben, wird es noch komplizierter, da Sie die Zeilen in der Standardreihenfolge der ersten Tabelle zurückgeben, auf die zugegriffen wird (wobei „first“ davon abhängt, dass der Optimierer die Reihenfolge der Tabellen wählt). Zeilen aus der verknüpften Tabelle hängen von der Reihenfolge der Zeilen aus der vorherigen Tabelle ab.

select straight_join foo.*, bar.* from bar join foo on bar.x=foo.x;
+----+------+------+----+------+------+
| id | x    | y    | id | x    | y    |
+----+------+------+----+------+------+
|  1 | E    |  567 |  5 | E    |  567 |
|  5 | A    |  123 |  1 | A    |  123 |
|  9 | B    |  234 |  2 | B    |  234 |
+----+------+------+----+------+------+

select straight_join foo.*, bar.* from foo join bar on bar.x=foo.x;
+----+------+------+----+------+------+
| id | x    | y    | id | x    | y    |
+----+------+------+----+------+------+
|  5 | A    |  123 |  1 | A    |  123 |
|  9 | B    |  234 |  2 | B    |  234 |
|  1 | E    |  567 |  5 | E    |  567 |
+----+------+------+----+------+------+

Das Fazit ist, dass es am besten ist, explizit zu sein:wenn Sie LIMIT verwenden , geben Sie einen ORDER BY an .