Inhaltsverzeichnis
CREATE
, DROP
,
ALTER
SELECT
, INSERT
,
UPDATE
, DELETE
Dieses Kapitel beschreibt die Syntax für die meisten von MySQL unterstützten SQL-Anweisungen. Weitere Beschreibungen zu Anweisungen finden Sie in den folgenden Kapiteln:
Kapitel 7, Optimierung, beschreibt die
EXPLAIN
-Anweisung.
Kapitel 19, Gespeicherte Prozeduren und Funktionen, behandelt Anweisungen zum Schreiben gespeicherter Routinen.
Kapitel 20, Trigger, behandelt Anweisungen zum Schreiben von Triggern.
Kapitel 21, Views, behandelt View-spezifische Anweisungen.
ALTER {DATABASE | SCHEMA} [db_name
]alter_specification
[,alter_specification
] ...alter_specification
: [DEFAULT] CHARACTER SETcharset_name
| [DEFAULT] COLLATEcollation_name
Mit ALTER DATABASE
können Sie die
grundlegenden Eigenschaften einer Datenbank ändern. Diese
Eigenschaften sind in der Datei db.opt
im
Datenbankverzeichnis gespeichert. Um ALTER
DATABASE
verwenden zu können, benötigen Sie die
Berechtigung ALTER
für die Datenbank.
ALTER SCHEMA
ist ein Synonym für
ALTER DATABASE
.
Die Klausel CHARACTER SET
ändert den
Standardzeichensatz der Datenbank. Die Klausel
COLLATE
ändert die Standardsortierfolge der
Datenbank. Kapitel 10, Zeichensatz-Unterstützung, behandelt Namen von
Zeichensätzen und Sortierfolgen.
Der Datenbankname kann weggelassen werden. In diesem Fall bezieht sich die Anweisung auf die Standarddatenbank.
ALTER [IGNORE] TABLEtbl_name
alter_specification
[,alter_specification
] ...alter_specification
: ADD [COLUMN]column_definition
[FIRST | AFTERcol_name
] | ADD [COLUMN] (column_definition
,...) | ADD INDEX [index_name
] [index_type
] (index_col_name
,...) | ADD [CONSTRAINT [symbol
]] PRIMARY KEY [index_type
] (index_col_name
,...) | ADD [CONSTRAINT [symbol
]] UNIQUE [INDEX] [index_name
] [index_type
] (index_col_name
,...) | ADD FULLTEXT [INDEX] [index_name
] (index_col_name
,...) [WITH PARSERparser_name
] | ADD SPATIAL [INDEX] [index_name
] (index_col_name
,...) | ADD [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
,...) [reference_definition
] | ALTER [COLUMN]col_name
{SET DEFAULTliteral
| DROP DEFAULT} | CHANGE [COLUMN]old_col_name
column_definition
[FIRST|AFTERcol_name
] | MODIFY [COLUMN]column_definition
[FIRST | AFTERcol_name
] | DROP [COLUMN]col_name
| DROP PRIMARY KEY | DROP INDEXindex_name
| DROP FOREIGN KEYfk_symbol
| DISABLE KEYS | ENABLE KEYS | RENAME [TO]new_tbl_name
| ORDER BYcol_name
| CONVERT TO CHARACTER SETcharset_name
[COLLATEcollation_name
] | [DEFAULT] CHARACTER SETcharset_name
[COLLATEcollation_name
] | DISCARD TABLESPACE | IMPORT TABLESPACE |table_options
|partition_options
| ADD PARTITIONpartition_definition
| DROP PARTITIONpartition_names
| COALESCE PARTITIONnumber
| REORGANIZE PARTITIONpartition_names
INTO (partition_definitions
) | ANALYZE PARTITIONpartition_names
| CHECK PARTITIONpartition_names
| OPTIMIZE PARTITIONpartition_names
| REBUILD PARTITIONpartition_names
| REPAIR PARTITIONpartition_names
ALTER TABLE
ermöglicht Ihnen das Ändern der
Struktur einer vorhandenen Tabelle. Sie können beispielsweise
Spalten hinzufügen oder entfernen, Indizes erstellen oder
löschen, den Typ einer vorhandenen Spalte ändern oder Spalten
oder die Tabelle umbenennen. Ferner können Sie den Kommentar
für die Tabelle und auch den Tabellentyp modifizieren.
Die Syntax für viele der zulässigen Änderungen ähnelt
Klauseln der CREATE TABLE
-Anweisung. Hierzu
gehören table_options
-Modifikationen
für Optionen wie ENGINE
,
AUTO_INCREMENT
und
AVG_ROW_LENGTH
. (Allerdings ignoriert
ALTER TABLE
die Tabellenoptionen
DATA DIRECTORY
und INDEX
DIRECTORY
.) Abschnitt 13.1.5, „CREATE TABLE
“, listet
alle Tabellenoptionen auf.
Bei manchen Operationen kann eine Warnung erzeugt werden, wenn
diese auf eine Tabelle angewendet werden sollen, deren
Speicher-Engine die Operation nicht unterstützt. Diese
Warnungen lassen sich mit SHOW WARNINGS
anzeigen. Siehe auch Abschnitt 13.5.4.25, „SHOW WARNINGS
“.
ALTER TABLE
erstellt zunächst eine
temporäre Kopie der Ursprungstabelle. Die Änderung wird dann
an der Kopie vorgenommen, und schließlich wird die
Originaltabelle gelöscht und die Kopie entsprechend umbenannt.
Während der Ausführung von ALTER TABLE
kann
die Originaltabelle von anderen Clients gelesen werden.
Änderungs- und Schreiboperationen in der Tabelle werden
blockiert, bis die neue Tabelle bereit ist, und dann automatisch
in die neue Tabelle umgeleitet. Aktualisierungen schlagen nicht
fehl.
Beachten Sie, dass, wenn Sie eine andere ALTER
TABLE
-Option als RENAME
verwenden,
MySQL immer eine Temporärtabelle erstellt – und zwar auch
dann, wenn die Daten strenggenommen nicht kopiert werden
müssten (z. B. wenn Sie nur den Namen einer Spalte ändern).
Bei MyISAM
-Tabellen ist die Neuerstellung des
Indexes der zeitaufwändigste Teil des Änderungsvorgangs. Sie
können diesen beschleunigen, indem Sie die Systemvariable
myisam_sort_buffer_size
auf einen hohen Wert
setzen.
Um ALTER TABLE
zu verwenden, benötigen
Sie die Berechtigungen ALTER
,
INSERT
und CREATE
für
die Tabelle.
IGNORE
ist eine MySQL-Erweiterung zum
SQL-Standard. Sie steuert, wie ALTER
TABLE
funktioniert, wenn Dubletten eindeutiger
Schlüssel in der neuen Tabelle vorhanden sind oder (bei
aktiviertem striktem Modus) Warnungen auftreten. Wenn
IGNORE
nicht angegeben ist, wird der
Vorgang bei Auftreten von Schlüsseldubletten abgebrochen,
und ein Rollback wird durchgeführt. Ist
IGNORE
angegeben, dann wird nur der erste
von mehreren Datensätzen mit Dubletten eindeutiger
Schlüssel verwendet. Die übrigen betroffenen Datensätze
werden gelöscht. Falsche Werte werden auf den
nächstliegenden zulässigen Wert gesetzt.
Sie können mehrere ADD
-,
ALTER
-, DROP
- und
CHANGE
-Klauseln in einer ALTER
TABLE
-Anweisung angeben. Diese werden durch
Kommata getrennt. Dies ist eine MySQL-Erweiterung zum
SQL-Standard, der nur jeweils eine dieser Klauseln je
ALTER TABLE
-Anweisung zulässt. Um
beispielsweise mehrere Spalten mit einer einzelnen Anweisung
zu löschen, tun Sie Folgendes:
ALTER TABLE t2 DROP COLUMN c, DROP COLUMN d;
CHANGE
, col_name
DROP
und
col_name
DROP INDEX
sind MySQL-Erweiterungen zum
SQL-Standard.
MODIFY
ist eine Oracle-Erweiterung zu
ALTER TABLE
.
Das Wort COLUMN
ist optional und darf
weggelassen werden.
Wenn Sie ALTER TABLE
ohne
zusätzliche Optionen sehen, benennt MySQL alle Dateien, die
der Tabelle tbl_name
RENAME TO
new_tbl_name
tbl_name
entsprechen,
einfach um. Es ist nicht notwendig, eine Temporärtabelle zu
erstellen. (Sie können zum Umbenennen von Tabellen auch die
Anweisung RENAME TABLE
verwenden. Siehe
auch Abschnitt 13.1.9, „RENAME TABLE
“.)
column_definition
-Klauseln
verwenden dieselbe Syntax für ADD
und
CHANGE
wie bei CREATE
TABLE
. Beachten Sie, dass diese Syntax den
Spaltennamen (und nicht nur den Datentyp) enthält. Siehe
auch Abschnitt 13.1.5, „CREATE TABLE
“.
Sie können eine Spalte mithilfe einer CHANGE
-Klausel
umbenennen. Zu diesem Zweck geben Sie den alten und den
neuen Spaltennamen sowie den Typ an, den die Spalte zurzeit
hat. Um beispielsweise eine
old_col_name
column_definition
INTEGER
-Spalte von a
zu b
umzubenennen, geben Sie Folgendes
ein:
ALTER TABLE t1 CHANGE a b INTEGER;
Wenn Sie den Typ einer Spalte, nicht aber ihren Namen
ändern wollen, erfordert die
CHANGE
-Syntax trotzdem einen alten und
neuen Spaltennamen, auch wenn diese dann identisch sind. Zum
Beispiel:
ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
Sie können den Spaltentyp auch mit
MODIFY
ändern, ohne die Spalte
umzubenennen:
ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
Wenn Sie CHANGE
oder
MODIFY
zum Kürzen einer Spalte
verwenden, für die ein Index vorhanden ist, und die Länge
der Spalte nach der Operation geringer ist als die
Indexlänge, dann kürzt MySQL den Index automatisch.
Ändern Sie einen Datentyp mit CHANGE
oder MODIFY
, dann versucht MySQL,
vorhandene Spaltenwerte bestmöglich in den neuen Typ zu
konvertieren.
Um eine Spalte an eine bestimmte Position in einer
Tabellenzeile hinzuzufügen, verwenden Sie
FIRST
oder AFTER
.
Standardmäßig werden neue Spalten am Ende eingefügt. Sie
können col_name
FIRST
und
AFTER
auch bei CHANGE
-
oder MODIFY
-Operationen verwenden.
ALTER ... SET DEFAULT
oder ALTER
... DROP DEFAULT
geben einen neuen Vorgabewert
für eine Spalte an bzw. entfernen den vorhandenen
Vorgabewert. Wenn die alte Vorgabe entfernt wird und die
Spalte NULL
werden kann, dann wird
NULL
zum neuen Vorgabewert. Kann die
Spalte nicht NULL
werden, dann weist
MySQL einen Standardwert zu (siehe auch
Abschnitt 11.1.4, „Vorgabewerte von Datentypen“).
DROP INDEX
entfernt einen Index. Dies ist
eine MySQL-Erweiterung zum SQL-Standard. Siehe auch
Abschnitt 13.1.7, „DROP INDEX
“.
Wenn Spalten aus einer Tabelle entfernt werden, werden die Spalten auch aus allen Indizes gelöscht, deren Bestandteil sie sind. Wenn alle Spalten, die einen Index bilden, gelöscht wurden, dann wird auch der Index gelöscht.
Enthält eine Tabelle nur eine Spalte, dann kann diese nicht
gelöscht werden. Zur Entfernung der Tabelle verwenden Sie
stattdessen DROP TABLE
.
DROP PRIMARY KEY
löscht den
Primärschlüssel. Hinweis: Bei
älteren MySQL-Versionen löscht DROP PRIMARY
KEY
, wenn kein Primärindex vorhanden ist, den
ersten eindeutigen Index in der Tabelle. Dies trifft bei
MySQL 5.1 nicht mehr zu: Wenn Sie hier
DROP PRIMARY KEY
auf eine Tabelle ohne
Primärschlüssel anzuwenden versuchen, erhalten Sie einen
Fehler.
Wenn Sie einer Tabelle mit UNIQUE INDEX
oder PRIMARY KEY
einen eindeutigen Index
bzw. einen Primärschlüssel hinzufügen, wird dieser vor
jedem nichteindeutigen Index gespeichert, sodass MySQL
Schlüsseldubletten schnellstmöglich erkennt.
ORDER BY
erlaubt Ihnen die Erstellung
einer neuen Tabelle mit allen Datensätzen in einer
bestimmten Reihenfolge. Beachten Sie, dass diese Reihenfolge
nach Einfüge- und Löschoperationen nicht aufrechterhalten
wird. Diese Option ist in erster Linie nützlich, wenn Sie
wissen, dass die Datensätze meistens in einer bestimmten
Reihenfolge abgefragt werden. Wenn Sie diese Option nach
umfangreicheren Änderungen in der Tabelle verwenden,
können Sie die Leistung unter Umständen steigern. In
bestimmten Fällen kann es MySQL das Sortieren erleichtern,
wenn die Tabelle in der Reihenfolge der Spalte angeordnet
ist, nach der Sie sie später auch sortieren wollen.
Wenn Sie ALTER TABLE
auf eine
MyISAM
-Tabelle anwenden, werden alle
nichteindeutigen Indizes in einer separaten Stapeloperation
erstellt (wie bei REPAIR TABLE
). Dies
sollte ALTER TABLE
erheblich
beschleunigen, wenn Sie viele Indizes haben.
Die Funktion lässt sich explizit aktivieren. ALTER
TABLE ... DISABLE KEYS
weist MySQL an, die
Aktualisierung nichteindeutiger Indizes für eine
MyISAM
-Tabelle zu beenden. Danach sollte
ALTER TABLE ... ENABLE KEYS
verwendet
werden, um die fehlenden Indizes neu zu erstellen. MySQL tut
dies mit einem speziellen Algorithmus, der wesentlich
schneller ist als das aufeinander folgende Einfügen von
Schlüsseln. Insofern sollte die Deaktivierung von
Schlüsseln vor umfangreichen Einfügeoperationen diese
erheblich beschleunigen. Die Verwendung von ALTER
TABLE ... DISABLE KEYS
erfordert neben den bereits
genannten Berechtigungen auch die Berechtigung
INDEX
.
Die Klauseln FOREIGN KEY
und
REFERENCES
werden von der
InnoDB
-Speicher-Engine unterstützt, die
ADD [CONSTRAINT
[
implementiert. Siehe auch
Abschnitt 14.2.6.4, „Fremdschlüssel-Beschränkungen“. Von
anderen Speicher-Engines werden die Klauseln zwar erkannt,
aber ignoriert. Zudem wird die Klausel
symbol
]] FOREIGN KEY (...)
REFERENCES ... (...)CHECK
von allen Speicher-Engines erkannt,
aber ignoriert. Siehe auch Abschnitt 13.1.5, „CREATE TABLE
“.
Diese Verhaltensweise – das Erkennen und nachfolgende
Ignorieren von Syntaxklauseln – ist aus
Kompatibilitätsgründen vorhanden. Sie erleichtert die
Portierung von Codes anderer SQL-Server und die Ausführung
von Anwendungen, die Tabellen mit Referenzen erstellen.
Siehe auch Abschnitt 1.9.5, „MySQL: Unterschiede im Vergleich zu ANSI SQL92“.
In separaten Klauseln derselben ALTER
TABLE
-Anweisung können Sie keinen Fremdschlüssel
hinzufügen und einen Fremdschlüssel löschen. Sie müssen
hierzu separate Anweisungen verwenden.
InnoDB
unterstützt die Verwendung von
ALTER TABLE
zum Löschen von
Fremdschlüsseln:
ALTER TABLEtbl_name
DROP FOREIGN KEYfk_symbol
;
In separaten Klauseln derselben ALTER
TABLE
-Anweisung können Sie keinen Fremdschlüssel
hinzufügen und einen Fremdschlüssel löschen. Sie müssen
hierzu separate Anweisungen verwenden.
Weitere Informationen finden Sie unter Abschnitt 14.2.6.4, „Fremdschlüssel-Beschränkungen“.
Wenn Sie den Standardzeichensatz einer Tabelle und den
Zeichensatz aller Zeichenspalten (CHAR
,
VARCHAR
, TEXT
) auf
einen neuen Zeichensatz umstellen wollen, verwenden Sie eine
Anweisung wie die folgende:
ALTER TABLEtbl_name
CONVERT TO CHARACTER SETcharset_name
;
Warnung: Die obige
Operation wandelt Spaltenwerte zwischen Zeichensätzen um.
Sie sollten dies keinesfalls tun, wenn
Sie eine Spalte in einem Zeichensatz (z. B.
latin1
) haben, die gespeicherten Werte
aber eigentlich einen anderen inkompatiblen Zeichensatz (wie
utf8
) verwenden. In diesem Fall müssen
Sie bei solchen Spalten Folgendes tun:
ALTER TABLE t1 CHANGE c1 c1 BLOB; ALTER TABLE t1 CHANGE c1 c1 TEXT CHARACTER SET utf8;
Der Grund, warum dies funktioniert, ist, dass, wenn Sie von
oder in BLOB
-Spalten konvertieren, keine
Konvertierung stattfindet.
Wenn Sie CONVERT TO CHARACTER SET binary
angeben, werden die CHAR
-,
VARCHAR
- und
TEXT
-Spalten in ihre entsprechenden
binären String-Typen umgewandelt
(BINARY
, VARBINARY
,
BLOB
). Das bedeutet, dass die Spalten
keinen Zeichensatz mehr haben; eine nachfolgende
CONVERT TO
-Operation hat also keine
Auswirkungen mehr.
Um nur den Standardzeichensatz einer Tabelle zu ändern, verwenden Sie folgende Anweisung:
ALTER TABLEtbl_name
DEFAULT CHARACTER SETcharset_name
;
Das Wort DEFAULT
ist optional. Der
Standardzeichensatz ist der Zeichensatz, der verwendet wird,
wenn Sie den Zeichensatz für eine neue Spalte, die Sie
(etwa mit ALTER TABLE ... ADD column
) zu
einer Tabelle hinzufügen, nicht explizit angegeben haben.
Bei einer InnoDB
-Tabelle, die mit einem
eigenen Tablespace in einer .ibd
-Datei
erstellt wurde, kann diese Datei verworfen und importiert
werden. Mit folgender Anweisung können Sie die
.ibd
-Datei verwerfen:
ALTER TABLE tbl_name
DISCARD TABLESPACE;
Hierbei wird die aktuelle .ibd
-Datei
gelöscht, d. h., Sie sollten zuerst ein Backup erstellt
haben. Der Versuch des Zugriffs auf die Tabelle, während
die Tablespace-Datei verworfen wird, führt zu einem Fehler.
Um die .ibd
-Sicherungsdatei in die
Tabelle zurückzuimportieren, kopieren Sie sie ins
Datenbankverzeichnis und setzen dann folgende Anweisung ab:
ALTER TABLE tbl_name
IMPORT TABLESPACE;
Siehe auch Abschnitt 14.2.3.1, „Verwendung von Tabellen-Tablespaces (ein Tablespace pro Tabelle)“.
ALTER TABLE
kann auch bei partitionierten
Tabellen verwendet werden, um Partitionen hinzuzufügen, zu
löschen, zu verbinden oder aufzutrennen. Auch die
Partitionierungswartung ist hiermit möglich.
Die einfache Angabe einer
partition_options
-Klausel zu
ALTER TABLE
für eine partitionierte
Tabelle partitioniert diese entsprechend dem
Partitionierungsschema neu, welches über die
partition_options
angegeben
wurde. Diese Klausel beginnt immer mit PARTITION
BY
und verwendet ansonsten dieselbe Syntax und die
Regeln, die auch auf die
partition_options
-Klausel für
CREATE TABLE
zutreffen. (Weitere
Informationen finden Sie in Abschnitt 13.1.5, „CREATE TABLE
“).
Hinweis: Diese Syntax wird
derzeit vom MySQL 5.1 Server akzeptiert, tut aber eigentlich
noch gar nichts. Wir erwarten die Implementierung im Zuge
der Fortentwicklung von MySQL 5.1.
Die partition_definition
-Klausel
für ALTER TABLE ADD PARTITION
unterstützt dieselben Optionen wie die gleichnamige Klausel
für die CREATE TABLE
-Anweisung.
(Informationen zu Syntax und eine Beschreibung finden Sie in
Abschnitt 13.1.5, „CREATE TABLE
“.) Angenommen, Sie haben wie
folgt eine partitionierte Tabelle erstellt:
CREATE TABLE t1 ( id INT, year_col INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999) );
Sie können dieser Tabelle nun wie folgt eine neue Partition
p3
hinzufügen, die Werte aufnehmen kann,
die kleiner als 2002
sind.
ALTER TABLE t1 ADD PARTITION p3 VALUES LESS THAN (2002);
Hinweis: Sie können
ALTER TABLE
nicht zum Hinzufügen von
Partitionen zu einer Tabelle verwenden, die (noch) nicht
partitioniert ist.
Mit DROP PARTITION
können Sie eine oder
mehrere RANGE
- oder
LIST
-Partitionen löschen. Diese
Anweisung kann nicht für HASH
- oder
KEY
-Partitionen verwendet werden; dort
benutzen Sie stattdessen COALESCE
PARTITION
(siehe unten). In gelöschten
Partitionen vorhandene Daten, die in der Liste
partition_names
aufgeführt sind,
werden verworfen. So können Sie beispielsweise in der zuvor
definierten Tabelle t1
die Partitionen
p0
und p1
wie folgt
löschen:
ALTER TABLE DROP PARTITION p0, p1;
Beachten Sie, dass DROP PARTITION
nicht
bei Tabellen funktioniert, die die NDB
Cluster
-Speicher-Engine verwenden. Siehe auch
Abschnitt 17.3.1, „Verwaltung von RANGE
- und
LIST
-Partitionen“, und
Abschnitt 16.8, „Bekannte Beschränkungen von MySQL Cluster“.
ADD PARTITION
und DROP
PARTITION
unterstützen IF [NOT]
EXISTS
derzeit nicht. Ferner ist es nicht
möglich, eine Partition oder eine partitionierte Tabelle
umzubenennen. Stattdessen müssen Sie, wenn Sie eine
Partition umbenennen wollen, diese löschen und neu
erstellen. Wollen Sie eine partitionierte Tabelle
umbenennen, dann müssen Sie zunächst alle Partitionen
löschen, die Tabelle dann umbenennen und schließlich alle
gelöschten Partitionen neu erstellen.
COALESCE PARTITION
kann bei Tabellen
benutzt werden, die mit HASH
oder
KEY
partitioniert wurden, um die Anzahl
der Partitionen um den Wert
number
zu verringern. Angenommen,
Sie haben die Tabelle t2
mit der
folgenden Definition erstellt:
CREATE TABLE t2 ( name VARCHAR (30), started DATE ) PARTITION BY HASH(YEAR(started)) PARTITIONS (6);
Sie können die Anzahl der von t2
verwendeten Partitionen nun mit der folgenden Anweisung von
6 auf 4 verringern:
ALTER TABLE t2 COALESCE PARTITION 2;
Die in den letzten number
Partitionen enthaltenen Daten werden in die verbleibenden
Partitionen eingefügt. In diesem Fall werden die
Partitionen 4 und 5 in die ersten vier Partitionen (0 bis 3)
eingefügt.
Um einige, aber nicht alle Partitionen zu ändern, die von
einer partitionierten Tabelle verwendet werden, können Sie
REORGANIZE PARTITION
verwenden. Diese
Anweisung kann auf mehrere Arten verwendet werden:
Um mehrere Partitionen zu einer zusammenzufassen. Hierzu
zählen Sie mehrere Partitionen in der
partition_names
-Liste auf und
geben genau eine Definition für
partition_definition
an.
Um eine vorhandene Partition in mehrere Partitionen
aufzuspalten. Hierzu benennen Sie genau eine Partition
für partition_names
und
geben in
partition_definitions
mehrere
Definitionen an.
Um die Bereiche für eine Teilmenge der Partitionen, die
mit VALUES LESS THAN
definiert wird,
oder die Wertelisten für eine Teilmenge der Partitionen
zu ändern, die mit VALUES IN
definiert wird.
Hinweis: Bei Partitionen,
die nicht explizit aufgeführt wurden, verwendet MySQL
automatisch die Standardnamen p0
,
p1
, p2
usw.
Weitere Informationen zu ALTER TABLE ... REORGANIZE
PARTITION
-Anweisungen und zugehörige Beispiele
finden Sie in Abschnitt 17.3, „Partitionsverwaltung“.
Mehrere zusätzliche Klauseln ermöglichen die Wartung und
Reparatur von Partitionen analog zu der Art und Weise, wie
diese Funktionalitäten bei nicht partitionierten Tabellen
durch Anweisungen wie CHECK TABLE
und
REPAIR TABLE
(welche von partitionierten
Tabellen nicht unterstützt werden)
implementiert sind. Hierzu gehören ANALYZE
PARTITION
, CHECK PARTITION
,
OPTIMIZE PARTITION
, REBUILD
PARTITION
und REPAIR PARTITION
.
Jede dieser Optionen nimmt eine
partition_names
-Klausel entgegen,
die einen oder mehrere durch Kommata getrennte
Partitionsnamen umfasst. Die Partitionen müssen in der zu
ändernden Tabelle bereits vorhanden sein. Weitere
Informationen hierzu und zugehörige Beispiele finden Sie in
Abschnitt 17.3.3, „Wartung von Partitionen“.
Mit der C-API-Funktion mysql_info()
können
Sie ermitteln, wie viele Datensätze kopiert und (sofern
IGNORE
verwendet wird) aufgrund doppelt
vorhandener eindeutiger Schlüsselwerte gelöscht wurden. Siehe
auch Abschnitt 24.2.3.34, „mysql_info()
“.
Es folgen ein paar Beispiele, die Anwendungsmöglichkeiten für
ALTER TABLE
zeigen. Beginnen wir mit einer
Tabelle t1
, die wie folgt erstellt wird:
CREATE TABLE t1 (a INTEGER,b CHAR(10));
So benennen Sie die Tabelle von t1
in
t2
um:
ALTER TABLE t1 RENAME t2;
So ändern Sie den Typ der Spalte a
von
INTEGER
auf TINYINT NOT
NULL
(wobei der Name erhalten bleibt) und den Typ der
Spalte b
von CHAR(10)
zu
CHAR(20)
sowie deren Namen von
b
zu c
:
ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
So fügen Sie eine neue TIMESTAMP
-Spalte
namens d
hinzu:
ALTER TABLE t2 ADD d TIMESTAMP;
So fügen Sie Indizes zu den Spalten d
und
a
hinzu:
ALTER TABLE t2 ADD INDEX (d), ADD INDEX (a);
So entfernen Sie die Spalte c
:
ALTER TABLE t2 DROP COLUMN c;
So fügen Sie eine neue AUTO_INCREMENT
-Spalte
namens c
hinzu:
ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT, ADD PRIMARY KEY (c);
Beachten Sie, dass wir c
(als
PRIMARY KEY
) indiziert haben, weil
AUTO_INCREMENT
-Spalten indiziert werden
müssen, und dass wir außerdem c
als
NOT NULL
deklariert haben, weil
Primärschlüsselspalten nicht NULL
sein
dürfen.
Wenn Sie eine AUTO_INCREMENT
-Spalte
hinzufügen, werden als Spaltenwerte automatisch Sequenznummern
eingetragen. Bei MyISAM
-Tabellen können Sie
die erste Sequenznummer durch Ausführung von SET
INSERT_ID=
vor
value
ALTER TABLE
oder durch Verwendung der
Tabellenoption
AUTO_INCREMENT=
einstellen. Siehe auch Abschnitt 13.5.3, „value
SET
“.
Sie können die Tabellenoption ALTER TABLE ...
AUTO_INCREMENT=
bei
value
InnoDB
-Tabellen zur Einstellung der
Sequenznummer für neue Datensätze benutzen, wenn der Wert
größer ist als der höchste Wert in der
AUTO_INCREMENT
-Spalte. Ist der Wert
kleiner als der aktuelle Maximalwert der Spalte, dann wird keine
Fehlermeldung ausgegeben, und der aktuelle Sequenzwert wird
nicht geändert.
Wenn Sie bei MyISAM
-Tabellen die
AUTO_INCREMENT
-Spalte nicht ändern, ist die
Sequenznummer nicht betroffen. Wenn Sie eine
AUTO_INCREMENT
-Spalte löschen und dann eine
neue AUTO_INCREMENT
-Spalte hinzufügen,
beginnen die Sequenznummern wieder bei 1.
Siehe auch Abschnitt A.7.1, „Probleme mit ALTER TABLE
“.
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS]db_name
[create_specification
[,create_specification
] ...]create_specification
: [DEFAULT] CHARACTER SETcharset_name
| [DEFAULT] COLLATEcollation_name
CREATE DATABASE
erstellt eine Datenbank des
angegebenen Namens. Um CREATE DATABASE
verwenden zu können, benötigen Sie die Berechtigung
CREATE
für die Datenbank. CREATE
SCHEMA
ist ein Synonym für CREATE
DATABASE
.
Die Regeln für zulässige Datenbanknamen sind in
Abschnitt 9.2, „Datenbank-, Tabellen-, Index-, Spalten- und Aliasnamen“, beschrieben. Wenn die Datenbank
vorhanden ist und Sie IF NOT EXISTS
nicht
angegeben haben, tritt ein Fehler auf.
create_specification
-Optionen geben
die Datenbankeigenschaften an. Diese Datenbankeigenschaften sind
in der Datei db.opt
im Datenbankverzeichnis
gespeichert. Die Klausel CHARACTER SET
gibt
den Standardzeichensatz der Datenbank an. Die Klausel
COLLATE
gibt die Standardsortierfolge der
Datenbank an. Kapitel 10, Zeichensatz-Unterstützung, behandelt Namen von
Zeichensätzen und Sortierfolgen.
Datenbanken werden in MySQL als Verzeichnisse implementiert, die
Dateien enthalten, welche den Tabellen der Datenbank
entsprechen. Weil bei der Erstellung einer Datenbank noch keine
Tabellen vorhanden sind, erzeugt die Anweisung CREATE
DATABASE
lediglich ein Verzeichnis im
MySQL-Datenverzeichnis sowie die Datei
db.opt
.
Wenn Sie manuell (z. B. mit mkdir) ein
Verzeichnis im Datenverzeichnis erstellen, betrachtet der Server
dieses als Datenbankverzeichnis und zeigt es in der Ausgabe von
SHOW DATABASES
an.
Sie können zur Erstellung von Datenbanken auch das Programm mysqladmin verwenden. Siehe auch Abschnitt 8.7, „mysqladmin — Client für die Verwaltung eines MySQL Servers“.
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEXindex_name
[USINGindex_type
] ONtbl_name
(index_col_name
,...) [WITH PARSERparser_name
]index_col_name
:col_name
[(length
)] [ASC | DESC]
CREATE INDEX
wird mit einer ALTER
TABLE
-Anweisung verknüpft, um Indizes zu erstellen.
Siehe auch Abschnitt 13.1.2, „ALTER TABLE
“. Weitere Informationen
dazu, wie MySQL Indizes verwendet, finden Sie in
Abschnitt 7.4.5, „Wie MySQL Indizes benutzt“.
Normalerweise erstellen Sie alle Indizes für eine Tabelle zu
dem Zeitpunkt, an dem Sie auch die Tabelle selbst mit
CREATE TABLE
anlegen. Siehe auch
Abschnitt 13.1.5, „CREATE TABLE
“. CREATE INDEX
erlaubt Ihnen das Hinzufügen von Indizes zu vorhandenen
Tabellen.
Eine Spaltenliste in der Form (col1,col2,...)
erstellt einen mehrspaltigen Index. Indexwerte werden gebildet,
indem die Werte der betreffenden Spalten verkettet werden.
Bei CHAR
-, VARCHAR
-,
BINARY
- und
VARBINARY
-Spalten können Indizes erstellt
werden, die nur einen Teil einer Spalte verwenden. Hier
verwenden Sie die Syntax
,
um die Länge des Indexpräfixes anzugeben. Indexeinträge
umfassen dann die ersten col_name
(length
)length
Zeichen jedes Spaltenwerts bei CHAR
- und
VARCHAR
-Spalten sowie die ersten
length
Bytes jedes Spaltenwerts bei
BINARY
- und
VARBINARY
-Spalten. BLOB
-
und TEXT
-Spalten lassen sich auch indizieren,
aber eine Präfixlänge muss angegeben
werden.
Die folgende Anweisung erstellt einen Index unter Verwendung der
ersten zehn Zeichen der Spalte name
:
CREATE INDEX part_of_name ON customer (name(10));
Wenn die ersten zehn Zeichen aller Namen in der Spalte sich
durchgehend unterscheiden, dann sollte dieser Index nicht viel
langsamer sein als ein Index, der aus der gesamten Spalte
name
erstellt wurde. Auch die Verwendung von
Teilspalten für Indizes kann die Indexdatei wesentlich kleiner
machen, wodurch sich viel Festplattenspeicher sparen lässt und
INSERT
-Operationen unter Umständen auch
beschleunigt werden können.
Präfixe können bis 1.000 Byte lang sein (767 Byte bei
InnoDB
-Tabellen). Beachten Sie, dass
Präfixbeschränkungen in Byte angegeben werden, wohingegen die
Präfixlänge in CREATE INDEX
-Anweisungen bei
nichtbinären Datentypen (CHAR
,
VARCHAR
, TEXT
) als Anzahl
der Zeichen interpretiert wird. Dies muss bei der Angabe einer
Präfixlänge für eine Spalte berücksichtigt werden, die einen
Multibytezeichensatz verwendet.
In MySQL 5.1 können Sie
einen Index für eine Spalte, die
NULL
-Werte enthalten kann, nur dann
hinzufügen, wenn Sie die Speicher-Engines
MyISAM
, InnoDB
,
BDB
oder MEMORY
verwenden,
einen Index für eine BLOB
- oder
TEXT
-Spalte nur dann hinzufügen, wenn
Sie die Speicher-Engines MyISAM
,
BDB
oder InnoDB
verwenden.
Eine index_col_name
-Definition kann
auf ASC
oder DESC
enden.
Diese Schlüsselwörter sind für zukünftige Erweiterungen
zulässig, um eine Speicherung der Indexwerte in auf- oder
absteigender Reihenfolge festzulegen. Zurzeit werden sie zwar
erkannt, aber ignoriert – Indexwerte werden immer in
aufsteigender Reihenfolge gespeichert.
Einige Speicher-Engines gestatten bei der Erstellung eines
Indexes die Angabe eines Indextyps. Die Syntax für die
Konfigurationsangabe index_type
lautet USING
. Zulässige Werte
für type_name
type_name
, die von den
verschiedenen Speicher-Engines unterstützt werden, sind in der
folgenden Tabelle aufgelistet. Sind mehrere Indextypen
aufgeführt, so wird der erste standardmäßig verwendet, wenn
keine Angabe für index_type
vorhanden ist.
Speicher-Engine | Zulässige Indextypen |
MyISAM | BTREE |
InnoDB | BTREE |
MEMORY /HEAP | HASH , BTREE |
Ein paar Beispiele:
CREATE TABLE lookup (id INT) ENGINE = MEMORY; CREATE INDEX id_index USING BTREE ON lookup (id);
TYPE
kann als Synonym für type_name
USING
benutzt werden,
um einen Indextyp anzugeben. Allerdings ist
type_name
USING
die bevorzugte Form. Ferner ist der
Indexname, der in der Syntax zur Indexspezifikation vor dem
Indextyp steht, bei TYPE
nicht optional:
Anders als USING
ist TYPE
kein reserviertes Wort und wird infolgedessen nicht als
Indexname interpretiert.
Wenn Sie einen Indextyp angeben, der für eine gegebene Speicher-Engine nicht zulässig ist, aber ein anderer Indextyp vorhanden ist, den die Engine verwenden kann, ohne dass hiervon Abfrageergebnisse betroffen wären, dann verwendet die Engine diesen verfügbaren Typ.
FULLTEXT
-Indizes werden nur für
MyISAM
-Tabellen unterstützt und dürfen nur
CHAR
-, VARCHAR
- und
TEXT
-Spalten enthalten. Siehe auch
Abschnitt 12.7, „MySQL-Volltextsuche“. Eine WITH
PARSER
-Klausel kann angegeben werden, um ein
Parser-Plug-In mit dem Index zu verknüpfen, wenn
Volltextindizierungs- und Suchoperationen besondere Maßnahmen
erfordern. Diese Klausel ist nur für
FULLTEXT
-Indizes zulässig. Informationen zur
Erstellung von Plug-Ins finden Sie in
Abschnitt 26.2, „Die MySQL-Plug-In-Schnittstelle“.
SPATIAL
-Indizes werden nur für
MyISAM
-Tabellen unterstützt und dürfen nur
raumbezogene Spalten enthalten, die als NOT
NULL
definiert sind.
Kapitel 18, Raumbezogene Erweiterungen in MySQL, beschreibt raumbezogene
Datentypen.
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
[(create_definition
,...)] [table_options
] [select_statement
]
Oder:
CREATE [TEMPORARY] TABLE [IF NOT EXISTS]tbl_name
[(] LIKEold_tbl_name
[)];create_definition
:column_definition
| [CONSTRAINT [symbol
]] PRIMARY KEY [index_type
] (index_col_name
,...) | KEY [index_name
] [index_type
] (index_col_name
,...) | INDEX [index_name
] [index_type
] (index_col_name
,...) | [CONSTRAINT [symbol
]] UNIQUE [INDEX] [index_name
] [index_type
] (index_col_name
,...) | FULLTEXT [INDEX] [index_name
] (index_col_name
,...) [WITH PARSERparser_name
] | SPATIAL [INDEX] [index_name
] (index_col_name
,...) | [CONSTRAINT [symbol
]] FOREIGN KEY [index_name
] (index_col_name
,...) [reference_definition
] | CHECK (expr
)column_definition
:col_name
type
[NOT NULL | NULL] [DEFAULTdefault_value
] [AUTO_INCREMENT] [UNIQUE [KEY] | [PRIMARY] KEY] [COMMENT 'string
'] [reference_definition
]type
: TINYINT[(length
)] [UNSIGNED] [ZEROFILL] | SMALLINT[(length
)] [UNSIGNED] [ZEROFILL] | MEDIUMINT[(length
)] [UNSIGNED] [ZEROFILL] | INT[(length
)] [UNSIGNED] [ZEROFILL] | INTEGER[(length
)] [UNSIGNED] [ZEROFILL] | BIGINT[(length
)] [UNSIGNED] [ZEROFILL] | REAL[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | DOUBLE[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | FLOAT[(length
,decimals
)] [UNSIGNED] [ZEROFILL] | DECIMAL(length
,decimals
) [UNSIGNED] [ZEROFILL] | NUMERIC(length
,decimals
) [UNSIGNED] [ZEROFILL] | DATE | TIME | TIMESTAMP | DATETIME | YEAR | CHAR(length
) [BINARY | ASCII | UNICODE] | VARCHAR(length
) [BINARY] | BINARY(length
) | VARBINARY(length
) | TINYBLOB | BLOB | MEDIUMBLOB | LONGBLOB | TINYTEXT [BINARY] | TEXT [BINARY] | MEDIUMTEXT [BINARY] | LONGTEXT [BINARY] | ENUM(value1
,value2
,value3
,...) | SET(value1
,value2
,value3
,...) |spatial_type
index_col_name
:col_name
[(length
)] [ASC | DESC]reference_definition
: REFERENCEStbl_name
[(index_col_name
,...)] [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE] [ON DELETEreference_option
] [ON UPDATEreference_option
]reference_option
: RESTRICT | CASCADE | SET NULL | NO ACTIONtable_options
:table_option
[table_option
] ...table_option
: {ENGINE|TYPE} [=]engine_name
| AUTO_INCREMENT [=]value
| AVG_ROW_LENGTH [=]value
| [DEFAULT] CHARACTER SETcharset_name
[COLLATEcollation_name
] | CHECKSUM [=] {0 | 1} | COMMENT [=] 'string
' | CONNECTION [=] 'connect_string
' | MAX_ROWS [=]value
| MIN_ROWS [=]value
| PACK_KEYS [=] {0 | 1 | DEFAULT} | PASSWORD [=] 'string
' | DELAY_KEY_WRITE [=] {0 | 1} | ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT} | UNION [=] (tbl_name
[,tbl_name
]...) | INSERT_METHOD [=] { NO | FIRST | LAST } | DATA DIRECTORY [=] 'absolute path to directory
' | INDEX DIRECTORY [=] 'absolute path to directory
'partition_options
: PARTITION BY [LINEAR] HASH(expr
) | [LINEAR] KEY(column_list
) | RANGE(expr
) | LIST(expr
) [PARTITIONSnum
] [ SUBPARTITION BY [LINEAR] HASH(expr
) | [LINEAR] KEY(column_list
) [SUBPARTITIONSnum
] ] [(partition_definition
) [, (partition_definition
)] ...]partition_definition
: PARTITIONpartition_name
[VALUES {LESS THAN (expr
) |MAXVALUE
| IN (value_list
)}] [[STORAGE] ENGINE [=]engine-name
] [COMMENT [=]'comment_text'
] [DATA DIRECTORY [=] ''] [INDEX DIRECTORY [=] '
data_dir
'] [MAX_ROWS [=]
index_dir
max_number_of_rows
] [MIN_ROWS [=]min_number_of_rows
] [TABLESPACE [=] (tablespace_name
)] [NODEGROUP [=]node_group_id
] [(subpartition_definition
) [, (subpartition_definition
)] ...]subpartition_definition
: SUBPARTITIONlogical_name
[[STORAGE] ENGINE [=]engine-name
] [COMMENT [=]'comment_text'
] [DATA DIRECTORY [=] ''] [INDEX DIRECTORY [=] '
data_dir
'] [MAX_ROWS [=]
index_dir
max_number_of_rows
] [MIN_ROWS [=]min_number_of_rows
] [TABLESPACE [=] (tablespace_name
)] [NODEGROUP [=]node_group_id
]select_statement:
[IGNORE | REPLACE] [AS] SELECT ... (Some legal select statement
)
CREATE TABLE
erstellt eine Tabelle des
angegebenen Namens. Für die Tabelle benötigen Sie die
Berechtigung CREATE
.
Die Regeln für zulässige Tabellennamen sind in Abschnitt 9.2, „Datenbank-, Tabellen-, Index-, Spalten- und Aliasnamen“, beschrieben. Standardmäßig wird die Tabelle in der Standarddatenbank erstellt. Wenn die Tabelle bereits vorhanden ist oder weder die Standarddatenbank noch die angegebene Datenbank vorhanden sind, wird ein Fehler erstellt.
Der Tabellenname kann als
db_name.tbl_name
angegeben werden, um
die Tabelle in einer bestimmten Datenbank zu erstellen. Das
funktioniert unabhängig vom Vorhandensein einer
Standarddatenbank, sofern die angegebene Datenbank vorhanden
ist. Wenn Sie Bezeichner in Anführungszeichen verwenden, setzen
Sie Datenbank- und Tabellennamen separat in Anführungszeichen.
So ist etwa `mydb`.`mytbl`
zulässig –
anders als `mydb.mytbl`
.
Sie können das Schlüsselwort TEMPORARY
bei
der Erstellung einer Tabelle verwenden. Eine
TEMPORARY
-Tabelle ist nur für die aktuelle
Verbindung sichtbar und wird beim Beenden dieser Verbindung
automatisch gelöscht. Das bedeutet, dass zwei verschiedene
Verbindungen Temporärtabellen desselben Namens verwenden
können, ohne dass es zu Konflikten mit der jeweils anderen
Tabelle oder einer nichttemporären Tabelle gleichen Namens
kommt. (Die vorhandene Tabelle wird verborgen, bis die
Temporärtabelle gelöscht wird.) Zur Erstellung von
Temporärtabellen benötigen Sie die Berechtigung
CREATE TEMPORARY TABLES
.
Die Schlüsselwörter IF NOT EXISTS
verhindern, dass ein Fehler auftritt, wenn die Tabelle vorhanden
ist. Allerdings wird nicht überprüft, ob die vorhandene
Tabelle die gleiche Struktur wie die in der CREATE
TABLE
-Anweisung angegebene Tabelle hat.
Hinweis: Wenn Sie IF NOT
EXISTS
in einer CREATE TABLE ...
SELECT
-Anweisung verwenden, werden alle durch den
SELECT
-Teil gewählten Datensätze ohne
Berücksichtigung der Frage eingefügt, ob die Tabelle bereits
vorhanden ist.
MySQL stellt jede Tabelle durch eine
.frm
-Tabellenformatdatei (Definitionsdatei)
im Datenbankverzeichnis dar. Die Speicher-Engine der Tabelle
erstellt unter Umständen auch andere Dateien. Im Falle von
MyISAM
-Tabellen erstellt die Speicher-Engine
Daten- und Indexdateien. Es gibt also für jede
MyISAM
-Tabelle
tbl_name
drei Dateien auf der
Festplatte:
Datei | Zweck |
| Tabellenformatdatei (Definitionsdatei) |
| Datendatei |
| Indexdatei |
Kapitel 14, Speicher-Engines und Tabellentypen, beschreibt, welche Dateien die einzelnen Speicher-Engines zur Darstellung von Tabellen erstellen.
type
stellt den Datentyp einer
Spaltendefinition dar. spatial_type
ist ein
raumbezogener Datentyp. Allgemeine Informationen zu den
Eigenschaften von Datentypen (außer raumbezogenen Datentypen)
finden Sie in Kapitel 11, Datentypen. Informationen zu
raumbezogenen Datentypen finden Sie in
Kapitel 18, Raumbezogene Erweiterungen in MySQL.
Wenn weder NULL
noch NOT
NULL
angegeben sind, wird die Spalte so behandelt,
als ob NULL
angegeben worden wäre.
Eine Integer-Spalte kann das Zusatzattribut
AUTO_INCREMENT
erhalten. Wenn Sie den
Wert NULL
(empfohlen) oder
0
in eine indizierte
AUTO_INCREMENT
-Spalte einfügen, wird die
Spalte auf den nächsten Sequenzwert gesetzt. Normalerweise
ist dies
, wobei
value
+1value
der derzeit größte Wert
der Spalte in der Tabelle ist.
AUTO_INCREMENT
-Sequenzen beginnen bei
1
.
Um einen AUTO_INCREMENT
-Wert nach
Einfügen eines Datensatzes abzurufen, verwenden Sie die
SQL-Funktion LAST_INSERT_ID()
oder die
C-API-Funktion mysql_insert_id()
. Siehe
auch Abschnitt 12.10.3, „Informationsfunktionen“, und
Abschnitt 24.2.3.36, „mysql_insert_id()
“.
Wenn der SQL-Modus NO_AUTO_VALUE_ON_ZERO
aktiviert ist, können Sie 0
in
AUTO_INCREMENT
-Spalten als
0
speichern, ohne einen neuen Sequenzwert
zu erzeugen. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.
Hinweis: Es kann nur eine
AUTO_INCREMENT
-Spalte pro Tabelle geben.
Diese muss indiziert sein und darf keinen Standardwert
haben. Eine AUTO_INCREMENT
-Spalte
funktioniert nur dann einwandfrei, wenn sie ausschließlich
positive Werte enthält. Das Einfügen eines negativen Werts
wird als Einfügen einer sehr großen positiven Zahl
aufgefasst. Dies wird gemacht, um genauigkeitsspezifische
Probleme zu vermeiden, die beim „Umklappen“ von
positiven auf negative Zahlen auftreten können, und um zu
gewährleisten, dass Sie nicht versehentlich eine
AUTO_INCREMENT
-Spalte erhalten, die
0
enthält.
Bei MyISAM
- und
BDB
-Tabellen können Sie
AUTO_INCREMENT
in einer Sekundärspalte
eines mehrspaltigen Schlüssels angeben. Siehe auch
Abschnitt 3.6.9, „Verwendung von AUTO_INCREMENT
“.
Um MySQL mit einigen ODBC-Anwendungen kompatibel zu machen,
können Sie den AUTO_INCREMENT
-Wert für
den letzten eingefügten Datensatz mit der folgenden Abfrage
ermitteln:
SELECT * FROMtbl_name
WHEREauto_col
IS NULL
Das Attribut SERIAL
kann als Alias für
BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
UNIQUE
verwendet werden.
Zeichendatentypen (CHAR
,
VARCHAR
, TEXT
) können
CHARACTER SET
- und
COLLATE
-Attribute zur Angabe von
Zeichensatz und Sortierfolge der Spalte enthalten. Weitere
Informationen finden Sie in Kapitel 10, Zeichensatz-Unterstützung.
CHARSET
ist ein Synonym für
CHARACTER SET
. Beispiel:
CREATE TABLE t (c CHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
MySQL 5.1 interpretiert Längenangaben in Zeichenspaltendefinitionen als Anzahl von Zeichen. (Versionen vor MySQL 4.1 interpretierten sie als Anzahl von Bytes.)
Die DEFAULT
-Klausel gibt einen
Vorgabewert für eine Spalte an. Mit einer Ausnahme muss der
Vorgabewert immer eine Konstante sein. Funktionen oder
Ausdrücke sind als Vorgabe nicht zulässig. Das bedeutet,
dass Sie beispielsweise als Vorgabewert einer Datumsspalte
nicht den Wert einer Funktion wie NOW()
oder CURRENT_DATE
angeben dürfen. Die
genannte Ausnahme besteht darin, dass Sie
CURRENT_TIMESTAMP
als Vorgabe für eine
TIMESTAMP
-Spalte festlegen können. Siehe
auch Abschnitt 11.3.1.1, „TIMESTAMP
-Eigenschaften ab MySQL 4.1“.
Wenn eine Spaltendefinition keinen expliziten
DEFAULT
-Wert enthält, bestimmt MySQL
diesen wie in Abschnitt 11.1.4, „Vorgabewerte von Datentypen“,
beschrieben.
Für BLOB
- und
TEXT
-Spalten können keine Vorgaben
festgelegt werden.
Ein Kommentar für eine Spalte kann mit der Option
COMMENT
angegeben werden. Der Kommentar
wird über die Anweisungen SHOW CREATE
TABLE
und SHOW FULL COLUMNS
angezeigt.
KEY
ist normalerweise ein Synonym für
INDEX
. Das Schlüsselattribut
PRIMARY KEY
kann auch einfach als
KEY
angegeben werden, sofern die Angabe
in einer Spaltendefinition erfolgt. Dieses Verhalten wurde
aus Gründen der Kompatibilität mit anderen
Datenbanksystemen implementiert.
Ein eindeutiger Index ist dahingehend eingeschränkt, dass
alle Werte im Index eindeutig sein müssen. Wenn Sie einen
neuen Datensatz mit einem Schlüssel hinzufügen, der dem
eines vorhandenen Datensatzes entspricht, tritt ein Fehler
auf. Eine Ausnahme hierzu besteht darin, dass, wenn eine
Spalte im Index NULL
-Werte enthalten
darf, diese mehrere NULL
-Werte enthalten
kann. Diese Ausnahme gilt jedoch nicht für
BDB
-Tabellen, bei denen eine Spalte mit
einem eindeutigen Index NULL
nur einmalig
gestattet.
Ein Primärschlüssel ist ein eindeutiger Index, bei dem
alle Schlüsselspalten als NOT NULL
definiert sein müssen. Wenn sie nicht explizit als
NOT NULL
deklariert sind, holt MySQL dies
implizit (und stillschweigend) nach. Eine Tabelle darf nur
einen Primärschlüssel enthalten. Wenn Sie keinen
Primärschlüssel haben und eine Anwendung nach dem
Primärschlüssel in Ihren Tabellen fragt, gibt MySQL als
Primärschlüssel den ersten eindeutigen Index zurück, der
keine NULL
-Spalten verwendet.
In der erstellten Tabelle wird der Primärschlüssel an die
erste Position gesetzt, gefolgt von allen eindeutigen
Indizes und nachfolgend den nichteindeutigen Indizes. Dies
erleichtert dem MySQL-Optimierer die Priorisierung der zu
verwendenden Indizes und die schnelle Erkennung von
Dubletten bei den UNIQUE
-Schlüsseln.
Ein Primärschlüssel kann ein mehrspaltiger Index sein. Sie
können allerdings keinen mehrspaltigen Index mithilfe des
Schlüsselattributs PRIMARY KEY
in einer
Spaltendefinition erstellen. Wenn Sie dies tun, wird nur
diese eine Spalte als Primärschlüssel gekennzeichnet. Sie
müssen hierzu eine separate PRIMARY
KEY(index_col_name, ...)
-Klausel verwenden.
Wenn ein Primärschlüssel oder ein eindeutiger Index aus
nur einer Spalte eines Integer-Typs bestehen, können Sie
die Spalte auch in SELECT
-Anweisungen als
_rowid
referenzieren.
In MySQL lautet der Name eines Primärschlüssels
PRIMARY
. Bei anderen Indizes erhält,
sofern Sie keinen Namen angeben, der Index jeweils denselben
Namen wie die erste indizierte Spalte. Es kann optional ein
Suffix (_2
, _3
,
...
) angegeben werden, um den Index
eindeutig zu machen. Sie können die Indexnamen für eine
Tabelle mit SHOW INDEX FROM
anzeigen.
Siehe auch Abschnitt 13.5.4.12, „tbl_name
SHOW INDEX
“.
Einige Speicher-Engines gestatten bei der Erstellung eines
Indexes die Angabe eines Indextyps. Die Syntax für die
Konfigurationsangabe index_type
lautet USING
.
type_name
Beispiel:
CREATE TABLE lookup (id INT, INDEX USING BTREE (id)) ENGINE = MEMORY;
Detaillierte Informationen zu USING
finden Sie in Abschnitt 13.1.4, „CREATE INDEX
“.
Weitere Informationen dazu, wie MySQL Indizes verwendet, finden Sie in Abschnitt 7.4.5, „Wie MySQL Indizes benutzt“.
In MySQL 5.1 unterstützen nur die
Speicher-Engines MyISAM
,
InnoDB
, BDB
und
MEMORY
Indizes bei Spalten, die
NULL
-Werte enthalten. In anderen Fällen
müssen Sie indizierte Spalten als NOT
NULL
deklarieren, andernfalls wird ein Fehler
zurückgegeben.
Mit der Syntax
in einer Indexdefinition können Sie einen Index erstellen,
der die Spalte nur teilweise verwendet. Indexeinträge
umfassen die ersten col_name
(length
)length
Zeichen jedes Spaltenwerts bei CHAR
- und
VARCHAR
-Spalten sowie die ersten
length
Bytes jedes Spaltenwerts
bei BINARY
- und
VARBINARY
-Spalten. Wenn Sie auf diese
Weise nur ein Präfix der Spaltenwerte indizieren, kann dies
die Indexdatei erheblich kleiner machen. Siehe auch
Abschnitt 7.4.3, „Spaltenindizes“.
Die Speicher-Engines MyISAM
,
BDB
und InnoDB
unterstützen die Indizierung von BLOB
-
und TEXT
-Spalten. Bei der Indizierung
einer BLOB
- oder
TEXT
-Spalte müssen
Sie eine Präfixlänge für den Index angeben. Zum Beispiel:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Präfixe können bis 1.000 Byte lang sein (767 Byte bei
InnoDB
-Tabellen). Beachten Sie, dass
Präfixbeschränkungen in Byte angegeben werden, wohingegen
die Präfixlänge in CREATE
TABLE
-Anweisungen bei nichtbinären Datentypen
(CHAR
, VARCHAR
,
TEXT
) als Anzahl der Zeichen
interpretiert wird. Dies muss bei der Angabe einer
Präfixlänge für eine Spalte berücksichtigt werden, die
einen Multibytezeichensatz verwendet.
Eine index_col_name
-Definition
kann auf ASC
oder DESC
enden. Diese Schlüsselwörter sind für zukünftige
Erweiterungen zulässig, um eine Speicherung der Indexwerte
in auf- oder absteigender Reihenfolge festzulegen. Zurzeit
werden sie zwar erkannt, aber ignoriert – Indexwerte
werden immer in aufsteigender Reihenfolge gespeichert.
Wenn Sie ORDER BY
oder GROUP
BY
für eine TEXT
- oder
BLOB
-Spalte in einer
SELECT
-Anweisung verwenden, sortiert der
Server Werte lediglich unter Verwendung der ersten Bytes.
Wie viele Bytes dies sind, wird von der Systemvariablen
max_sort_length
angegeben. Siehe auch
Abschnitt 11.4.3, „Die Spaltentypen BLOB
und TEXT
“.
Sie können spezielle Volltextindizes erstellen, die für
die Volltextsuche verwendet werden. Nur die
MyISAM
-Speicher-Engine unterstützt
Volltextindizes. Diese können nur aus
CHAR
-, VARCHAR
- und
TEXT
-Spalten erstellt werden. Die
Indizierung erfolgt immer über die gesamte Spalte: Eine
Teilindizierung wird nicht unterstützt, und ein eventuell
angegebenes Präfix wird ignoriert. Weitere Informationen
finden Sie in Abschnitt 12.7, „MySQL-Volltextsuche“. Eine
WITH PARSER
-Klausel kann angegeben
werden, um ein Parser-Plug-In mit dem Index zu verknüpfen,
wenn Volltextindizierungs- und Suchoperationen besondere
Maßnahmen erfordern. Diese Klausel ist nur für
FULLTEXT
-Indizes zulässig. Informationen
zur Erstellung von Plug-Ins finden Sie in
Abschnitt 26.2, „Die MySQL-Plug-In-Schnittstelle“.
SPATIAL
-Indizes können Sie für
raumbezogene Typen erstellen. Solche Typen werden nur für
MyISAM
-Tabellen unterstützt, und
indizierte Spalten müssen als NOT NULL
deklariert sein. Siehe auch
Kapitel 18, Raumbezogene Erweiterungen in MySQL.
InnoDB
-Tabellen unterstützen die
Überprüfung von Fremdschlüssel-Constraints. Siehe auch
Abschnitt 14.2, „InnoDB
-Tabellen“. Beachten Sie, dass die
Fremdschlüsselsyntax in InnoDB
restriktiver ist als die zu Beginn dieses Abschnitts für
die CREATE TABLE
-Anweisung präsentierte
Syntax: Die Spalten der referenzierten Tabellen müssen
immer explizit genannt werden. InnoDB
unterstützt sowohl ON DELETE
- als auch
ON UPDATE
-Aktionen für Fremdschlüssel.
Informationen zur exakten Syntax finden Sie in
Abschnitt 14.2.6.4, „Fremdschlüssel-Beschränkungen“.
Bei anderen Speicher-Engines erkennt MySQL Server die
FOREIGN KEY
- und
REFERENCES
-Syntax in CREATE
TABLE
-Anweisungen, ignoriert sie aber. Zudem wird
die Klausel CHECK
von allen
Speicher-Engines erkannt, aber ignoriert. Siehe auch
Abschnitt 1.9.5.5, „Fremdschlüssel“.
Bei MyISAM
-Tabellen benötigt jede
NULL
-Spalte ein zusätzliches Bit,
aufgerundet auf das nächste Byte. Die maximale
Datensatzlänge in Byte kann wie folgt berechnet werden:
row length = 1 + (sum of column lengths
) + (number of NULL columns
+delete_flag
+ 7)/8 + (number of variable-length columns
)
delete_flag
ist 1 bei Tabellen
mit statischem Datensatzformat. Statische Tabellen verwenden
ein Bit im Datensatz für ein Flag, das angibt, ob der
Datensatz gelöscht wurde.
delete_flag
ist 0 bei dynamischen
Tabellen, weil das Flag im dynamischen Datensatz-Header
gespeichert wird.
Diese Berechnungen gelten nicht für
InnoDB
-Tabellen, bei denen der
Speicherbedarf von NULL
-Spalten sich
nicht von dem von NOT NULL
-Spalten
unterscheidet.
Die Tabellenoption ENGINE
gibt die
Speicher-Engine für die Tabelle an. TYPE
ist
ein Synonym hierzu, wobei ENGINE
der
bevorzugte Name ist.
Die Tabellenoption ENGINE
akzeptiert die in
der folgenden Tabelle aufgeführten Namen für Speicher-Engines.
Speicher-Engine | Beschreibung |
ARCHIVE | Speicher-Engine zur Archivierung. Siehe auch
Abschnitt 14.8, „Die ARCHIVE -Speicher-Engine“. |
BDB | Transaktionssichere Tabellen mit Seitensperrung. Heißt auch
BerkeleyDB . Siehe auch
Abschnitt 14.5, „Die BDB -Speicher-Engine“. |
CSV | Tabellen, die Datensätze als kommagetrennte Werte speichern. Siehe auch
Abschnitt 14.9, „Die CSV -Speicher-Engine“. |
EXAMPLE | Eine Beispiel-Engine. Siehe auch
Abschnitt 14.6, „Die EXAMPLE -Speicher-Engine“. |
FEDERATED | Speicher-Engine, die auf entfernte Tabellen zugreift. Siehe auch
Abschnitt 14.7, „Die FEDERATED -Speicher-Engine“. |
HEAP | Ein Synonym für MEMORY . |
ISAM (VERALTET) | In MySQL 5.1 nicht verfügbar. Wenn Sie von einer älteren
Version auf MySQL 5.1 aktualisieren,
sollten Sie alle vorhandenen
ISAM -Tabellen in
MyISAM -Tabellen konvertieren,
bevor Sie das Upgrade durchführen. |
InnoDB | Transaktionssichere Tabellen mit Datensatzsperrung und Fremdschlüsseln.
Siehe auch Abschnitt 14.2, „InnoDB -Tabellen“. |
MEMORY | Die Daten für diese Speicher-Engine werden nur im Speicher abgelegt.
Siehe auch Abschnitt 14.4, „Die MEMORY -Speicher-Engine“. |
MERGE | Eine Sammlung von MyISAM -Tabellen, die als eine
Tabelle verwendet wird. Heißt auch
MRG_MyISAM . Siehe auch
Abschnitt 14.3, „Die MERGE -Speicher-Engine“. |
MyISAM | Binäre portable Speicher-Engine, die als Standard-Engine in MySQL
verwendet wird. Siehe auch
Abschnitt 14.1, „Die MyISAM -Speicher-Engine“. |
NDBCLUSTER | Fehlertolerante, speicherbasierte Cluster-Tabellen. Heißt auch
NDB . Siehe auch
Kapitel 16, MySQL Cluster. |
Wird eine Speicher-Engine angegeben, die nicht verfügbar ist,
dann verwendet MySQL stattdessen die Standard-Engine. Im
Normalfall ist dies MyISAM
. Wenn
beispielsweise eine Tabellendefinition die Option
ENGINE=BDB
enthält, aber der MySQL Server
BDB
-Tabellen nicht unterstützt, dann wird
die Tabelle als MyISAM
-Tabelle erstellt. Auf
diese Weise ist eine Replikationskonfiguration realisierbar, bei
der Sie transaktionssichere Tabellen auf dem Master haben,
während die auf dem Slave erstellten Tabellen nicht
transaktionssicher sind (was eine Erhöhung der
Verarbeitungsgeschwindigkeit nach sich zieht). In MySQL
5.1 erscheint eine Warnung, wenn die Spezifikation
der Speicher-Engine nicht berücksichtigt werden kann.
Die übrigen Tabellenoptionen werden zur Optimierung des Verhaltens der Tabelle verwendet. In den meisten Fällen müssen Sie sie überhaupt nicht angeben. Diese Optionen gelten für alle Speicher-Engines, soweit nichts anderes angegeben ist:
AUTO_INCREMENT
Der AUTO_INCREMENT
-Startwert für die
Tabelle. In MySQL 5.1 funktioniert dies bei
MyISAM
-, MEMORY
- und
InnoDB
-Tabellen. Um den ersten
AUTO_INCREMENT
-Wert für Engines zu
setzen, die die Tabellenoption
AUTO_INCREMENT
nicht unterstützen,
fügen Sie einen „Pseudodatensatz“ mit einem
Wert ein, der um 1 niedriger ist als der gewünschte
Startwert. Nach der Erstellung der Tabelle löschen Sie den
Pseudodatensatz dann.
Bei Engines, die die Tabellenoption
AUTO_INCREMENT
in CREATE
TABLE
-Anweisungen unterstützen, können Sie auch
ALTER TABLE
verwenden, um den tbl_name
AUTO_INCREMENT = N
AUTO_INCREMENT
-Wert
zurückzusetzen.
AVG_ROW_LENGTH
Ein Näherungswert für die durchschnittliche Datensatzlänge in Ihrer Tabelle. Sie müssen die Einstellung nur bei großen Tabellen mit Datensätzen unterschiedlicher Größe vornehmen.
Wenn Sie eine MyISAM
-Tabelle erstellen,
verwendet MySQL das Produkt der Optionen
MAX_ROWS
und
AVG_ROW_LENGTH
, um zu ermitteln, wie
groß die resultierende Tabelle sein wird. Geben Sie keine
der Optionen an, dann beträgt die maximale Tabellengröße
65.536 Tbyte Daten. (Wenn Ihr Betriebssystem derart große
Dateien nicht unterstützt, wird die maximale Größe einer
Tabelle durch die betriebssystemseitige Beschränkung der
Dateigröße bestimmt.) Wenn Sie die Zeigergrößen gering
halten wollen, damit der Index kleiner und schneller wird,
und Sie eigentlich keine großen Dateien benötigen, können
Sie die Standardzeigergröße durch Einstellen der
Systemvariablen myisam_data_pointer_size
verringern. (Siehe auch
Abschnitt 5.2.2, „Server-Systemvariablen“.) Wenn Sie wollen,
dass alle Ihre Tabellen über das standardmäßige Limit
hinaus anwachsen können, und dafür in Kauf nehmen, dass
die Tabellen etwas größer und langsamer sind als
notwendig, dann können Sie die Standardzeigergröße durch
Einstellen der Variablen auch erhöhen.
[DEFAULT] CHARACTER SET
Gibt einen Standardzeichensatz für die Tabelle an.
CHARSET
ist ein Synonym für
CHARACTER SET
.
COLLATE
Gibt eine Standardsortierfolge für die Tabelle an.
CHECKSUM
Setzen Sie diese Option auf 1, wenn Sie wollen, dass MySQL
eine Prüfsumme für alle Datensätze erstellt, die zudem
bei Änderungen in der Tabelle automatisch aktualisiert
wird. Dies macht die Aktualisierung der Tabelle zwar ein
wenig langsamer, erleichtert aber das Auffinden
beschädigter Tabellen. Die Anweisung CHECKSUM
TABLE
meldet die Prüfsumme. (Nur für
MyISAM
.)
COMMENT
Ein Kommentar für die Tabelle, der bis zu 60 Zeichen lang sein kann.
CONNECTION
Der Verbindungs-String für eine
FEDERATED
-Tabelle.
(Hinweis: Ältere Versionen
von MySQL verwendeten eine Option COMMENT
für den Verbindungs-String.)
MAX_ROWS
Maximale Anzahl der Datensätze, die Sie in der Tabelle zu speichern beabsichtigen. Dies ist keine feste Beschränkung, sondern ein Indikator für die Anzahl der Datensätze, die die Tabelle zumindest speichern können muss.
MIN_ROWS
Minimale Anzahl der Datensätze, die Sie in der Tabelle zu speichern beabsichtigen.
PACK_KEYS
Setzen Sie diese Option auf 1, wenn Sie kleinere Indizes
wünschen. Hierdurch werden Updates in der Regel langsamer
und Leseoperationen schneller. Wenn Sie die Option auf 0
setzen, wird das Packen für alle Schlüssel deaktiviert.
Setzen Sie sie hingegen auf DEFAULT
, dann
wird die Speicher-Engine angewiesen, nur lange
CHAR
- und
VARCHAR
-Spalten zu packen. (Nur für
MyISAM
.)
Wenn Sie PACK_KEYS
nicht verwenden,
werden standardmäßig Strings, aber nicht Zahlen gepackt.
Bei PACK_KEYS=1
werden auch Zahlen
gepackt.
Beim Packen von binären Zahlenschlüsseln verwendet MySQL die Präfixkompression:
Jeder Schlüssel benötigt ein zusätzliches Byte, um anzugeben, wie viele Bytes des vorherigen Schlüssels beim nachfolgenden Schlüssel identisch sind.
Der Zeiger auf den Datensatz wird direkt auf den Schlüssel folgend und in absteigender Reihenfolge der Bytewertigkeit gespeichert, um die Komprimierung zu optimieren.
Das bedeutet, dass, wenn Sie viele gleiche Schlüssel in
zwei aufeinander folgenden Datensätzen haben, alle
nachfolgenden „identischen“ Schlüssel
einschließlich des Zeigers auf den Datensatz nur 2 Byte
benötigen. Vergleichen Sie dies einmal mit dem normalen
Fall, in dem die nachfolgenden Schlüssel
storage_size_for_key + pointer_size
Bytes
benötigen (wobei die Zeigergröße normalerweise 4
beträgt). Umgekehrt können Sie nur dann umfassend von der
Präfixkomprimierung profitieren, wenn Sie viele identische
Zahlen haben. Wenn alle Schlüssel vollständig
unterschiedlich sind, verwenden Sie pro Schlüssel ein Byte
mehr, wenn der jeweilige Schlüssel keine
NULL
-Werte haben kann. (In diesem Fall
wird die Länge des gepackten Schlüssels im selben Byte
gespeichert, das zur Kennzeichnung verwendet wird, wenn ein
Schlüssel NULL
ist.)
PASSWORD
Verschlüsselt die .frm
-Datei mit einem
Passwort. In der MySQL-Standardversion tut die Option
nichts.
DELAY_KEY_WRITE
Setzen Sie diese Option auf 1, wenn Sie Schlüssel-Updates
für die Tabelle auf einen Zeitpunkt verschieben wollen, an
dem die Tabelle geschlossen ist. Details finden Sie in der
Beschreibung zur Systemvariablen
delay_key_write
in
Abschnitt 5.2.2, „Server-Systemvariablen“. (Nur für
MyISAM
.)
ROW_FORMAT
Definiert, wie die Datensätze gespeichert werden sollen.
Bei MyISAM
-Tabellen kann der Optionswert
FIXED
oder DYNAMIC
für das statische wie auch das variabel lange
Datensatzformat sein. myisampack setzt
den Typ auf COMPRESSED
. Siehe auch
Abschnitt 14.1.3, „MyISAM-Tabellenformate“.
Bei InnoDB
-Tabellen werden die
Datensätze standardmäßig im kompakten Format
(ROW_FORMAT=COMPACT
) gespeichert. Das
nichtkompakte Format, welches in älteren MySQL-Versionen
verwendet wurde, kann noch über die Angabe von
ROW_FORMAT=REDUNDANT
angefordert werden.
RAID_TYPE
Die RAID
-Unterstützung wurde ab MySQL
5.0 entfernt. Informationen zu RAID
finden Sie online im MySQL-4.1-Handbuch unter
http://dev.mysql.com/doc/refman/4.1/en/create-table.html.
UNION
UNION
wird verwendet, wenn Sie auf eine
ganze Sammlung identischer
MyISAM
-Tabellen zugreifen wollen. Dies
funktioniert nur bei MERGE
-Tabellen.
Siehe auch Abschnitt 14.3, „Die MERGE
-Speicher-Engine“.
Sie benötigen die Berechtigungen SELECT
,
UPDATE
und DELETE
für
die Tabellen, um die Sammlung einer MERGE
zuordnen zu können. (Hinweis:
Ursprünglich mussten alle verwendeten Tabellen sich in der
gleichen Datenbank wie die MERGE
-Tabelle
selbst befinden. Diese Einschränkung trifft nicht mehr zu.)
INSERT_METHOD
Wenn Sie Daten in eine MERGE
-Tabelle
einfügen wollen, müssen Sie mit
INSERT_METHOD
die Tabelle festlegen, in
die der Datensatz einzufügen ist. Die Option
INSERT_METHOD
ist nur für
MERGE
-Tabellen sinnvoll. Verwenden Sie
die Werte FIRST
oder
LAST
, um die Einfügung in die erste bzw.
letzte Tabelle vorzunehmen, oder NO
, um
Einfügeoperationen ganz auszuschließen. Siehe auch
Abschnitt 14.3, „Die MERGE
-Speicher-Engine“.
DATA DIRECTORY
, INDEX
DIRECTORY
Mithilfe von DATA
DIRECTORY='
oder directory
'INDEX
DIRECTORY='
können Sie angeben, wo die
directory
'MyISAM
-Speicher-Engine die Daten- und
Indexdatei einer Tabelle ablegen soll.
directory
muss als vollständiger
Pfadname zum Verzeichnis angegeben werden; relative Pfade
sind nicht möglich.
Diese Optionen funktionieren nur, wenn Sie die Option
--skip-symbolic-links
nicht verwenden.
Außerdem muss Ihr Betriebssystem über einen
funktionsfähigen und Thread-sicheren
realpath()
-Aufruf verfügen. Weitere
Informationen finden Sie in
Abschnitt 7.6.1.2, „Benutzung symbolischer Links für Tabellen“.
Partitionierungsoptionen
(partition_options
) können zur
Steuerung der Partitionierung einer Tabelle benutzt werden,
die mit CREATE TABLE
erstellt wurde.
Sofern angegeben, muss mindestens eine PARTITION
BY
-Klausel enthalten sein. Diese Klausel enthält
die Funktion, die zur Bestimmung der Partition verwendet
wird. Die Funktion gibt einen ganzzahligen Wert zwischen 1
und num
zurück, wobei
num
die Gesamtzahl der
Partitionen ist. Die nachfolgende Liste zeigt die
Auswahlmöglichkeiten für diese Funktion in MySQL
5.1.
Wichtig: Nicht alle zu
Beginn dieses Abschnitts in der Syntax für
partition_options
aufgeführten
Optionen stehen für alle Partitionierungstypen zur
Verfügung. Entnehmen Sie den Listings für die jeweiligen
Typen die passenden Informationen. Weitere Informationen zu
Wirkungsweise und Anwendungsmöglichkeiten der
Partitionierung in MySQL sowie zusätzliche Beispiele zur
Tabellenerstellung und zu anderen partitionierungsbezogenen
Anweisungen in MySQL finden Sie in
Kapitel 17, Partitionierung.
HASH(
:
Führt ein Hashing einer oder mehrerer Spalten aus, um
einen Schlüssel zum Platzieren und Wiederauffinden von
Datensätzen zu erstellen.
expr
)expr
ist ein Ausdruck, der
eine oder mehrere Tabellenspalten verwendet. Dabei kann
es sich um einen zulässigen MySQL-Ausdruck
(einschließlich MySQL-Funktionen) handeln, der genau
einen Integer-Wert ausgibt. Die nachfolgenden
CREATE TABLE
-Anweisungen mit
PARTITION BY HASH
-Option etwa sind
alle zulässig:
CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH(col1); CREATE TABLE t1 (col1 INT, col2 CHAR(5)) PARTITION BY HASH( ORD(col2) ); CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );
VALUES LESS THAN
- und VALUES
IN
-Klauseln dürfen nicht mit
PARTITION BY HASH
gemeinsam
eingesetzt werden.
PARTITION BY HASH
verwendet den Rest
des Ausdrucks expr
geteilt
durch die Anzahl der Partitionen (d. h. den Modulo).
Beispiele und Informationen finden Sie in
Abschnitt 17.2.3, „HASH
-Partitionierung“.
Das Schlüsselwort LINEAR
bringt
einen etwas anderen Algorithmus mit sich. In diesem Fall
wird die Nummer der Partition, auf der ein Datensatz
gespeichert ist, als Ergebnis einer oder mehrerer
logischer AND
-Operationen ermittelt.
Eine Beschreibung und Beispiele für das lineare Hashing
finden Sie in
Abschnitt 17.2.3.1, „LINEAR HASH
-Partitionierung“.
KEY(
:
Dies ähnelt column_list
)HASH
, nur wird die
Hashing-Funktion hier von MySQL selbst bereitgestellt,
um eine gleichmäßige Datenverteilung zu
gewährleisten. Das Argument
column_list
ist eine einfache
Liste mit Tabellenspalten. Dieses Beispiel zeigt eine
einfache, durch einen Schlüssel partitionierte Tabelle
mit vier Partitionen:
CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY KEY(col3) PARTITIONS 4;
Bei Tabellen, die durch einen Schlüssel partitioniert
sind, können Sie die lineare Partitionierung durch
Angabe des Schlüsselworts LINEAR
benutzen. Dies hat die gleichen Auswirkungen wie bei
Tabellen, die mit HASH
partitioniert
wurden: Die Partitionsnummer wird mithilfe des Operators
&
statt über den Modulo
ermittelt (siehe auch
Abschnitt 17.2.3.1, „LINEAR HASH
-Partitionierung“, und
Abschnitt 17.2.4, „KEY
-Partitionierung“). Dieses Beispiel
verwendet die lineare Partitionierung über einen
Schlüssel, um Daten auf fünf Partitionen zu verteilen:
CREATE TABLE tk (col1 INT, col2 CHAR(5), col3 DATE) PARTITION BY LINEAR KEY(col3) PARTITIONS 5;
VALUES LESS THAN
- und VALUES
IN
-Klauseln dürfen nicht mit
PARTITION BY KEY
gemeinsam eingesetzt
werden.
RANGE
: In diesem Fall zeigt
expr
unter Verwendung einer
Menge von VALUES LESS THAN
-Operatoren
einen Wertebereich an. Wenn Sie die
Bereichspartitionierung verwenden, müssen Sie
mindestens eine Partition mit VALUES LESS
THAN
angeben. VALUES IN
können Sie bei der Bereichspartitionierung nicht
einsetzen.
VALUES LESS THAN
kann entweder mit
einem literalen Wert oder einem Ausdruck benutzt werden,
der genau einen Wert zurückgibt.
Angenommen, Sie haben eine Tabelle, die Sie nach einer Spalte partitionieren wollen, die Jahreswerte enthält. Hierbei wollen Sie das folgende Schema verwenden:
Partitionsnummer: | Jahre |
0 | 1990 und früher |
1 | 1991–1994 |
2 | 1995–1998 |
3 | 1999–2002 |
4 | 2003–2005 |
5 | 2006 und später |
Eine Tabelle, die dieses Partitionierungsschema
implementiert, kann mit der folgenden CREATE
TABLE
-Anweisung erstellt werden:
CREATE TABLE t1 ( year_col INT, some_data INT ) PARTITION BY RANGE (year_col) ( PARTITION p0 VALUES LESS THAN (1991), PARTITION p1 VALUES LESS THAN (1995), PARTITION p2 VALUES LESS THAN (1999), PARTITION p3 VALUES LESS THAN (2002), PARTITION p4 VALUES LESS THAN (2006), PARTITION p5 VALUES LESS THAN MAXVALUE );
PARTITION ... VALUES LESS THAN
...
-Anweisungen arbeiten konsekutiv, d. h.,
VALUES LESS THAN MAXVALUE
verarbeitet
die „übrig gebliebenen“ Werte, die
größer sind als der anderweitig angegebene
Maximalwert.
Beachten Sie, dass VALUES LESS
THAN
-Klauseln sequenziell auf eine Weise
verarbeitet werden, die der von
case
-Abschnitten eines
switch ... case
-Blocks ähnelt, wie
man sie aus vielen Programmiersprachen wie C, Java oder
PHP her kennt: Die Klauseln müssen so angeordnet sein,
dass der obere Grenzwert einer nachfolgenden
VALUES LESS THAN
-Klausel größer ist
als der der vorherigen Klausel; dabei muss
MAXVALUE
als Letztes in der Liste
erscheinen.
LIST(
:
Dies ist praktisch, wenn man Partitionen basierend auf
einer Tabellenspalte mit einer beschränkten Menge
möglicher Werte (z. B. Land, PLZ usw.) konfiguriert.
In einem solchen Fall lassen sich alle Datensätze, die
einem bestimmten Land oder einer PLZ zuzuordnen sind,
derselben Partition zuweisen, oder eine Partition kann
für bestimmte Länder oder Postleitzahlen reserviert
werden. Dies ähnelt expr
)RANGE
mit der
Einschränkung, dass nur VALUES IN
zur Angabe zulässiger Werte für jede Partition
verwendet werden kann.
VALUES IN
wird mit einer Liste
passender Werte benutzt. Beispielsweise könnten Sie ein
Partitionierungsschema wie das folgende erstellen:
CREATE TABLE client_firms ( id INT, name VARCHAR(35) ) PARTITION BY LIST (id) ( PARTITION r0 VALUES IN (1, 5, 9, 13, 17, 21), PARTITION r1 VALUES IN (2, 6, 10, 14, 18, 22), PARTITION r2 VALUES IN (3, 7, 11, 15, 19, 23), PARTITION r3 VALUES IN (4, 8, 12, 16, 20, 24) );
Wenn Sie die Listenpartitionierung verwenden, müssen
Sie mindestens eine Partition mit VALUES
IN
angeben. VALUES LESS
THAN
können Sie bei der Listenpartitionierung
nicht einsetzen.
Hinweis: Derzeit darf
die für VALUES IN
verwendete
Werteliste nur aus Integers bestehen.
Die Anzahl der Partitionen kann optional mit einer
PARTITIONS
-Klausel
angegeben werden, wobei num
num
die Anzahl der Partitionen ist. Werden diese Klausel
und beliebige
PARTITION
-Klauseln verwendet, muss
num
gleich der Anzahl aller
Partitionen sein, die mit
PARTITION
-Klauseln deklariert wurden.
Hinweis: Unabhängig
davon, ob Sie eine PARTITIONS
-Klausel
bei der Erstellung einer Tabelle verwenden, die mit
RANGE
oder LIST
partitioniert wurde, müssen Sie in jedem Fall
mindestens eine PARTITION
VALUES
-Klausel in der Tabellendefinition
angeben (siehe unten).
Eine Partition kann optional in eine Anzahl
Unterpartitionen aufgeteilt werden. Dies kann durch
Verwendung der optionalen Klausel SUBPARTITION
BY
angegeben werden. Die Unterpartitionierung
kann mit HASH
oder
KEY
erfolgen. Beide können
LINEAR
sein. Sie funktionieren auf
die gleiche Weise wie oben für die entsprechenden
Partitionierungstypen beschrieben. (Es ist nicht
möglich, Unterpartitionen nach LIST
oder RANGE
zu erstellen.)
Die Anzahl der Unterpartitionen kann mit dem
Schlüsselwort SUBPARTITIONS
, gefolgt
von einem Integer-Wert, angegeben werden.
Jede Partition kann individuell mit einer
partition_definition
-Klausel
definiert werden. Die einzelnen Teile, aus denen die Klausel
besteht, sind die folgenden:
PARTITION
:
Gibt einen logischen Namen für die Partition an.
partition_name
VALUES
-Klausel: Bei der
Bereichspartitionierung muss jede Partition eine
VALUES LESS THAN
-Klausel enthalten,
und bei der Listenpartitionierung müssen Sie eine
VALUES IN
-Klausel je Partition
angeben. Hiermit wird bestimmt, welche Datensätze in
dieser Partition gespeichert werden sollen. Weitere
Informationen und Syntaxinformationen entnehmen Sie der
Beschreibung der Partitionierungstypen in
Kapitel 17, Partitionierung.
Eine optionale COMMENT
-Klausel kann
zur Beschreibung der Partition angegeben werden. Der
Kommentar muss in einzelne Anführungszeichen gesetzt
werden. Beispiel:
COMMENT = 'Data for the years previous to 1999'
DATA DIRECTORY
und INDEX
DIRECTORY
können zur Angabe des
Verzeichnisses verwendet werden, in dem die Daten bzw.
die Indizes dieser Partition gespeichert werden sollen.
Sowohl
als auch
data_dir
müssen absolute Pfadnamen sein. Beispiel:
index_dir
CREATE TABLE th (id INT, name VARCHAR(30), adate DATE) PARTITION BY LIST(YEAR(adate)) ( PARTITION p1999 VALUES IN (1995, 1999, 2003) DATA DIRECTORY = '/var/appdata/95/data
' INDEX DIRECTORY = '/var/appdata/95/idx
', PARTITION p2000 VALUES IN (1996, 2000, 2004) DATA DIRECTORY = '/var/appdata/96/data
' INDEX DIRECTORY = '/var/appdata/96/idx
', PARTITION p2001 VALUES IN (1997, 2001, 2005) DATA DIRECTORY = '/var/appdata/97/data
' INDEX DIRECTORY = '/var/appdata/97/idx
', PARTITION p2000 VALUES IN (1998, 2002, 2006) DATA DIRECTORY = '/var/appdata/98/data
' INDEX DIRECTORY = '/var/appdata/98/idx
' );
DATA DIRECTORY
und INDEX
DIRECTORY
verhalten sich genauso wie in der
table_option
-Klausel einer
CREATE TABLE
-Anweisung bei
MyISAM
-Tabellen.
Je Partition können ein Daten- und ein Indexverzeichnis angegeben werden. Wenn keine Angaben gemacht werden, werden Daten und Indizes standardmäßig im MySQL-Datenverzeichnis abgelegt.
MAX_ROWS
und
MIN_ROWS
können zur Angabe der
größten bzw. kleinsten Zahl von Datensätzen verwendet
werden, die in der Partition gespeichert werden. Die
Werte für max_number_of_rows
und min_number_of_rows
müssen positive ganze Zahlen sein. Wie bei den
gleichnamigen Optionen auf Tabellenebene sind auch dies
keine festen Grenzwerte, sondern nur
„Vorschläge“ für den Server.
Die optionale TABLESPACE
-Klausel kann
zur Angabe eines Tablespaces für die Partition
verwendet werden. (Nur für MySQL Cluster.)
Die optionale [STORAGE]
ENGINE
-Klausel bewirkt, dass die Tabelle in
dieser Partition die angegebene Speicher-Engine
verwendet. Dies kann jede der vom betreffenden MySQL
Server unterstützten Engines sein. Sowohl das
Schlüsselwort STORAGE
als auch das
Gleichheitszeichen (=
) sind optional.
Wird keine partitionsspezifische Speicher-Engine mit
dieser Option angegeben, dann wird die für die gesamte
Tabelle gültige Engine auch für diese Partition
verwendet.
Hinweis: Der
Partitionierungs-Handler akzeptiert eine Option
[STORAGE] ENGINE
sowohl für
PARTITION
als auch für
SUBPARTITION
. Die derzeit einzige
Möglichkeit, diese Klausel zu nutzen, besteht darin,
alle Partitionen oder alle Unterpartitionen auf dieselbe
Speicher-Engine zu setzen. Der Versuch, verschiedene
Engines für Partitionen oder Unterpartitionen einer
Tabelle einzustellen, führt zum Fehler ERROR
1469 (HY000): The mix of handlers in the partitions is
not allowed in this version of MySQL
. Wir
beabsichtigen, diese partitionierungsbezogene
Einschränkung in einem zukünftigen Release von MySQL
5.1 zu beseitigen.
Die Option NODEGROUP
kann verwendet
werden, um diese Partition zu einem Teil der
Knotengruppe zu machen, die als
node_group_id
angegeben ist.
(Nur für MySQL Cluster.)
Die Partitionsdefinition kann optional eine oder mehrere
subpartition_definition
-Klauseln
enthalten. Jede dieser Klauseln umfasst zumindest
SUBPARTITION
, wobei
name
name
ein Bezeichner für die
Unterpartition ist. Die Syntax für eine
Unterpartitionsdefinition ist mit der einer Partition
bis auf die Tatsache identisch, dass das Schlüsselwort
PARTITION
durch
SUBPARTITION
zu ersetzen ist.
Die Unterpartitionierung muss über
HASH
oder KEY
erfolgen und kann nur bei RANGE
- oder
LIST
-Partitionen durchgeführt
werden. Siehe auch
Abschnitt 17.2.5, „Unterpartitionen“.
Partitionen können geändert, verbunden und zu Tabellen
hinzugefügt sowie aus diesen gelöscht werden. Grundlegende
Informationen zu den MySQL-Anweisungen, mit denen diese
Aufgaben erledigt werden, finden Sie in
Abschnitt 13.1.2, „ALTER TABLE
“. Detaillierte Beschreibungen
und Beispiele finden Sie in
Abschnitt 17.3, „Partitionsverwaltung“.
Sie können eine Tabelle aus einer anderen Tabelle erstellen,
indem Sie am Ende der CREATE TABLE
-Anweisung
eine SELECT
-Anweisung hinzufügen:
CREATE TABLEnew_tbl
SELECT * FROMorig_tbl
;
MySQL erstellt neue Spalten für alle Elemente in der
SELECT
-Anweisung. Zum Beispiel:
mysql>CREATE TABLE test (a INT NOT NULL AUTO_INCREMENT,
->PRIMARY KEY (a), KEY(b))
->ENGINE=MyISAM SELECT b,c FROM test2;
Hierbei wird eine MyISAM
-Tabelle mit drei
Spalten a
, b
und
c
erstellt. Beachten Sie, dass die Spalten
aus der SELECT
-Anweisung rechts an die
Tabelle angehängt und nicht in diese eingesetzt werden.
Betrachten Sie einmal das folgende Beispiel:
mysql>SELECT * FROM foo;
+---+ | n | +---+ | 1 | +---+ mysql>CREATE TABLE bar (m INT) SELECT n FROM foo;
Query OK, 1 row affected (0.02 sec) Records: 1 Duplicates: 0 Warnings: 0 mysql>SELECT * FROM bar;
+------+---+ | m | n | +------+---+ | NULL | 1 | +------+---+ 1 row in set (0.00 sec)
Für jeden Datensatz in der Tabelle foo
wird
ein Datensatz in bar
mit den Werten aus
foo
und den Standardwerten bei neuen Spalten
eingefügt.
In einer Tabelle, die mit CREATE TABLE ...
SELECT
erstellt wurde, erscheinen die Spalten, die im
CREATE TABLE
-Teil genannt werden, zuerst. Die
in beiden Teilen oder nur im SELECT
-Teil
genannten Spalten folgen nach. Der Datentyp der
SELECT
-Spalten kann außer Kraft gesetzt
werden, indem die Spalte zusätzlich im CREATE
TABLE
-Teil genannt wird.
Wenn während des Kopierens der Daten in die Tabelle Fehler auftreten, wird diese automatisch gelöscht und nicht erstellt.
CREATE TABLE ... SELECT
erstellt keine
automatischen Indizes. Dies wurde bewusst so eingerichtet, um
die Anweisung so flexibel wie möglich zu halten. Wenn Sie
wollen, dass Indizes in der Tabelle erstellt werden, müssen Sie
diese vor der SELECT
-Anweisung spezifizieren:
mysql> CREATE TABLE bar (UNIQUE (n)) SELECT n FROM foo;
Es kann dadurch zu Fällen von Datentypkonvertierung kommen. So
wird z. B. das AUTO_INCREMENT
-Attribut nicht
beibehalten, und VARCHAR
-Spalten können in
CHAR
-Spalten umgewandelt werden.
Wenn Sie eine Tabelle mit CREATE ... SELECT
erstellen, müssen Sie in jedem Fall Aliase für
Funktionsaufrufe oder Ausdrücke in der Abfrage verwenden.
Andernfalls kann die CREATE
-Anweisung
fehlschlagen, oder es können unerwünschte Spaltennamen
entstehen.
CREATE TABLE artists_and_works SELECT artist.name, COUNT(work.artist_id) AS number_of_works FROM artist LEFT JOIN work ON artist.id = work.artist_id GROUP BY artist.id;
Sie können den Typ einer erzeugten Spalte auch explizit angeben:
CREATE TABLE foo (a TINYINT NOT NULL) SELECT b+1 AS a FROM bar;
Mit LIKE
können Sie eine leere Tabelle
basierend auf der Definition einer anderen Tabelle
einschließlich aller Spaltenattribute und Indizes erstellen,
die auch in der Ursprungstabelle vorhanden sind:
CREATE TABLEnew_tbl
LIKEorig_tbl
;
CREATE TABLE ... LIKE
behält weder für die
Ursprungstabelle angegebene DATA DIRECTORY
-
und INDEX DIRECTORY
-Optionen noch
Fremdschlüsseldefinitionen bei.
Sie können dem SELECT
ein
IGNORE
oder REPLACE
voranstellen, um anzugeben, wie mit Datensätzen zu verfahren
ist, in denen Dubletten für eindeutige Schlüssel auftreten.
Bei IGNORE
werden neue Datensätze, die eine
Dublette eines eindeutigen Schlüssels für einen bereits
vorhandenen Datensatz enthalten, einfach verworfen. Wenn Sie
REPLACE
angeben, ersetzen die neuen die
vorhandenen Datensätze, die denselben eindeutigen
Schlüsselwert aufweisen. Werden weder IGNORE
noch REPLACE
angegeben, dann führt das
Auftreten von Dubletten eindeutiger Schlüssel zu einem Fehler.
Um sicherzustellen, dass das Binärlog zur Wiederherstellung der
Originaltabellen verwendet werden kann, gestattet MySQL keine
gleichzeitigen Einfügeoperationen während der Ausführung
einer CREATE TABLE ... SELECT
-Anweisung.
DROP {DATABASE | SCHEMA} [IF EXISTS] db_name
DROP DATABASE
löscht alle Tabellen in der
Datenbank und nachfolgend auch die Datenbank. Seien Sie im
Umgang mit dieser Anweisung extrem
sorgfältig! Um DROP DATABASE
verwenden zu
können, benötigen Sie die Berechtigung DROP
für die Datenbank. DROP SCHEMA
ist ein
Synonym für DROP DATABASE
.
IF EXISTS
wird verwendet, um einen Fehler
abzufangen, wenn die Datenbank nicht vorhanden ist.
Wenn Sie DROP DATABASE
für eine symbolisch
verknüpfte Datenbank verwenden, werden sowohl die Verknüpfung
als auch die Originaldatenbank gelöscht.
DROP DATABASE
gibt die Anzahl der entfernten
Tabellen zurück. Diese entspricht der Anzahl der gelöschten
.frm
-Dateien.
Die DROP DATABASE
-Anweisung entfernt jene
Dateien und Verzeichnisse, die MySQL im normalen Betrieb selbst
erstellt hat, aus dem angegebenen Datenbankverzeichnis:
Alle Dateien mit den folgenden Erweiterungen:
.BAK | .DAT | .HSH |
.MRG | .MYD | .ISD |
.MYI | .db | .frm |
Alle Unterverzeichnisse mit Namen, die aus zwei
Hexadezimalstellen
(00
-ff
) bestehen. Dies
sind Unterverzeichnisse, die für
RAID
-Tabellen verwendet werden. (Diese
Verzeichnisse werden ab MySQL 5.0 nicht entfernt, weil die
Unterstützung für RAID
-Tabellen
aufgehoben wurde. Sie sollten alle vorhandenen
RAID
-Tabellen konvertieren und diese
Verzeichnisse manuell entfernen, bevor Sie auf MySQL 5.0
oder höher aktualisieren. Weitere Informationen finden Sie
im Abschnitt zur Aktualisierung von früheren Releases auf
MySQL 5.0 im MySQL 5.0 Reference Manual, welches auf der
MySQL-Website erhältlich ist.)
Datei db.opt
(sofern vorhanden).
Wenn andere Dateien oder Verzeichnisse im Datenbankverzeichnis
zurückbleiben, nachdem MySQL die genannten Elemente entfernt
hat, kann das Datenbankverzeichnis nicht gelöscht werden. In
diesem Fall müssen Sie alle verbleibenden Dateien oder
Verzeichnisse manuell entfernen und die DROP
DATABASE
-Anweisung nachfolgend erneut absetzen.
Sie können Datenbanken auch mit mysqladmin löschen. Siehe auch Abschnitt 8.7, „mysqladmin — Client für die Verwaltung eines MySQL Servers“.
DROP INDEXindex_name
ONtbl_name
DROP INDEX
löscht den Index namens
index_name
aus der Tabelle
tbl_name
. Diese Anweisung wird einer
ALTER TABLE
-Anweisung zugewiesen, die den
Index löscht. Siehe auch Abschnitt 13.1.2, „ALTER TABLE
“.
DROP [TEMPORARY] TABLE [IF EXISTS]tbl_name
[,tbl_name
] ... [RESTRICT | CASCADE]
DROP TABLE
löscht eine oder mehrere
Tabellen. Für jede Tabelle benötigen Sie die Berechtigung
DROP
. Alle Tabellendaten und die
Tabellendefinition werden entfernt! Seien
Sie also auch im Umgang mit dieser Anweisung sehr
vorsichtig!
Beachten Sie, dass DROP TABLE
bei einer
partitionierten Tabelle die Tabellendefinition, alle Partitionen
und alle in diesen Partitionen gespeicherten Daten permanent
entfernt. Ebenso gelöscht wird die
Partitionierungsdefinitiondatei (.par
) der
gelöschten Tabelle.
Verwenden Sie IF EXISTS
, um einen Fehler bei
Tabellen abzufangen, die nicht vorhanden sind. Für jede nicht
vorhandene Tabelle wird ein Hinweis erzeugt, wenn Sie
IF EXISTS
benutzen. Siehe auch
Abschnitt 13.5.4.25, „SHOW WARNINGS
“.
RESTRICT
und CASCADE
erlauben eine leichtere Portierung. Derzeit haben sie aber keine
Funktion.
Hinweis: DROP
TABLE
übergibt die derzeit aktive Transaktion sofort,
sofern Sie nicht das Schlüsselwort TEMPORARY
benutzen.
Das Schlüsselwort TEMPORARY
hat die
folgenden Auswirkungen:
Die Anweisung löscht nur Temporärtabellen.
Die Anweisung beendet keine laufende Transaktion.
Zugriffsrechte werden nicht geprüft. (Eine Temporärtabelle ist nur für den Client sichtbar, der sie erstellt hat; insofern ist eine Überprüfung unnötig.)
Die Verwendung von TEMPORARY
ist eine gute
Möglichkeit, sicherzustellen, dass Sie nicht versehentlich eine
nichttemporäre Tabelle löschen.
RENAME TABLEtbl_name
TOnew_tbl_name
[,tbl_name2
TOnew_tbl_name2
] ...
Mit dieser Anweisung werden eine oder mehrere Tabellen umbenannt.
Der Umbenennungsvorgang erfolgt automatisch, d. h., kein
anderer Thread kann währenddessen auf die umzubenennende(n)
Tabelle(n) zugreifen. Wenn Sie beispielsweise eine Tabelle
old_table
haben, können Sie eine andere
Tabelle new_table
erstellen, die dieselbe
Struktur hat, aber leer ist, und die vorhandene Tabelle dann wie
folgt durch die leere Tabelle ersetzen (sofern
backup_table
nicht bereits vorhanden ist):
CREATE TABLE new_table (...); RENAME TABLE old_table TO backup_table, new_table TO old_table;
Wenn die Anweisung mehrere Tabellen umbenennt, erfolgen die
Umbenennungen von links nach rechts. Wollen Sie zwei
Tabellennamen gegeneinander austauschen, dann können Sie dies
wie folgt tun (sofern tmp_table
nicht bereits
vorhanden ist):
RENAME TABLE old_table TO tmp_table, new_table TO old_table, tmp_table TO new_table;
Solange zwei Datenbanken sich im selben Dateisystem befinden,
können Sie mit RENAME TABLE
auch eine
Tabelle von einer Datenbank in eine andere verschieben:
RENAME TABLEcurrent_db.tbl_name
TOother_db.tbl_name;
RENAME TABLE
funktioniert auch bei Views,
solange Sie nicht versuchen, einen View in einer anderen
Datenbank umzubenennen.
Wenn Sie RENAME
ausführen, dürfen keine
Tabellen gesperrt und keine Transaktionen aktiv sein. Sie
benötigen für die Ursprungstabelle ferner die Berechtigungen
ALTER
und DROP
sowie die
Berechtigungen CREATE
und
INSERT
für die neue Tabelle.
Wenn MySQL in einer tabellenübergreifenden Umbenennungsaktion auf Fehler trifft, wird für alle umbenannten Tabellen eine umgekehrte Umbenennung durchgeführt, um den ursprünglichen Zustand wiederherzustellen.
Syntax für eine Tabelle:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
Syntax für mehrere Tabellen:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE]tbl_name
[.*] [,tbl_name
[.*]] ... FROMtable_references
[WHEREwhere_condition
]
Oder:
DELETE [LOW_PRIORITY] [QUICK] [IGNORE] FROMtbl_name
[.*] [,tbl_name
[.*]] ... USINGtable_references
[WHEREwhere_condition
]
Bei der Ein-Tabellen-Syntax löscht die
DELETE
-Anweisung Datensätze aus
tbl_name
und gibt die Anzahl
gelöschter Datensätze zurück. Sofern angegeben, bestimmt die
WHERE
-Klausel die Bedingungen dafür, welche
Datensätze gelöscht werden. Ohne
WHERE
-Klausel werden alle Datensätze
gelöscht. Wenn die ORDER BY
-Klausel
vorhanden ist, werden die Datensätze in der angegebenen
Reihenfolge gelöscht. Die LIMIT
-Klausel kann
die Anzahl der zu löschenden Datensätze beschränken.
Bei der Mehrtabellensyntax löscht DELETE
aus
jeder Tabelle tbl_name
die
Datensätze, die die Bedingungen erfüllen. In diesem Fall
können ORDER BY
und LIMIT
nicht verwendet werden.
where_condition
ist ein Ausdruck, der
für jeden zu löschenden Datensatz wahr ist. Er wird wie in
Abschnitt 13.2.7, „SELECT
“, beschrieben angegeben.
Wie bereits gesagt, löscht eine
DELETE
-Anweisung ohne
WHERE
-Klausel alle Datensätze. Wenn Sie die
Anzahl der gelöschten Datensätze nicht kennen müssen, können
Sie dies schneller mit TRUNCATE TABLE
erledigen. Siehe auch Abschnitt 13.2.9, „TRUNCATE
“.
Wenn Sie den Datensatz entfernen, der den höchsten Wert für
eine AUTO_INCREMENT
-Spalte hat, dann wird der
Wert bei BDB
-Tabellen später
wiederverwendet, nicht jedoch bei MyISAM
-
oder InnoDB
-Tabellen. Wenn Sie im
AUTOCOMMIT
-Modus alle Datensätze in der
Tabelle mit DELETE FROM
(ohne
tbl_name
WHERE
-Klausel) löschen, beginnt die Sequenz
für alle Speicher-Engines mit Ausnahme von
InnoDB
und MyISAM
neu. Bei
InnoDB
-Tabellen gibt es bezüglich dieses
Verhaltens ein paar Ausnahmen, die in
Abschnitt 14.2.6.3, „Wie eine Auto-Increment-Spalte in InnoDB funktioniert“, beschrieben
sind.
Bei MyISAM
- und
BDB
-Tabellen können Sie
AUTO_INCREMENT
in einer Sekundärspalte eines
mehrspaltigen Schlüssels angeben. In diesem Fall werden Werte,
die am Anfang der Sequenz gelöscht wurden, auch bei
MyISAM
-Tabellen wiederverwendet. Siehe auch
Abschnitt 3.6.9, „Verwendung von AUTO_INCREMENT
“.
Die DELETE
-Anweisung unterstützt die
folgenden Modifizierer:
Wenn Sie LOW_PRIORITY
angeben, verzögert
der Server die Ausführung von DELETE
,
bis kein Client mehr aus der Tabelle liest.
Wenn Sie bei MyISAM
-Tabellen das
Schlüsselwort QUICK
angeben, fasst die
Speicher-Engine beim Löschen Indexzweige nicht zusammen.
Dies kann bestimmte Arten von Löschvorgängen
beschleunigen.
Das Schlüsselwort IGNORE
bewirkt, dass
MySQL alle Fehler während des Vorgangs der
Datensatzlöschung ignoriert. (Fehler, die bei der Analyse
auftreten, werden allerdings wie gewöhnlich verarbeitet.)
Fehler, die aufgrund der Verwendung von
OPTION
ignoriert werden, werden als
Warnungen zurückgegeben.
Die Geschwindigkeit von Löschoperationen kann auch von den
Faktoren beeinflusst werden, die in
Abschnitt 7.2.18, „Geschwindigkeit von DELETE
-Anfragen“, beschrieben werden.
Bei MyISAM
-Tabellen werden gelöschte
Datensätze zu einer verknüpften Liste hinzugefügt.
Nachfolgende INSERT
-Operationen verwenden die
alten Datensatzpositionen neu. Um ungenutzten Speicher wieder
freizugeben und die Dateigrößen zu verringern, verwenden Sie
die OPTIMIZE TABLE
-Anweisung oder das
Hilfsprogramm myisamchk zur Reorganisierung
der Tabellen. OPTIMIZE TABLE
ist einfacher,
myisamchk hingegen schneller. Siehe auch
Abschnitt 13.5.2.5, „OPTIMIZE TABLE
“, und
Abschnitt 8.2, „myisamchk — Hilfsprogramm für die Tabellenwartung von MyISAM“.
Der Modifizierer QUICK
bestimmt, ob
Indexzweige bei Löschoperationen zusammengefasst werden.
DELETE QUICK
ist am nützlichsten bei
Anwendungen, bei denen Indexwerte für gelöschte Datensätze
durch ähnliche Indexwerte von später eingefügten Datensätzen
ersetzt werden. In diesem Fall werden die von den gelöschten
Werten zurückgelassenen Löcher wiederverwendet.
DELETE QUICK
ist hingegen nicht nützlich,
wenn gelöschte Werte nicht aufgefüllte Indexblöcke zur Folge
haben, die einen Bereich von Indexwerten umfassen, bei denen
neue Einfügeoperationen auftreten. In diesem Fall kann die
Verwendung von QUICK
zur Verschwendung von
Speicher im Index führen, da dieser Speicher nicht mehr
freigegeben wird. Hier ein Beispiel für ein solches Szenario:
Erstellen Sie eine Tabelle, die eine indizierte
AUTO_INCREMENT
-Spalte enthält.
Fügen Sie viele Datensätze in diese Tabelle ein. Jede Einfügeoperation führt dazu, dass ein Indexwert am Ende des Indexes eingefügt wird.
Löschen Sie mit DELETE QUICK
einen Block
mit Datensätzen vorne im Spaltenbereich.
In diesem Szenario werden die Indexblöcke, die mit den
gelöschten Indexwerten verknüpft sind, nicht aufgefüllt, aber
aufgrund der Verwendung von QUICK
auch nicht
mit anderen Indexblöcken zusammengefasst. Sie bleiben also
unaufgefüllt, wenn weitere Einfügeoperationen auftreten, weil
die neuen Datensätze keine Indexwerte im gelöschten Bereich
haben. Außerdem bleiben sie auch dann unaufgefüllt, wenn Sie
später DELETE
ohne QUICK
verwenden, sofern nicht zufällig einige der gelöschten
Indexwerte in Indexblöcken innerhalb oder neben den nicht
aufgefüllten Blöcken liegen. Um ungenutzten Indexspeicher
unter diesen Umständen wieder freizugeben, verwenden Sie
OPTIMIZE TABLE
.
Wenn Sie viele Datensätze aus einer Tabelle zu löschen
beabsichtigen, kann DELETE QUICK
gefolgt von
OPTIMIZE TABLE
die schnellere Lösung sein.
Hierbei wird der Index neu erstellt, statt zahlreiche
Zusammenfassungsoperationen für Indexblöcke auszuführen.
Die MySQL-spezifische Option LIMIT
für
row_count
DELETE
nennt dem Server die maximale Anzahl
Datensätze, die gelöscht werden, bevor die Kontrolle an den
Client zurückgegeben wird. Hiermit können Sie gewährleisten,
dass eine gegebene DELETE
-Anweisung nicht zu
viel Zeit in Anspruch nimmt. Sie können die
DELETE
-Anweisung dann einfach wiederholen,
bis die Gesamtzahl betroffener Datensätze kleiner ist als der
LIMIT
-Wert.
Wenn die DELETE
-Anweisung eine ORDER
BY
-Klausel enthält, werden die Datensätze in der in
der Klausel angegebenen Reihenfolge gelöscht. Dies ist nur in
Verbindung mit LIMIT
wirklich nützlich. Die
folgende Anweisung beispielsweise findet Datensätze, die der
WHERE
-Klausel entsprechen, sortiert sie nach
timestamp_column
und löscht den ersten
(d. h. ältesten) Datensatz:
DELETE FROM somelog WHERE user = 'jcole' ORDER BY timestamp_column LIMIT 1;
Sie können in einer DELETE
-Anweisung mehrere
Tabellen angeben, aus denen je nach Bedingung der
WHERE
-Klausel Datensätze gelöscht werden.
Allerdings können Sie ORDER BY
oder
LIMIT
nicht in einer
DELETE
-Anweisung für mehrere Tabellen
verwenden. Die Klausel
table_references
listet die Tabellen
auf, die im Join berücksichtigt werden. Die Syntax ist in
Abschnitt 13.2.7.1, „JOIN
“, beschrieben.
Bei der ersten Mehrtabellensyntax werden nur passende
Datensätze aus den Tabellen gelöscht, die vor der
FROM
-Klausel aufgelistet sind. Bei der
zweiten Mehrtabellensyntax werden nur passende Datensätze aus
den Tabellen gelöscht, die in der
FROM
-Klausel (vor der
USING
-Klausel) aufgelistet sind. Die Folge
ist, dass Sie Datensätze aus vielen Tabellen gleichzeitig
löschen und gleichzeitig in weiteren Tabellen nur suchen lassen
können:
DELETE t1, t2 FROM t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
Oder:
DELETE FROM t1, t2 USING t1, t2, t3 WHERE t1.id=t2.id AND t2.id=t3.id;
Diese Anweisungen verwenden auf der Suche nach zu löschenden
Datensätzen alle drei Tabellen, aber gelöscht werden passende
Datensätze tatsächlich nur aus den Tabellen
t1
und t2
.
Die obigen Beispiele zeigen innere Joins, die den Kommaoperator
verwenden. DELETE
-Anweisungen für mehrere
Tabellen können jedoch einen beliebigen Join-Typ verwenden, der
für SELECT
-Anweisungen zulässig ist, also
etwa LEFT JOIN
.
Die Syntax erlaubt .*
nach den Tabellennamen,
um die Kompatibilität mit Access zu gewährleisten.
Wenn Sie eine DELETE
-Anweisung für mehrere
Tabellen verwenden, die auch InnoDB
-Tabellen
einbezieht, für die Fremdschlüssel-Constraints vorhanden sind,
dann verarbeitet der MySQL-Optimierer die Tabellen unter
Umständen in einer Reihenfolge, die sich von der ihrer
Parent/Child-Beziehung unterscheidet. In diesem Fall schlägt
die Anweisung fehl, und es wird ein Rollback durchgeführt.
Stattdessen sollten Sie die Löschoperation dann aus nur einer
Tabelle durchführen und sich auf die ON
DELETE
-Funktionalität verlassen, die
InnoDB
bietet, um andere Tabellen
entsprechend zu ändern.
Hinweis: Wenn Sie einen Alias für eine Tabelle angegeben haben, müssen Sie diesen bei der Referenzierung der Tabelle verwenden:
DELETE t1 FROM test AS t1, test2 WHERE ...
Datenbankübergreifende Löschvorgänge werden von Löschvorgängen für mehrere Tabellen unterstützt. In diesem Fall müssen Sie die Tabellen aber ohne Verwendung von Aliasen referenzieren. Zum Beispiel:
DELETE test1.tmp1, test2.tmp2 FROM test1.tmp1, test2.tmp2 WHERE ...
Zurzeit können Sie in einer Unterabfrage keine Löschoperation in einer Tabelle durchführen und gleichzeitig eine Auswahl in einer anderen Tabelle treffen.
DOexpr
[,expr
] ...
DO
führt Ausdrücke aus, gibt aber keine
Ergebnisse zurück. In den meisten Fällen ist
DO
eine Kurzform von SELECT
, hat aber den
Vorteil, dass es etwas schneller ist, sofern das Ergebnis für
Sie keine Rolle spielt. Allerdings meldet expr
, ...DO
keine Fehler. Stattdessen werden Fehler als Warnungen
ausgegeben.
DO
ist in erster Linie bei Funktionen
praktisch, die Begleiterscheinungen haben (z. B.
RELEASE_LOCK()
).
HANDLERtbl_name
OPEN [ ASalias
] HANDLERtbl_name
READindex_name
{ = | >= | <= | < } (value1
,value2
,...) [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
READindex_name
{ FIRST | NEXT | PREV | LAST } [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
READ { FIRST | NEXT } [ WHEREwhere_condition
] [LIMIT ... ] HANDLERtbl_name
CLOSE
Die Anweisung HANDLER
bietet direkten Zugriff
auf die Schnittstellen der Speicher-Engine einer Tabelle. Sie
steht für MyISAM
- und
InnoDB
-Tabellen zur Verfügung.
Die Anweisung HANDLER ... OPEN
öffnet eine
Tabelle und gestattet den Zugriff über nachfolgende
HANDLER ... READ
-Anweisungen. Dieses
Tabellenobjekt wird nicht mit anderen Threads gemeinsam genutzt
und wird erst geschlossen, wenn der Thread HANDLER ...
CLOSE
aufruft oder beendet wird. Wenn Sie die Tabelle
unter Verwendung eines Alias öffnen, müssen nachfolgende
Referenzierungen durch andere
HANDLER
-Anweisungen den Alias statt des
Tabellennamens verwenden.
Die erste HANDLER ... READ
-Syntax holt einen
Datensatz, bei dem der angegebene Index den übergebenen Werten
entspricht und die WHERE
-Bedingung erfüllt
ist. Wenn Sie einen mehrspaltigen Index haben, geben Sie die
Indexspaltenwerte als kommagetrennte Liste an. Entweder geben
Sie Werte für alle Spalten im Index oder aber Werte für das
links stehende Präfix der Indexspalten an. Angenommen, ein
Index my_idx
enthält drei Spalten namens
col_a
, col_b
und
col_c
in genau dieser Reihenfolge. Die
Anweisung HANDLER
kann Werte für alle drei
Spalten im Index oder für die Spalten in einem links stehenden
Präfix angeben. Zum Beispiel:
HANDLER ... READ my_idx = (col_a_val,col_b_val,col_c_val) ... HANDLER ... READ my_idx = (col_a_val,col_b_val) ... HANDLER ... READ my_idx = (col_a_val) ...
Um die HANDLER
-Schnittstelle für die
Referenzierung des Primärschlüssels einer Tabelle zu
verwenden, setzen Sie den Bezeichner in Anführungszeichen
(`PRIMARY`
).
HANDLER tbl_name
READ `PRIMARY` ...
Die zweite HANDLER ... READ
-Syntax holt aus
der Tabelle einen Datensatz in der Indexreihenfolge, die der
WHERE
-Bedingung entspricht.
Die dritte HANDLER ... READ
-Syntax holt aus
der Tabelle einen Datensatz in der natürlichen
Datensatzreihenfolge, die der WHERE
-Bedingung
entspricht. Sie ist schneller als HANDLER
, wenn ein
vollständiger Tabellenscan gewünscht wird. Die natürliche
Datensatzreihenfolge ist die Reihenfolge, in der die Datensätze
in der Datendatei einer tbl_name
READ
index_name
MyISAM
-Tabelle
gespeichert sind. Diese Anweisung funktioniert auch bei
InnoDB
-Tabellen, aber das Konzept greift hier
in Ermangelung einer separaten Datendatei nicht.
Ohne eine LIMIT
-Klausel holen alle Formen von
HANDLER ... READ
einen einzelnen Datensatz
(sofern vorhanden). Um eine bestimmte Anzahl Datensätze
zurückzugeben, fügen Sie eine LIMIT
-Klausel
ein. Sie hat dieselbe Syntax wie bei der
SELECT
-Anweisung. Siehe auch
Abschnitt 13.2.7, „SELECT
“.
HANDLER ... CLOSE
schließt eine Tabelle, die
mit HANDLER ... OPEN
geöffnet worden war.
HANDLER
ist eine etwas maschinennahe
Anweisung. Sie bietet z. B. keine Konsistenz: HANDLER
... OPEN
fertigt keine
Momentaufnahme der Tabelle an und sperrt sie
nicht. Das bedeutet, dass, nachdem eine
HANDLER ... OPEN
-Anweisung abgesetzt wurde,
die Tabellendaten (vom aktuellen, aber auch von anderen Threads)
modifiziert werden können und diese Änderungen dann für
HANDLER ... NEXT
- oder HANDLER ...
PREV
-Scans unter Umständen nur teilweise sichtbar
sind.
Es gibt eine Reihe von Gründen zur Verwendung der
HANDLER
-Schnittstelle anstelle einer normalen
SELECT
-Anweisung:
HANDLER
ist schneller als
SELECT
:
Für HANDLER ... OPEN
wird ein
dediziertes Speicher-Engine-spezifisches Handler-Objekt
reserviert. Das Objekt wird bei nachfolgenden
HANDLER
-Anweisungen für diese
Tabelle wiederverwendet; es muss nicht jeweils neu
initialisiert werden.
Der Analyseaufwand ist geringer.
Es ist kein zusätzlicher Aufwand für den Optimierer oder die Abfrageüberprüfung erforderlich.
Die Tabelle muss nicht zwischen zwei Handler-Anforderungen gesperrt werden.
Die Handler-Schnittstelle muss keine konsistente Sicht
der Daten bieten (Dirty Reads beispielsweise sind
zulässig) – die Speicher-Engine kann also
Optimierungen verwenden, die SELECT
normalerweise nicht zulassen würde.
Bei Anwendungen, die eine maschinennahe
ISAM
-artige Schnittstelle verwenden,
erleichtert HANDLER
deren Portierung auf
MySQL.
HANDLER
erlaubt Ihnen das Durchlaufen
einer Datenbank auf eine Weise, die mit
SELECT
– wenn überhaupt – nur sehr
schwierig zu realisieren ist. Die
HANDLER
-Schnittstelle ist eine
natürlicher anmutende Art der Datensicht, wenn Sie mit
Anwendungen arbeiten, die eine interaktive
Benutzeroberfläche für die Datenbank bereitstellen.
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[(col_name
,...)] VALUES ({expr
| DEFAULT},...),(...),... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
Oder:
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
SETcol_name
={expr
| DEFAULT}, ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
Oder:
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[(col_name
,...)] SELECT ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
INSERT
fügt neue Datensätze in eine
vorhandene Tabelle ein. Die Formen INSERT ...
VALUES
und INSERT ... SET
der
Anweisung fügen Datensätze basierend auf explizit angegebenen
Werten ein. Die Form INSERT ... SELECT
fügt
Datensätze ein, die in einer oder mehreren anderen Tabellen
ausgewählt wurden. INSERT ... SELECT
wird in
Abschnitt 13.2.4.1, „INSERT ... SELECT
“, näher erläutert.
Sie können REPLACE
anstelle von
INSERT
verwenden, um alte Datensätze zu
überschreiben. REPLACE
ist das Gegenstück
zu INSERT IGNORE
bei der Behandlung neuer
Datensätze, deren eindeutige Schlüsselwerte Dubletten bereits
vorhandener Datensätze sind: Die neuen Datensätze ersetzen die
alten, statt verworfen zu werden. Siehe auch
Abschnitt 13.2.6, „REPLACE
“.
tbl_name
ist die Tabelle, in die die
Datensätze eingefügt werden sollen. Die Spalten, für die die
Anweisung Werte angibt, lassen sich wie folgt angeben:
Sie können eine kommagetrennte Liste von Spaltennamen
gefolgt vom Tabellennamen angeben. In diesem Fall muss für
jede genannte Spalte in der VALUES
-Liste
oder der SELECT
-Anweisung ein Wert
vorhanden sein.
Wenn Sie keine Liste mit Spaltennamen für INSERT
... VALUES
oder INSERT ...
SELECT
angeben, dann müssen die Werte für alle
Spalten in der Tabelle in der
VALUES
-Liste oder der
SELECT
-Anweisung vorhanden sein. Wenn Sie
die Reihenfolge der Spalten in der Tabelle nicht kennen,
ermitteln Sie sie mit DESCRIBE
.
tbl_name
Die SET
-Klausel gibt die Spaltennamen
ausdrücklich an.
Spaltenwerte lassen sich auf mehrerlei Weise übergeben:
Wenn Sie MySQL nicht im strikten SQL-Modus ausführen, dann wird jede Spalte, für die kein Wert angegeben wird, auf den (expliziten oder impliziten) Standardwert gesetzt. Wenn Sie also etwa eine Spaltenliste angeben, die nicht alle Spalten in der Tabelle aufführt, werden nicht genannte Spalten auf ihre jeweiligen Standardwerte gesetzt. Die Zuweisung von Standardwerten ist in Abschnitt 11.1.4, „Vorgabewerte von Datentypen“, beschrieben. Siehe auch Abschnitt 1.9.6.2, „Constraints auf ungültigen Daten“.
Wenn Sie wollen, dass eine
INSERT
-Anweisung einen Fehler erzeugt,
wenn Sie nicht alle Werte für alle Spalten ausdrücklich
angeben, für die kein Standardwert vorhanden ist, dann
sollten Sie den strikten Modus verwenden. Siehe auch
Abschnitt 5.2.5, „Der SQL-Modus des Servers“.
Mit dem Schlüsselwort DEFAULT
können
Sie eine Spalte explizit auf ihren Standardwert setzen. Dies
erleichtert das Formulieren von
INSERT
-Anweisungen, die allen Spalten
(bis auf einigen wenigen) Werte zuweisen, denn so brauchen
Sie keine unvollständige VALUES
-Liste zu
erstellen, die nicht für jede Spalte in der Tabelle einen
Wert enthält. Andernfalls müssten Sie die Liste der
Spaltennamen ausschreiben, die den einzelnen Werten in der
VALUES
-Liste entspricht.
Sie können auch
DEFAULT(
als eine allgemeinere Form benutzen, mit der in Ausdrücken
der Standardwert einer gegebenen Spalte erzeugt werden kann.
col_name
)
Wenn sowohl die Spaltenliste als auch die
VALUES
-Liste leer sind, erstellt
INSERT
einen Datensatz, bei dem jede
Spalte auf den jeweiligen Standardwert gesetzt ist:
INSERT INTO tbl_name
() VALUES();
Im strikten Modus tritt ein Fehler auf, wenn nicht für jede Spalte ein Standardwert angegeben ist. Andernfalls verwendet MySQL den impliziten Standardwert für jede Spalte, der kein expliziter Wert zugewiesen ist.
Sie können den Spaltenwert auch durch einen Ausdruck
expr
angeben. Dies kann eine
Typenkonvertierung bedingen, wenn der Ausdruckstyp nicht dem
Typ der Spalte entspricht. Die Konvertierung eines gegebenen
Werts kann je nach Datentyp zu unterschiedlichen
Einfügewerten führen. So hat z. B. das Einfügen des
Strings '1999.0e-2'
in eine
INT
-. FLOAT
-,
DECIMAL(10,6)
- oder
YEAR
-Spalte die Einfügewerte
1999
, 19.9921
,
19.992100
bzw. 1999
zur Folge. Der Grund dafür, dass der in den
INT
- und YEAR
-Spalten
gespeicherte Wert 1999
ist, besteht
darin, dass bei der Konvertierung des Strings in den Integer
nur der Teil des Strings berücksichtigt wird, der als
gültiger Integer bzw. als sinnvolle Jahresangabe betrachtet
wird. Bei Fließkomma- und Festkommaspalten wird bei der
Umwandlung des Strings in einen Fließkommawert der gesamte
String als zulässiger Fließkommawert betrachtet.
Ein Ausdruck expr
kann jede
Spalte referenzieren, die zuvor in einer Werteliste
eingestellt wurde. Sie könnten dies beispielsweise tun,
weil der Wert von col2
die zuvor
zugewiesene Spalte col1
referenziert:
INSERT INTO tbl_name
(col1,col2) VALUES(15,col1*2);
Die folgende Variante ist jedoch nicht zulässig, weil der
Wert für col1
die Spalte
col2
referenziert, die jedoch erst nach
col1
zugewiesen wurde:
INSERT INTO tbl_name
(col1,col2) VALUES(col2*2,15);
Eine Ausnahme betrifft Spalten, die
AUTO_INCREMENT
-Werte enthalten. Weil der
AUTO_INCREMENT
-Wert nach anderen
Wertezuweisungen erzeugt wird, gibt eine Referenzierung
einer AUTO_INCREMENT
-Spalte
0
zurück.
INSERT
-Anweisungen, die die
VALUES
-Syntax verwenden, können mehrere
Datensätze einfügen. Zu diesem Zweck fügen Sie mehrere Listen
mit Spaltenwerten ein, die jeweils in Klammern gesetzt und durch
Kommata getrennt sind. Beispiel:
INSERT INTO tbl_name
(a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Die Werteliste für jeden Datensatz muss in Klammern gesetzt werden. Die folgende Anweisung ist unzulässig, weil die Anzahl der Werte in der Liste nicht der Anzahl der Spaltennamen entspricht:
INSERT INTO tbl_name
(a,b,c) VALUES(1,2,3,4,5,6,7,8,9);
Der Wert der von einer INSERT
-Anweisung
betroffenen Datensätze kann mit der C-API-Funktion
mysql_affected_rows()
ermittelt werden. Siehe
auch Abschnitt 24.2.3.1, „mysql_affected_rows()
“.
Wenn Sie eine INSERT ... VALUES
-Anweisung mit
mehreren Wertelisten oder INSERT ... SELECT
verwenden, gibt die Anweisung einen Informations-String im
folgenden Format zurück:
Records: 100 Duplicates: 0 Warnings: 0
Records
gibt die Anzahl der von der Anweisung
verarbeiteten Datensätze zurück. (Dies entspricht nicht
unbedingt der Anzahl der tatsächlich eingefügten Datensätze,
weil Duplicates
auch ungleich null sein
kann.) Duplicates
gibt die Anzahl der
Datensätze an, die nicht eingefügt wurden, weil eindeutige
Schlüsselwerte andernfalls dupliziert worden wären.
Warnings
gibt die Anzahl der
Spalteneinfügeversuche an, die aus irgendeinem Grund
problematisch waren. Warnungen können unter den folgenden
Umständen auftreten:
Einfügen von NULL
in eine Spalte, die
als NOT NULL
deklariert wurde. Bei
INSERT
-Anweisung für mehrere Datensätze
oder INSERT INTO ... SELECT
-Anweisungen
wird die Spalte auf den impliziten Standardwert für den
betreffenden Spaltendatentyp gesetzt. Bei numerischen Typen
ist dies 0
, bei String-Typen der
Leer-String (''
) und der
„Nullwert“ bei Datums- und Uhrzeittypen.
INSERT INTO ... SELECT
-Anweisungen werden
auf die gleiche Weise behandelt wie Einfügeoperationen für
mehrere Datensätze, weil der Server die Ergebnismenge von
SELECT
nicht darauf überprüft, ob genau
ein Datensatz zurückgegeben wird. (Bei
INSERT
-Anweisungen für nur einen
Datensatz erscheint keine Warnung, wenn
NULL
in eine NOT
NULL
-Spalte eingefügt wird. Stattdessen schlägt
die Anweisung mit einem Fehler fehl.)
Setzen einer numerischen Spalte auf einen Wert außerhalb des zulässigen Wertebereichs. Der Wert wird auf den nächstgelegenen Endpunkt des Bereichs gesetzt.
Zuweisen eines Werts wie '10.34 a'
zu
einer numerischen Spalte. Der nichtnumerische Text am Ende
wird entfernt, und der verbleibende numerische Teil wird
eingefügt. Hat der String-Wert am Anfang keinen numerischen
Teil, dann wird die Spalte auf 0
gesetzt.
Einfügen eines Strings in eine String-Spalte
(CHAR
, VARCHAR
,
TEXT
oder BLOB
), die
die maximale Länge der Spalte überschreitet. Der Wert wird
auf die zulässige Maximallänge der Spalte gekürzt.
Einfügen eines Werts in eine Spalte für Datum oder Uhrzeit, der für diesen Datentyp nicht zulässig ist. Die Spalte wird auf den passenden Nullwert des Typs gesetzt.
Wenn Sie die C-API verwenden, kann der Informations-String durch
Aufruf der Funktion mysql_info()
ermittelt
werden. Siehe auch Abschnitt 24.2.3.34, „mysql_info()
“.
Wenn INSERT
einen Datensatz in eine Tabelle
einfügt, die eine AUTO_INCREMENT
-Spalte
enthält, dann können Sie den Wert dieser Spalte mithilfe der
SQL-Funktion LAST_INSERT_ID()
abfragen. Aus
der C-API heraus verwenden Sie die Funktion
mysql_insert_id()
. Sie sollten allerdings
beachten, dass die beiden Funktionen sich nicht immer identisch
verhalten. Das Verhalten von
INSERT
-Anweisungen in Bezug auf
AUTO_INCREMENT
-Spalten wird in
Abschnitt 12.10.3, „Informationsfunktionen“, und
Abschnitt 24.2.3.36, „mysql_insert_id()
“, ausführlicher beschrieben.
Die INSERT
-Anweisung unterstützt die
folgenden Modifizierer:
Wenn Sie das Schlüsselwort DELAYED
verwenden, legt der Server den oder die einzufügenden
Datensätze in einem Puffer ab, und der Client, der die
INSERT DELAYED
-Anweisung abgesetzt hat,
kann sofort weiterarbeiten. Wird die Tabelle gerade
verwendet, dann hält der Server die Datensätze zurück.
Sobald die Tabelle frei ist, startet der Server mit dem
Einfügen der Datensätze und prüft dabei periodisch, ob
neue Leseanforderungen für die Tabelle anstehen. In diesem
Fall wird die Warteschlange mit den verzögerten
Datensätzen angehalten, bis die Tabelle wieder frei wird.
Siehe auch Abschnitt 13.2.4.2, „INSERT DELAYED
“.
DELAYED
wird bei INSERT ...
SELECT
oder INSERT ... ON DUPLICATE KEY
UPDATE
ignoriert.
Wenn Sie das Schlüsselwort LOW_PRIORITY
angeben, wird die Ausführung von INSERT
verzögert, bis kein Client mehr aus der Tabelle liest. Dies
schließt andere Clients mit ein, die Leseoperationen
starten, während bereits vorhandene Clients aus der Tabelle
lesen und die INSERT
LOW_PRIORITY
-Anweisung wartet. Aus diesem Grund
ist es möglich, dass ein Client, der eine INSERT
LOW_PRIORITY
-Anweisung absetzt, sehr lange warten
muss – in Umgebungen mit extrem hohen Aufkommen von
Leseoperationen sogar für immer. (Dies steht im Gegensatz
zu INSERT DELAYED
, wo der Client direkt
fortfahren kann.) Beachten Sie, dass
LOW_PRIORITY
normalerweise nicht bei
MyISAM
-Tabellen benutzt werden sollte, da
auf diese Weise gleichzeitige Einfügeoperationen unmöglich
gemacht werden. Siehe auch
Abschnitt 7.3.3, „Gleichzeitige Einfügevorgänge“.
Wenn Sie HIGH_PRIORITY
angeben, setzt es
die Auswirkungen der Option
--low-priority-updates
außer Kraft, sofern
der Server mit dieser Option gestartet worden war. Außerdem
sind auch hier gleichzeitige Einfügeoperationen nicht
möglich.
Wenn Sie das Schlüsselwort IGNORE
angeben, werden Fehler, die während der Ausführung der
INSERT
-Anweisung auftreten, als Warnungen
behandelt. So würde beispielsweise ohne
IGNORE
ein Datensatz, der einen
vorhandenen eindeutigen Index oder einen
Primärschlüsselwert in der Tabelle dupliziert, einen
Dublettenfehler verursachen, woraufhin die Anweisung
abgebrochen würde. Bei IGNORE
wird der
Datensatz zwar auch nicht eingefügt, aber es wird kein
Fehler ausgegeben. Bei Fehler auslösenden
Datenkonvertierungen wird die Anweisung abgebrochen, wenn
IGNORE
nicht angegeben ist. Bei
IGNORE
hingegen werden ungültige Werte
auf den jeweils nächstgelegenen gültigen Wert gesetzt und
dann einfügt; außerdem werden Warnungen erzeugt, aber die
Anweisung wird nicht abgebrochen. Mit der C-API-Funktion
mysql_info()
können Sie ermitteln, wie
viele Datensätze tatsächlich in die Tabelle eingefügt
wurden.
Wenn Sie ON DUPLICATE KEY UPDATE
angeben
und ein Datensatz eingefügt wird, der einen doppelten Wert
in einem eindeutigen Index oder einem Primärschlüssel
erzeugen würde, dann wird für den alten Datensatz
UPDATE
ausgeführt. Siehe auch
Abschnitt 13.2.4.3, „INSERT ... ON DUPLICATE KEY UPDATE
“.
INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE] [INTO]tbl_name
[(col_name
,...)] SELECT ... [ ON DUPLICATE KEY UPDATEcol_name
=expr
, ... ]
Mit INSERT ... SELECT
können Sie schnell
mehrere Datensätze aus einer oder mehreren Tabellen in eine
Tabelle einfügen. Zum Beispiel:
INSERT INTO tbl_temp2 (fld_id) SELECT tbl_temp1.fld_order_id FROM tbl_temp1 WHERE tbl_temp1.fld_order_id > 100;
Die folgenden Bedingungen gelten für eine INSERT ...
SELECT
-Anweisung:
Geben Sie IGNORE
an, um Datensätze zu
ignorieren, die unzulässige Schlüsseldubletten erzeugen
würden.
DELAYED
wird bei INSERT ...
SELECT
ignoriert.
Die Zieltabelle der INSERT
-Anweisung
kann in der FROM
-Klausel des
SELECT
-Teils der Abfrage erscheinen.
(Dies war bei einigen älteren MySQL-Versionen nicht
möglich.)
AUTO_INCREMENT
-Spalten arbeiten wie
gewöhnlich.
Um sicherzustellen, dass das Binärlog zur
Wiederherstellung der Originaltabellen verwendet werden
kann, gestattet MySQL keine nebenläufigen
Einfügeoperationen während der Ausführung einer
INSERT ... SELECT
-Anweisung.
Zurzeit können Sie in einer Unterabfrage keine Einfügeoperation in eine Tabelle durchführen und gleichzeitig eine Auswahl in einer anderen Tabelle treffen.
Im Werteteil von ON DUPLICATE KEY UPDATE
können Sie Spalten in anderen Tabellen referenzieren, solange
Sie im SELECT
-Teil nicht GROUP
BY
verwenden. Eine Begleiterscheinung besteht darin,
dass Sie nichteindeutige Spaltennamen im Werteteil
qualifizieren müssen.
INSERT DELAYED ...
Die Option DELAYED
für die
INSERT
-Anweisung ist eine MySQL-Erweiterung
zum SQL-Standard, die sehr praktisch ist, wenn Sie Clients
haben, die nicht auf den Abschluss der
INSERT
-Anweisung warten können oder
müssen. Eine solche Situation liegt häufig vor, wenn Sie
MySQL zum Loggen verwenden und zudem regelmäßig
SELECT
- und
UPDATE
-Anweisungen ausführen, deren
Fertigstellung sehr lange dauert.
Wenn ein Client INSERT DELAYED
verwendet,
wird diese Anweisung vom Server sofort angenommen und der
Datensatz in einer Warteschlange abgelegt. Sobald die Tabelle
von keinem anderen Thread mehr verwendet wird, wird der
Datensatz dann aus der Warteschlange eingefügt.
Ein weiterer wesentlicher Vorteil von INSERT
DELAYED
besteht darin, dass Einfügeoperationen
mehrerer Clients gebündelt und dann in einem Block
geschrieben werden. Dies ist bedeutend schneller als die
Durchführung vieler separater Einfügeoperationen.
Beachten Sie, dass INSERT DELAYED
, sofern
die Tabelle gerade nicht anderweitig verwendet wird, langsamer
als eine normale INSERT
-Anweisung ist. Auch
liegt die Serverbelastung etwas höher, weil der Server für
jede Tabelle, für die verzögerte Datensätze vorhanden sind,
einen separaten Thread verwalten muss. Insofern sollten Sie
INSERT DELAYED
nur verwenden, wenn Sie
wirklich sicher sind, dass Sie die Funktionalität benötigen.
Die Datensätze in der Warteschlange verbleiben nur solange im
Speicher, bis sie in die Tabelle eingefügt wurden. Aufgrund
dessen gehen, wenn Sie mysqld – etwa mit
kill -9
– terminieren oder
mysqld unerwartet abstürzt, alle
Datensätze in der Warteschlange, die noch nicht auf
Festplatte geschrieben wurden, verloren!
Für die Verwendung von DELAYED
gelten
einige Einschränkungen:
INSERT DELAYED
funktioniert nur bei
MyISAM
-, MEMORY
- und
ARCHIVE
-Tabellen. Siehe auch
Abschnitt 14.1, „Die MyISAM
-Speicher-Engine“,
Abschnitt 14.4, „Die MEMORY
-Speicher-Engine“ und
Abschnitt 14.8, „Die ARCHIVE
-Speicher-Engine“.
Bei MyISAM
-Tabellen werden, wenn keine
freien Blöcke in der Mitte der Datendatei vorhanden sind,
gleichzeitige SELECT
- und
INSERT
-Anweisung unterstützt. Unter
diesen Umständen müssen Sie INSERT
DELAYED
bei MyISAM
nur in
sehr seltenen Fällen verwenden.
INSERT DELAYED
sollte nur für
INSERT
-Anweisungen eingesetzt werden,
die Wertelisten angeben. Bei INSERT DELAYED ...
SELECT
-Anweisungen ignoriert der Server das
DELAYED
.
Ebenso ignoriert der Server das DELAYED
bei INSERT ... SELECT
- oder
INSERT ... ON DUPLICATE KEY
UPDATE
-Anweisungen.
Weil die INSERT DELAYED
-Anweisung aus
Clientsicht abgeschlossen wird, bevor die Datensätze
tatsächlich eingefügt werden, können Sie den von der
Anweisung erstellten
AUTO_INCREMENT
-Wert nicht mit
LAST_INSERT_ID()
abrufen.
Verzögerte Datensätze werden für
SELECT
-Anweisungen erst sichtbar, wenn
sie tatsächlich eingefügt wurden.
DELAYED
wird auf
Slave-Replikationsservern ignoriert, weil andernfalls auf
dem Slave andere Daten vorhanden sein könnten als auf dem
Master.
Nachfolgend wird ausführlich beschrieben, was geschieht, wenn
Sie die Option DELAYED
für
INSERT
oder REPLACE
einsetzen. In dieser Beschreibung ist „Thread“
der Thread, der eine INSERT
DELAYED
-Anweisung empfangen hat, und
„Handler“ der Thread, der alle INSERT
DELAYED
-Anweisungen der betreffenden Tabelle
verwaltet.
Wenn ein Thread eine DELAYED
-Anweisung
für eine Tabelle ausführt, wird – sofern nicht bereits
vorhanden – ein Handler-Thread erzeugt, um alle
DELAYED
-Anweisungen für die Tabelle zu
verarbeiten.
Der Thread überprüft, ob der Handler zuvor bereits eine
DELAYED
-Sperre erwirkt hat, und weist
den Handler andernfalls dazu an. Die
DELAYED
-Sperre kann auch dann erwirkt
werden, wenn andere Threads eine READ
-
oder WRITE
-Sperre für die Tabelle
halten. Allerdings wartet der Handler, bis alle
ALTER TABLE
-Sperren aufgehoben und
FLUSH TABLES
-Anweisungen abgeschlossen
sind, um zu gewährleisten, dass die Tabellenstruktur
aktuell ist.
Der Thread führt die INSERT
-Anweisung
aus, schreibt den Datensatz aber nicht in die Tabelle,
sondern setzt eine Kopie des endgültigen Datensatzes in
eine Warteschlange, die vom Handler verwaltet wird.
Syntaxfehler werden vom Thread bemerkt und an das
Clientprogramm zurückgemeldet.
Der Client kann die Anzahl doppelter Datensätze oder den
AUTO_INCREMENT
-Wert des resultierenden
Datensatzes nicht beim Server erfragen, weil die
INSERT
-Anweisung vor Durchführung der
eigentlichen Einfügeoperation bereits abgeschlossen wird.
(Wenn Sie die C-API verwenden, dann gibt die Funktion
mysql_info()
aus demselben Grund nur
irrelevante Angaben zurück.)
Das Binärlog wird vom Handler-Thread aktualisiert, sobald der Datensatz in die Tabelle eingefügt wurde. Im Falle des Einfügens mehrerer Datensätze wird das Binärlog aktualisiert, wenn der erste Datensatz eingefügt wird.
Jedes Mal, wenn delayed_insert_limit
Datensätze geschrieben wurden, überprüft der Handler,
ob noch weitere SELECT
-Anweisungen
anhängig sind. Ist dies der Fall, so gestattet er deren
Ausführung, bevor er fortfährt.
Wenn der Handler keine Datensätze mehr in der
Warteschlange hat, wird die Tabelle entsperrt. Werden
innerhalb des durch
delayed_insert_timeout
(in Sekunden)
angegebenen Zeitraums keine neuen INSERT
DELAYED
-Anweisungen empfangen, dann wird der
Handler beendet.
Sind mehr als delayed_queue_size
Datensätze in einer bestimmten Handler-Warteschlange
anhängig, dann fordert der Thread INSERT
DELAYED
auf, zu warten, bis wieder Platz in der
Warteschlange ist. Hierdurch soll gewährleistet werden,
dass mysqld nicht den gesamten Speicher
für die Warteschlange mit den verzögerten Datensätzen
verwendet.
Der Handler-Thread erscheint in der MySQL-Prozessliste als
delayed_insert
in der Spalte
Command
. Er wird terminiert, wenn Sie
eine FLUSH TABLES
-Anweisung absetzen
oder KILL
ausführen.
Allerdings speichert er vor der Terminierung alle in der
Warteschlange vorhandenen Datensätze in die Tabelle,
bevor er beendet wird. In diesem Zeitraum werden keine
neuen thread_id
INSERT
-Anweisungen anderer
Threads angenommen. Wenn Sie nachfolgend eine
INSERT DELAYED
-Anweisung ausführen,
wird ein neuer Handler-Thread erstellt.
Beachten Sie, dass dies bedeutet, dass INSERT
DELAYED
-Anweisungen Vorrang vor normalen
INSERT
-Anweisungen haben, wenn ein
INSERT DELAYED
-Handler ausgeführt
wird. Andere Änderungsanweisungen müssen warten, bis die
INSERT DELAYED
-Warteschlange leer ist
oder jemand den Handler-Thread (mit KILL
) terminiert
oder eine thread_id
FLUSH TABLES
-Anweisung
ausführt.
Die folgenden Statusvariablen machen Angaben zu
INSERT DELAYED
-Anweisungen:
Statusvariable | Bedeutung |
Delayed_insert_threads | Anzahl der Handler-Threads |
Delayed_writes | Anzahl der mit INSERT DELAYED geschriebenen
Datensätze |
Not_flushed_delayed_rows | Anzahl der Datensätze, die noch geschrieben werden müssen |
Sie können diese Variablen anzeigen, indem Sie eine
SHOW STATUS
-Anweisung absetzen oder den
Befehl mysqladmin extended-status
ausführen.
Wenn Sie ON DUPLICATE KEY UPDATE
angeben
und ein Datensatz eingefügt wird, der einen doppelten Wert in
einem eindeutigen Index oder einem Primärschlüssel erzeugen
würde, dann wird für den alten Datensatz
UPDATE
ausgeführt. Angenommen, die Spalte
a
wird als UNIQUE
deklariert und enthält den Wert 1
; in
diesem Fall hätten die beiden folgenden Anweisungen dieselbe
Wirkung:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
Der Wert der betroffenen Datensätze ist 1, wenn der Datensatz als neuer Datensatz eingefügt wird, und 2, wenn ein vorhandener Eintrag aktualisiert wird.
Wenn die Spalte b
ebenfalls eindeutig ist,
ist die INSERT
-Anweisung stattdessen
gleichbedeutend mit der folgenden
UPDATE
-Anweisung:
UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
Wenn a=1 OR b=2
mehreren Datensätzen
entspricht, wird nur ein Datensatz
aktualisiert. Generell sollten Sie von der Verwendung einer
ON DUPLICATE KEY
-Klausel bei Tabellen mit
mehreren eindeutigen Indizes absehen.
Sie können die Funktion
VALUES(
in der col_name
)UPDATE
-Klausel verwenden, um
Spaltenwerte aus dem INSERT
-Teil der
INSERT ... UPDATE
-Anweisung zu
referenzieren. Anders gesagt, verweist
VALUES(
in der col_name
)UPDATE
-Klausel auf den Wert von
col_name
, der eingefügt worden
wäre, wäre nicht ein Konflikt aufgrund einer
Schlüsseldublette aufgetreten. Diese Funktion ist
insbesondere bei Einfügevorgängen für mehrere Datensätze
praktisch. Die Funktion VALUES()
ist nur in
INSERT ... UPDATE
-Anweisungen sinnvoll zu
verwenden; andernfalls gibt sie NULL
zurück. Beispiel:
INSERT INTO table (a,b,c) VALUES (1,2,3),(4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(a)+VALUES(b);
Diese Anweisung ist identisch mit den folgenden beiden Anweisungen:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=3; INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=9;
Die Option DELAYED
wird ignoriert, wenn Sie
ON DUPLICATE KEY UPDATE
verwenden.
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name
' [REPLACE | IGNORE] INTO TABLEtbl_name
[FIELDS [TERMINATED BY 'string
'] [[OPTIONALLY] ENCLOSED BY 'char
'] [ESCAPED BY 'char
'] ] [LINES [STARTING BY 'string
'] [TERMINATED BY 'string
'] ] [IGNOREnumber
LINES] [(col_name_or_user_var
,...)] [SETcol_name
=expr
,...)]
Die Anweisung LOAD DATA INFILE
liest
Datensätze mit extrem hoher Geschwindigkeit aus einer Textdatei
in eine Tabelle ein. Der Dateiname muss als literaler String
übergeben werden.
Die Syntax für die FIELDS
- und
LINES
-Klauseln gilt auch für die
SELECT ... INTO OUTFILE
-Anweisung, die im
weiteren Verlauf dieses Abschnitts beschrieben wird. (Siehe auch
Abschnitt 13.2.7, „SELECT
“.)
Weitere Informationen zur Effektivität von
INSERT
im Vergleich zu LOAD DATA
INFILE
und zur Beschleunigung von LOAD DATA
INFILE
finden Sie in Abschnitt 7.2.16, „Geschwindigkeit von INSERT
-Anweisungen“.
Der von der Systemvariablen
character_set_database
angegebene Zeichensatz
wird zur Interpretation der Daten in der Datei verwendet.
SET NAMES
und die Einstellung von
character_set_client
wirken sich hingegen
nicht auf die Interpretation der Eingabe aus.
Beachten Sie, dass es derzeit nicht möglich ist, Datendateien
zu laden, die den Zeichensatz ucs2
verwenden.
Sie können Datendateien auch mithilfe des Hilfsprogramms
mysqlimport laden; dieses sendet dann eine
LOAD DATA INFILE
-Anweisung an den Server. Die
Option --local
bewirkt, dass
mysqlimport Datendateien vom Clienthost
liest. Sie können die Option --compress
angeben, um bei langsamen Netzwerken eine bessere Leistung zu
erzielen, sofern Client und Server das Komprimierungsprotokoll
unterstützen. Siehe auch Abschnitt 8.12, „mysqlimport — Programm zum Datenimport“.
Wenn Sie das Schlüsselwort LOW_PRIORITY
angeben, wird die Ausführung von LOAD DATA
verzögert, bis kein Client mehr aus der Tabelle liest.
Geben Sie CONCURRENT
bei einer
MyISAM
-Tabelle an, die die Bedingungen für
gleichzeitige Einfügeoperationen erfüllt (d. h. keine freien
Blöcke in der Mitte enthält), dann können andere Threads
Daten aus der Tabelle abrufen, während LOAD
DATA
ausgeführt wird. Die Verwendung dieser Option
beeinflusst die Leistungsfähigkeit von LOAD
DATA
auch dann geringfügig, wenn gleichzeitig kein
anderer Thread die Tabelle verwendet.
Das Schlüsselwort LOCAL
wird, sofern
angegeben, in Bezug auf die Clientseite der Verbindung
interpretiert:
Wenn LOCAL
angegeben ist, wird die Datei
vom Clientprogramm auf dem Clienthost gelesen und an den
Server geschickt. Die Datei kann als vollständiger Pfadname
angegeben werden, um die exakte Position zu beschreiben.
Erfolgt die Angabe als relativer Pfadname, dann wird der
Name relativ zum Verzeichnis interpretiert, in dem das
Clientprogramm gestartet wurde.
Wird LOCAL
nicht angegeben, dann muss die
Datei sich auf dem Serverhost befinden und wird direkt vom
Server gelesen. Der Server wendet zur Bestimmung der
Dateiposition die folgenden Regeln an:
Wenn der Dateiname absolut angegeben wurde, verwendet ihn der Server wie angegeben.
Ist der Dateiname ein relativer Pfadname mit einer oder mehreren am Anfang stehenden Komponenten, dann sucht der Server nach der Datei relativ zum eigenen Datenverzeichnis.
Wird ein Dateiname ohne Komponenten am Anfang übergeben, dann sucht der Server im Datenbankverzeichnis der Standarddatenbank nach der Datei.
Beachten Sie, dass, sofern keine LOCAL
-Option
angegeben wurde, die Regeln zur Folge haben, dass eine Datei
namens ./myfile.txt
im Datenverzeichnis des
Servers gesucht wird, während die Datei
myfile.txt
aus dem Datenbankverzeichnis der
Standarddatenbank gelesen wird. Ist also beispielsweise
db1
die Standarddatenbank, dann liest die
folgende LOAD DATA
-Anweisung die Datei
data.txt
aus dem Datenbankverzeichnis für
db1
aus, obwohl die Anweisung die Datei
explizit in die Datenbank db2
lädt:
LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;
Windows-Pfadnamen müssen unter Verwendung von Schrägstrichen (statt Backslashs) angegeben werden. Wenn Sie Backslashs (umgekehrte Schrägstriche) verwenden, müssen Sie sie doppelt angeben.
Aus Sicherheitsgründen müssen Textdateien, die auf dem Server
ausgelesen werden, entweder im Datenbankverzeichnis liegen oder
von allen gelesen werden können. Außerdem benötigen Sie zur
Verwendung von LOAD DATA INFILE
für
Serverdateien die Berechtigung FILE
. Siehe
auch Abschnitt 5.8.3, „Von MySQL zur Verfügung gestellte Berechtigungen“.
Die Verwendung von LOCAL
ist ein wenig
langsamer als der Direktzugriff des Servers auf die Dateien,
weil der Inhalt der Datei vom Client über die Verbindung an den
Server gesendet werden muss. Die Berechtigung
FILE
benötigen Sie hingegen zum Laden
lokaler Dateien nicht.
Die Option LOCAL
funktioniert nur, wenn ihre
Verwendung sowohl am Client als auch am Server aktiviert wurde.
Wenn beispielsweise mysqld mit
--local-infile=0
gestartet wurde, funktioniert
LOCAL
nicht. Siehe auch
Abschnitt 5.7.4, „Sicherheitsprobleme mit LOAD DATA LOCAL
“.
Unter Unix können Sie, wenn LOAD DATA
über
eine Pipe lesen soll, die folgende Methode verwenden (hierbei
laden wir das Listing des Verzeichnisses /
in eine Tabelle):
mkfifo /mysql/db/x/x chmod 666 /mysql/db/x/x find / -ls > /mysql/db/x/x mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
Die Schlüsselwörter REPLACE
und
IGNORE
steuern den Umgang mit eingegebenen
Datensätzen, die Duplikate vorhandener Datensätze mit
eindeutigen Schlüsselwerten darstellen.
Wenn Sie REPLACE
angeben, ersetzt die Eingabe
vorhandene Datensätze. Dies betrifft Datensätze, die denselben
Wert bei einem Primärschlüssel oder einem eindeutigen Index
wie die neuen Datensätze haben. Siehe auch
Abschnitt 13.2.6, „REPLACE
“.
Bei Angabe von IGNORE
hingegen werden neue
Datensätze, deren eindeutiger Schlüsselwert bereits einem
vorhandenen Datensatz zugewiesen ist, ignoriert. Wenn Sie keine
Option angeben, hängt das Verhalten davon ab, ob das
Schlüsselwort LOCAL
angegeben wird. Ohne
LOCAL
tritt ein Fehler auf, wenn ein
doppelter Schlüsselwert gefunden wird; in diesem Fall wird der
Rest der Textdatei ignoriert. Mit LOCAL
ist
das Standardverhalten so, als ob IGNORE
angegeben worden wäre. Das liegt daran, dass der Server keine
Möglichkeit hat, die Übertragung der Datei während des
Vorgangs zu beenden.
Wenn Sie Fremdschlüssel-Constraints während des Ladevorgangs
ignorieren wollen, können Sie eine SET
FOREIGN_KEY_CHECKS=0
-Anweisung vor der Ausführung von
LOAD DATA
absetzen.
Wenn Sie LOAD DATA INFILE
auf eine leere
MyISAM
-Tabelle anwenden, werden alle
nichteindeutigen Indizes in einer separaten Stapeloperation
erstellt (wie bei REPAIR TABLE
). Dies sollte
LOAD DATA INFILE
erheblich beschleunigen,
wenn Sie viele Indizes haben. In einigen Extremfällen können
Sie die Indizes noch schneller erstellen, indem Sie sie vor dem
Einladen der Datei in die Tabelle mit ALTER TABLE ...
DISABLE KEYS
abschalten und sie nach Abschluss des
Ladevorgangs mit ALTER TABLE ... ENABLE KEYS
neu erstellen. Siehe auch Abschnitt 7.2.16, „Geschwindigkeit von INSERT
-Anweisungen“.
LOAD DATA INFILE
ist das Gegenstück zu
SELECT ... INTO OUTFILE
. (Siehe auch
Abschnitt 13.2.7, „SELECT
“.) Um Daten aus einer Tabelle in eine
Datei zu schreiben, benutzen Sie SELECT ... INTO
OUTFILE
; wollen Sie die Datei wieder in eine Tabelle
einlesen, dann verwenden Sie LOAD DATA
INFILE
. Die Syntax der Klauseln
FIELDS
und LINES
ist bei
beiden Anweisungen dieselbe. Beide sind optional, aber
FIELDS
muss LINES
vorangehen, sofern beide angegeben sind.
Wenn Sie eine FIELDS
-Klausel festlegen, ist
auch jede einzelne Unterklausel (TERMINATED
BY
, [OPTIONALLY] ENCLOSED BY
und
ESCAPED BY
) ebenfalls optional – Sie
müssen lediglich mindestens eine dieser Unterklauseln angeben.
Wenn Sie keine FIELDS
-Klausel angeben,
entsprechen die Vorgabeeinstellungen dem Folgenden:
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
Wenn Sie keine LINES
-Klausel angeben,
entsprechen die Vorgabeeinstellungen dem Folgenden:
LINES TERMINATED BY '\n' STARTING BY ''
Anders gesagt, die Standardwerte bewirken, dass LOAD
DATA INFILE
sich beim Einlesen wie folgt verhält:
Es wird nach Zeilenbegrenzungen bei Zeilenumbrüchen gesucht.
Zeilenpräfixe werden nicht übersprungen.
Zeilen werden bei Tabulatoren in Felder unterteilt.
Felder müssen nicht innerhalb von Anführungszeichen abgeschlossen werden.
Fälle von Tabulatoren, Zeilenumbrüchen oder
‘\
’, denen
‘\
’ vorangeht, werden als
literale Zeichen interpretiert, die Teile von Feldwerten
sind.
Umgekehrt bewirken die Voreinstellungen, dass sich
SELECT ... INTO OUTFILE
beim Schreiben einer
Ausgabe wie folgt verhält:
Tabulatoren werden zwischen Felder gesetzt.
Mehrere Felder werden nicht zwischen Anführungszeichen gesetzt.
‘\
’ wird zur Kennzeichnung
von Tabulatoren, Zeilenumbrüchen und
‘\
’ verwendet, die innerhalb
von Feldwerten auftreten.
Am Ende von Zeilen werden Zeilenumbrüche geschrieben.
Der Backslash wird bei MySQL als Escape-Zeichen in Strings
verwendet. Insofern müssen Sie, um FIELDS ESCAPED BY
'\\'
zu schreiben, zwei Backslashes angeben, damit der
Wert als ein Backslash interpretiert wird.
Hinweis: Wenn Sie die Textdatei
auf einem Windows-System erzeugt haben, müssen Sie unter
Umständen LINES TERMINATED BY '\r\n'
verwenden, um die Datei korrekt einzulesen, weil
Windows-Programme normalerweise zwei Zeichen als
Zeilenendzeichen verwenden. Einige Programme wie WordPad
verwenden beim Schreiben von Dateien unter Umständen sogar
\r
als Zeilenendzeichen. Um solche Dateien zu
lesen, verwenden Sie LINES TERMINATED BY
'\r'
.
Wenn alle Zeilen, die Sie einlesen wollen, ein gemeinsames
Präfix aufweisen, das Sie ignorieren wollen, können Sie mit
LINES STARTING BY
'
das Präfix
und alles, was davor steht, überspringen.
Enthält eine Zeile das Präfix gar nicht, dann wird die gesamte
Zeile übersprungen. Nehmen wir an, dass Sie folgende Anweisung
absetzen:
prefix_string
'
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test FIELDS TERMINATED BY ',' LINES STARTING BY 'xxx';
Nehmen wir ferner an, dass die Datendatei wie folgt aussieht:
xxx"abc",1 something xxx"def",2 "ghi",3
In diesem Fall werden als Ergebnis die Datensätze
("abc",1)
und ("def",2)
erzeugt. Der dritte Datensatz in der Datei wird übersprungen,
weil er das Präfix nicht enthält.
Die Option IGNORE
kann verwendet werden, um Zeilen am Anfang der
Datei zu ignorieren. So können Sie etwa number
LINESIGNORE 1
LINES
angeben, um eine Kopfzeile zu überspringen, die
etwa die Spaltennamen enthält:
LOAD DATA INFILE '/tmp/test.txt' INTO TABLE test IGNORE 1 LINES;
Wenn Sie SELECT ... INTO OUTFILE
gemeinsam
mit LOAD DATA INFILE
verwenden, um Daten aus
einer Datenbank in eine Datei zu schreiben und die Datei später
wieder in die Datenbank einzulesen, dann müssen die Optionen
der beiden Anweisungen zur Behandlung von Feldern und Zeilen
einander entsprechen. Andernfalls kann LOAD DATA
INFILE
den Inhalt der Datei nicht korrekt einlesen.
Angenommen, Sie schreiben mit SELECT ... INTO
OUTFILE
eine Datei mit Feldern, die kommagetrennt
sind:
SELECT * INTO OUTFILE 'data.txt' FIELDS TERMINATED BY ',' FROM table2;
Um diese kommagetrennte Datei wieder einzulesen, müssen Sie folgende Anweisung verwenden:
LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY ',';
Haben Sie stattdessen probiert, die Datei mit der folgenden
Anweisung einzulesen, dann ist dies nicht gelungen, da
LOAD DATA INFILE
angewiesen wird, nach
Tabulatoren zwischen den Feldern zu suchen:
LOAD DATA INFILE 'data.txt' INTO TABLE table2 FIELDS TERMINATED BY '\t';
Infolgedessen wird jede Eingabezeile wohl als separates Feld interpretiert werden.
Mit LOAD DATA INFILE
können Sie Dateien
lesen, die Sie aus externen Quellen erhalten haben.
Beispielsweise exportieren viele Programme Daten als
kommagetrennte Werte im so genannten CSV-Format (Comma-Separate
Values). Hierbei werden die Felder durch Kommata voneinander
getrennt und in doppelte Anführungszeichen gesetzt. Wenn Zeilen
in einer solchen Datei durch Zeilenumbrüche abgeschlossen
werden, veranschaulicht die folgende Anweisung die Optionen zur
Feld- und Zeilenbehandlung, wie Sie sie zum Laden der Datei
verwenden würden:
LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\n';
Alle Optionen zur Feld- und Zeilenbehandlung können einen
Leer-String (''
) angeben. Wenn der String
nicht leer ist, müssen die Werte FIELDS [OPTIONALLY]
ENCLOSED BY
und FIELDS ESCAPED BY
genau ein Zeichen umfassen. Die Werte FIELDS TERMINATED
BY
, LINES STARTING BY
und
LINES TERMINATED BY
können hingegen auch
mehrere Zeichen enthalten. Um etwa Zeilen zu schreiben, die
jeweils aus einem aus einer Absatzschaltung und einem
Zeilenvorschub bestehenden Zeichenpaar bestehen, geben Sie die
Klausel LINES TERMINATED BY '\r\n'
an.
Um eine Datei mit Witzen zu lesen, die durch aus
%%
bestehenden Zeilen getrennt sind, können
Sie Folgendes tun:
CREATE TABLE jokes (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, joke TEXT NOT NULL); LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes FIELDS TERMINATED BY '' LINES TERMINATED BY '\n%%\n' (joke);
FIELDS [OPTIONALLY] ENCLOSED BY
steuert die
Anführungszeichen um die Felder. Bei der Ausgabe
(SELECT ... INTO OUTFILE
) werden, wenn Sie
das Wort OPTIONALLY
weglassen, alle Felder
vom durch ENCLOSED BY
angegebenen Zeichen
umschlossen. Hier ein Beispiel für eine solche Ausgabe (mit dem
Komma als Feldtrennzeichen):
"1","a string","100.20" "2","a string containing a , comma","102.20" "3","a string containing a \" quote","102.20" "4","a string containing a \", quote and comma","102.20"
Wenn Sie OPTIONALLY
angeben, wird das
ENCLOSED BY
-Zeichen nur zum Umschließen von
Werten in Spalten verwendet, die einen String-Datentyp haben
(z. B. CHAR
, BINARY
,
TEXT
oder ENUM
):
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a \" quote",102.20 4,"a string containing a \", quote and comma",102.20
Beachten Sie, dass das Auftreten des ENCLOSED
BY
-Zeichens in einem Feldwert gekennzeichnet wird,
indem man ihm das ESCAPED BY
-Zeichen
voranstellt. Ferner ist wichtig, dass es, wenn Sie einen leeren
ESCAPED BY
-Wert angeben, möglich ist,
versehentlich eine Ausgabe zu erzeugen, die von LOAD
DATA INFILE
nicht korrekt eingelesen werden kann. Die
obige Ausgabe beispielsweise würde wie folgt angezeigt werden,
wenn das Escape-Zeichen leer wäre. Sie werden bemerken, dass
das zweite Feld in der vierten Zeile ein auf das
Anführungszeichen folgendes Komma enthält, welches das Feld
abzuschließen scheint (was nicht zutrifft).
1,"a string",100.20 2,"a string containing a , comma",102.20 3,"a string containing a " quote",102.20 4,"a string containing a ", quote and comma",102.20
Bei der Eingabe wird das ENCLOSED BY
-Zeichen
– sofern vorhanden – am Ende der jeweiligen Feldwerte
entfernt. (Dies erfolgt unabhängig davon, ob
OPTIONALLY
angegeben ist oder nicht –
OPTIONALLY
hat keine Auswirkung auf die
Eingabeinterpretation.) Instanzen des ENCLOSED
BY
-Zeichens, denen das ESCAPED
BY
-Zeichen vorangestellt ist, werden als Teil des
aktuellen Feldwerts interpretiert.
Beginnt das Feld mit dem ENCLOSED BY
-Zeichen,
dann werden Instanzen dieses Zeichens nur dann als
Feldtrennzeichen ausgewertet, wenn ihnen jeweils die
TERMINATED BY
-Sequenz für Feld oder Zeile
folgt. Um Mehrdeutigkeiten zu vermeiden, können Fälle des
ENCLOSED BY
-Zeichens innerhalb eines
Feldwerts verdoppelt werden; sie werden dann als einzelne
Instanz des Zeichens ausgewertet. Wird also etwa
ENCLOSED BY '"'
angegeben, dann wird mit
Anführungszeichen wie hier gezeigt verfahren:
"The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss The ""BIG"" boss -> The ""BIG"" boss
FIELDS ESCAPED BY
steuert, wie Sonderzeichen
geschrieben oder gelesen werden. Wenn das FIELDS
ESCAPED BY
-Zeichen nicht leer ist, dann wird es bei
der Ausgabe als Präfix für die folgenden Zeichen verwendet:
FIELDS ESCAPED BY
-Zeichen
FIELDS [OPTIONALLY] ENCLOSED BY
-Zeichen
das erste Zeichen der Werte FIELDS TERMINATED
BY
und LINES TERMINATED BY
ASCII 0
(eigentlich wird auf das
Escape-Zeichen folgend ASCII
‘0
’ und kein Nullwertbyte
geschrieben)
Ist das FIELDS ESCAPED BY
-Zeichen leer, dann
werden keinerlei Zeichen gekennzeichnet und
NULL
wird als NULL
(und
nicht als \N
) ausgegeben. Es ist
wahrscheinlich nicht angeraten, ein leeres Escape-Zeichen
anzugeben; dies gilt insbesondere dann, wenn Feldwerte in Ihren
Daten eines der in der obigen Liste enthaltenen Zeichen
enthalten.
Wenn das FIELDS ESCAPED BY
-Zeichen nicht leer
ist, werden Instanzen dieses Zeichens bei der Eingabe entfernt,
und das nachfolgende Zeichen wird literal als Teil des Feldwerts
verwendet. Ausnahmen sind die gekennzeichneten Zeichen
‘0
’ oder
‘N
’ (z. B. \0
oder \N
, wenn das Escape-Zeichen
‘\
’ ist). Diese Sequenzen werden
als ASCII-NUL (Nullwertbyte) bzw. als NULL
interpretiert. Die Regeln für den Umgang mit
NULL
werden im weiteren Verlauf dieses
Abschnitts beschrieben.
Weitere Informationen zur
‘\
’-Escape-Syntax finden Sie in
Abschnitt 9.1, „Literale: wie Strings und Zahlen geschrieben werden“.
In bestimmten Fällen interagieren die Optionen zur Feld- und Zeilenbehandlung:
Wenn LINES TERMINATED BY
ein Leer-String
und FIELDS TERMINATED BY
nicht leer ist,
werden Zeilen auch mit FIELDS TERMINATED
BY
abgeschlossen.
Sind die Werte von FIELDS TERMINATED BY
und FIELDS ENCLOSED BY
beide leer
(''
), dann wird ein festes
Datensatzformat (ohne Trennzeichen) verwendet. Bei einem
solchen Format fehlt zwar das Trennzeichen, ein
Zeilenabschlusszeichen kann aber nichtsdestoweniger
vorhanden sein. Stattdessen werden Spaltenwerte unter
Berücksichtigung der Anzeigebreiten der Spalten geschrieben
und gelesen. Wird z. B. eine Spalte als
INT(7)
deklariert, dann werden Werte für
diese Spalte unter Verwendung von Feldern mit einer Länge
von sieben Zeichen geschrieben. Bei der Eingabe werden die
Spaltenwerte dann ermittelt, indem sieben Zeichen ausgelesen
werden.
LINES TERMINATED BY
wird nach wie vor zur
Trennung von Zeilen verwendet. Wenn eine Zeile nicht alle
Felder enthält, werden die verbleibenden Spalten auf ihre
Vorgabewerte gesetzt. Wenn kein Zeilenabschlusszeichen
vorhanden ist, sollten Sie dieses auf ''
setzen. In diesem Fall muss die Textdatei alle Felder für
jeden Datensatz enthalten.
Das Festformat für Datensätze beeinflusst auch den Umgang
mit NULL
-Werten (siehe unten). Beachten
Sie, dass dieses Format nicht funktioniert, wenn Sie einen
Multibytezeichensatz verwenden.
Die Handhabung von NULL
-Werten variiert
entsprechend den verwendeten FIELDS
- und
LINES
-Optionen:
Bei den FIELDS
- und
LINES
-Standardwerten wird
NULL
als Feldwert \N
in die Ausgabe geschrieben. Analog wird der Feldwert
\N
bei der Eingabe als
NULL
gelesen (vorausgesetzt, das
ESCAPED BY
-Zeichen ist
‘\
’).
Wenn FIELDS ENCLOSED BY
nicht leer ist,
dann wird ein Feld, das das Wort NULL
als
Wert enthält, als NULL
-Wert gelesen.
Dies unterscheidet sich von dem Wort
NULL
, wenn es in FIELDS ENCLOSED
BY
-Zeichen gesetzt ist – dieses wird als
'NULL'
gelesen.
Ist FIELDS ESCAPED BY
leer, dann wird
NULL
als Wort NULL
geschrieben.
Beim Festformat (welches verwendet wird, wenn
FIELDS TERMINATED BY
und FIELDS
ENCLOSED BY
beide leer sind), wird
NULL
als Leer-String geschrieben.
Beachten Sie, dass dies zur Folge hat, dass
NULL
-Werte und Leer-Strings in der
Tabelle nicht mehr unterschieden werden können, sobald sie
in die Datei geschrieben werden, weil beide als Leer-Strings
geschrieben werden. Müssen die beiden Werte nach dem
Wiedereinlesen der Datei weiterhin unterscheidbar sein, dann
sollten Sie das Festformat nicht verwenden.
Manche Fälle werden von LOAD DATA INFILE
nicht unterstützt:
Datensätze fester Länge (FIELDS TERMINATED
BY
und FIELDS ENCLOSED BY
sind
leer) und BLOB
- oder
TEXT
-Spalten.
Wenn Sie ein Trennzeichen angeben, das mit einem anderen
Trennzeichen (oder dessen Präfix) identisch ist, kann
LOAD DATA INFILE
die Eingabe nicht
korrekt interpretieren. Die folgende
FIELDS
-Klausel beispielsweise würde
Probleme verursachen:
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
Wenn FIELDS ESCAPED BY
leer ist, bewirkt
ein Feldwert, der eine Instanz von FIELDS ENCLOSED
BY
oder LINES TERMINATED BY
gefolgt vom FIELDS TERMINATED BY
-Wert
enthält, dass LOAD DATA INFILE
das
Einlesen eines Felds oder einer Zeile zu früh beendet. Dies
geschieht, weil LOAD DATA INFILE
nicht
genau bestimmen kann, wo der Feld- oder Zeilenwert endet.
Das folgende Beispiel lädt alle Spalten der Tabelle
persondata
:
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;
Standardmäßig wird, wenn keine Spaltenliste am Ende der
LOAD DATA INFILE
-Anweisung vorhanden ist,
erwartet, dass Eingabezeilen ein Feld für jede Tabellenspalte
enthalten. Wenn Sie nur einen Teil der Spalten einer Tabelle
laden wollen, müssen Sie eine Spaltenliste angeben:
LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);
Ferner müssen Sie eine Spaltenliste festlegen, wenn die Reihenfolge der Felder in der Eingabedatei sich von der Reihenfolge der Spalten in der Tabelle unterscheidet. Andernfalls kann MySQL nicht ermitteln, wie die Eingabefelder den Tabellenspalten zuzuordnen sind.
Die Spaltenliste kann entweder Spaltennamen oder
Benutzervariablen enthalten. Bei Benutzervariablen gestattet
Ihnen die SET
-Klausel die Durchführung einer
Werteumwandlung vor der Zuweisung des Ergebnisses zu den
Spalten.
Benutzervariablen in der SET
-Klausel können
auf unterschiedliche Weise verwendet werden. Die folgenden Werte
benutzen die erste Eingabespalte direkt für den Wert von
t1.column1
und weisen die zweite
Eingabespalte einer Benutzervariablen zu, an der eine Division
durchgeführt wird, bevor sie als Wert für
t1.column2
verwendet wird:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, @var1) SET column2 = @var1/100;
Die SET
-Klausel kann zur Übermittlung von
Werten benutzt werden, die nicht der Eingabedatei entnommen
wurden. Die folgende Anweisung weist column3
das aktuelle Datum und die Uhrzeit zu:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, column2) SET column3 = CURRENT_TIMESTAMP;
Sie können einen Eingabewert auch verwerfen, indem Sie ihn einer Benutzervariablen zuweisen, der Variablen aber keine Tabellenspalte zuordnen:
LOAD DATA INFILE 'file.txt' INTO TABLE t1 (column1, @dummy, column2, @dummy, column3);
Die Verwendung der Spalten-/Variablenliste und der
SET
-Klausel ist den folgenden
Einschränkungen unterworfen:
Zuordnungen in der SET
-Klausel sollten
auf der linken Seite des Zuweisungsoperators nur
Spaltennamen aufweisen.
Auf der rechten Seite einer SET
-Zuordnung
dürfen auch Unterabfragen zum Einsatz kommen. Eine
Unterabfrage, die einen Wert zurückgibt, der einer Spalte
zugeordnet werden soll, darf nur eine skalare Unterabfrage
sein. Außerdem können Sie eine Unterabfrage nicht für
Auswahlabfragen an die Tabelle verwenden, die gerade geladen
wird.
Zeilen, die von einer IGNORE
-Klausel
ignoriert werden, werden für die Spalten-/Variablenliste
oder die SET
-Klausel nicht verarbeitet.
Benutzervariablen können nicht verwendet werden, wenn Daten mit Festformat geladen werden, da Benutzervariablen keine Anzeigebreite haben.
Wenn eine Eingabezeile verarbeitet wird, unterteilt
LOAD DATA
sie in Felder und verwendet die
Werte entsprechend der Spalten-/Variablenliste und der
SET
-Klausel, sofern diese vorhanden sind. Der
Ergebnisdatensatz wird dann in die Tabelle eingefügt. Sind
BEFORE INSERT
- oder AFTER
INSERT
-Trigger für die Tabelle vorhanden, so werden
diese vor bzw. nach dem Einfügen des Datensatzes aktiviert.
Hat eine Eingabezeile zu viele Felder, dann werden die überzähligen Felder ignoriert und die Anzahl der Warnungen wird erhöht.
Hat eine Eingabezeile zu wenig Felder, dann werden die Tabellenspalten, deren Eingabefelder fehlen, auf ihre Standardwerte gesetzt. Die Zuweisung von Standardwerten ist in Abschnitt 11.1.4, „Vorgabewerte von Datentypen“, beschrieben.
Ein leerer Feldwert wird anders interpretiert als ein fehlender Feldwert:
Bei String-Typen wird die Spalte auf den Leer-String gesetzt.
Bei numerischen Typen wird die Spalte auf
0
gesetzt.
Bei zeitbezogenen Typen wird die Spalte auf den passenden „Nullwert“ des Typs gesetzt. Siehe auch Abschnitt 11.3, „Datums- und Zeittypen“.
Dies sind dieselben Werte, die als Ergebnis ausgegeben werden,
wenn Sie einem String, einem numerischen oder einem
zeitbezogenen Wert in einer INSERT
- oder
UPDATE
-Anweisung explizit den Leer-String
zuweisen.
TIMESTAMP
-Spalten werden nur dann auf die
aktuellen Werte für Datum und Uhrzeit gesetzt, wenn ein
NULL
-Wert (d. h. \N
) für
die Spalte vorhanden ist oder der Standardwert der
TIMESTAMP
-Spalte der aktuelle Zeitstempel ist
und in der Feldliste (sofern vorhanden) weggelassen wurde.
LOAD DATA INFILE
betrachtet alle Eingaben als
Strings, d. h., Sie können für ENUM
- oder
SET
-Spalten numerische Werte nicht so
eingeben wie von INSERT
-Anweisungen her
gewohnt. Alle ENUM
- und
SET
-Werte müssen als Strings angegeben
werden.
Wenn die LOAD DATA INFILE
-Anweisung
abgeschlossen ist, gibt sie einen Informations-String im
folgenden Format zurück:
Records: 1 Deleted: 0 Skipped: 0 Warnings: 0
Wenn Sie die C-API verwenden, können Sie Informationen zur
Anweisung durch einen Aufruf der Funktion
mysql_info()
ermitteln. Siehe auch
Abschnitt 24.2.3.34, „mysql_info()
“.
Warnungen treten unter denselben Umständen auf wie beim
Einfügen von Werten mithilfe der
INSERT
-Anweisung (siehe
Abschnitt 13.2.4, „INSERT
“); der einzige Unterschied besteht
darin, dass LOAD DATA INFILE
auch dann
Warnungen erzeugt, wenn zu wenig oder zu viel Felder im
Eingabedatensatz vorhanden sind. Die Warnungen werden nirgends
gespeichert; Sie können ihrer Anzahl lediglich entnehmen, ob
alles geklappt hat oder nicht.
Mit SHOW WARNINGS
erhalten Sie eine Liste der
ersten max_error_count
Warnungen mit
Informationen dazu, was unter Umständen nicht geklappt hat.
Siehe auch Abschnitt 13.5.4.25, „SHOW WARNINGS
“.
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
[(col_name
,...)] VALUES ({expr
| DEFAULT},...),(...),...
Oder:
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
SETcol_name
={expr
| DEFAULT}, ...
Oder:
REPLACE [LOW_PRIORITY | DELAYED] [INTO]tbl_name
[(col_name
,...)] SELECT ...
REPLACE
funktioniert auf exakt gleiche Weise
wie INSERT
. Der Unterschied besteht darin,
dass, wenn ein alter Datensatz denselben Wert wie ein neuer
Datensatz für einen Primärschlüssel oder einen eindeutigen
Index hat, der alte Datensatz gelöscht wird, bevor der neue
eingefügt wird. Siehe auch Abschnitt 13.2.4, „INSERT
“.
REPLACE
ist eine MySQL-Erweiterung zum
SQL-Standard. Es kann Datensätze einfügen, oder es kann
Datensätze löschen und einfügen. Wenn
Sie eine Anweisung suchen, die dem SQL-Standard entspricht und
die entweder einfügt oder aktualisiert,
dann benutzen Sie die INSERT ... ON DUPLICATE KEY
UPDATE
-Anweisung (siehe auch
Abschnitt 13.2.4.3, „INSERT ... ON DUPLICATE KEY UPDATE
“).
Beachten Sie, dass, sofern die Tabelle nicht einen
Primärschlüssel oder einen eindeutigen Index hat, die
Verwendung von REPLACE
unsinnig ist. Die
Anweisung wäre dann mit INSERT
identisch,
weil kein Index vorhanden ist, anhand dessen bestimmt werden
könnte, ob ein neuer Datensatz ein Duplikat eines bereits
vorhandenen darstellt.
Werte für alle Spalten werden den Werten entnommen, die in der
REPLACE
-Anweisung angegeben sind. Fehlende
Spalten werden – wie bei INSERT
– auf
ihre Standardwerte gesetzt. Es ist nicht möglich, Werte aus dem
aktuellen Datensatz zu referenzieren und diese dann im neuen
Datensatz zu verwenden. Wenn Sie eine Zuordnung wie SET
verwenden,
wird die Referenzierung des Spaltennamens auf der rechten Seite
wie
col_name
=
col_name
+ 1DEFAULT(
behandelt, d. h., die Zuordnung ist äquivalent zu col_name
)SET
.
col_name
=
DEFAULT(col_name
) + 1
Um REPLACE
zu verwenden, benötigen Sie die
Berechtigungen INSERT
und
DELETE
für die Tabelle.
Die REPLACE
-Anweisung gibt einen Wert
zurück, der die Anzahl der betroffenen Datensätze angibt.
Konkret ist dies die Summe der gelöschten und eingefügten
Datensätze. Wenn der Wert bei einer
REPLACE
-Anweisung für einen Datensatz 1
beträgt, dann wurde ein Datensatz eingefügt und keiner
gelöscht. Ist der Wert größer als 1, dann wurden ein oder
mehrere alte Datensätze gelöscht, bevor der neue Datensatz
eingefügt wurde. Ein einzelner Datensatz kann durchaus mehr als
nur einen alten Datensatz ersetzen, sofern die Tabelle mehrere
eindeutige Indizes hat und der neue Datensatz Werte
verschiedener alter Datensätze in verschiedenen eindeutigen
Indizes dupliziert.
Die Anzahl der betroffenen Datensätze erlaubt also die einfache
Bestimmung, ob REPLACE
nur einen Datensatz
hinzugefügt hat oder ob auch Datensätze ersetzt wurden:
Überprüfen Sie, ob der Wert 1 (Hinzufügung) oder größer ist
(Ersetzung).
Wenn Sie die C-API verwenden, kann die Anzahl der betroffenen
Datensätze durch die Funktion
mysql_affected_rows()
ermittelt werden.
Zurzeit können Sie in einer Unterabfrage keine Ersetzungsoperation in einer Tabelle durchführen und gleichzeitig eine Auswahl in einer anderen Tabelle treffen.
MySQL verwendet für REPLACE
(und
LOAD DATA ... REPLACE
) den folgenden
Algorithmus:
Es wird versucht, den neuen Datensatz in die Tabelle einzufügen.
Wenn die Einfügeoperation aufgrund einer Schlüsseldublette in einem Primärschlüssel oder einem eindeutigen Index fehlschlägt,
wird der konfliktauslösende Datensatz mit dem doppelten Schlüsselwert aus der Tabelle entfernt,
wird erneut versucht, den neuen Datensatz in die Tabelle einzufügen.
SELECT [ALL | DISTINCT | DISTINCTROW ] [HIGH_PRIORITY] [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT] [SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]select_expr
, ... [FROMtable_references
[WHEREwhere_condition
] [GROUP BY {col_name
|expr
|position
} [ASC | DESC], ... [WITH ROLLUP]] [HAVINGwhere_condition
] [ORDER BY {col_name
|expr
|position
} [ASC | DESC], ...] [LIMIT {[offset
,]row_count
|row_count
OFFSEToffset
}] [PROCEDUREprocedure_name
(argument_list
)] [INTO OUTFILE 'file_name
'export_options
| INTO DUMPFILE 'file_name
'] [FOR UPDATE | LOCK IN SHARE MODE]]
SELECT
wird zum Abrufen von Datensätzen
verwendet, die aus einer oder mehreren Tabellen ausgewählt
wurden, und kann UNION
-Anweisungen und
Unterabfragen enthalten. Siehe auch Abschnitt 13.2.7.2, „UNION
“, und
Abschnitt 13.2.8, „Syntax von Unterabfragen“.
Die meistverwendeten Klauseln für SELECT
sind die folgenden:
Jede select_expr
gibt eine Spalte
an, die Sie abrufen wollen. Es muss mindestens ein
select_expr
vorhanden sein.
table_references
gibt die
Tabelle(n) an, aus der oder denen die Datensätze abgerufen
werden sollen. Die Syntax ist in Abschnitt 13.2.7.1, „JOIN
“,
beschrieben.
Die WHERE
-Klausel gibt, soweit vorhanden,
die Bedingung(en) an, die Datensätze erfüllen müssen,
damit sie ausgewählt werden.
where_condition
ist ein Ausdruck,
der für jeden auszuwählenden Datensatz wahr ist. Die
Anweisung wählt, wenn keine
WHERE
-Klausel vorhanden ist, alle
Datensätze aus.
Sie können in der WHERE
-Klausel alle von
MySQL unterstützten Funktionen und Operatoren mit Ausnahme
der Zusammenfassungsfunktionen einsetzen. Siehe auch
Kapitel 12, Funktionen für die Benutzung in SELECT
- und
WHERE
-Klauseln.
SELECT
kann auch verwendet werden, um
Datensätze abzurufen, die ohne Referenzierung einer Tabelle
berechnet wurden.
Zum Beispiel:
mysql> SELECT 1 + 1;
-> 2
Sie können DUAL
als Pseudotabellenname in
Situationen angeben, in denen keine Tabellen referenziert
werden:
mysql> SELECT 1 + 1 FROM DUAL;
-> 2
DUAL
ist ausschließlich zum Zweck der
Kompatibilität mit anderen Datenbankservern vorhanden, die eine
FROM
-Klausel erfordern. MySQL benötigt keine
solche Klausel, wenn keine Tabellen referenziert werden.
Generell müssen Klauseln in genau der Reihenfolge angegeben
werden, die in der Syntaxbeschreibung erscheint. So muss etwa
eine HAVING
-Klausel hinter den GROUP
BY
-Klauseln und vor den ORDER
BY
-Klauseln stehen. Die einzige Ausnahme ist die
INTO
-Klausel, die entweder wie in der
Syntaxbeschreibung gezeigt oder unmittelbar vor der
FROM
-Klausel stehen kann.
Einem Ausdruck select_expr
lässt
sich mit AS
ein Alias
zuweisen. Der Alias wird als Spaltenname des Ausdrucks
benutzt und kann in alias_name
GROUP BY
-,
ORDER BY
- oder
HAVING
-Klauseln verwendet werden. Zum
Beispiel:
SELECT CONCAT(last_name,', ',first_name) AS full_name FROM mytable ORDER BY full_name;
Das Schlüsselwort AS
ist beim Zuweisen
eines Alias zu select_expr
optional. Das obige Beispiel hätte auch wie folgt
geschrieben sein können:
SELECT CONCAT(last_name,', ',first_name) full_name FROM mytable ORDER BY full_name;
Allerdings kann, weil AS
optional ist,
ein kleines Problem auftreten, wenn Sie das Komma zwischen
zwei select_expr
-Ausdrücken
vergessen: MySQL interpretiert den zweiten Ausdruck als
Aliasnamen. Sie wird etwa in der folgenden Anweisung
columnb
als Aliasname behandelt:
SELECT columna columnb FROM mytable;
Aus diesem Grund hat es sich bewährt, AS
beim Festlegen von Spaltenaliasen immer explizit anzugeben.
Es ist nicht zulässig, einen Spaltenalias in einer
WHERE
-Klausel zu verwenden, weil der
Spaltenwert unter Umständen nicht bestimmt werden kann,
wenn die WHERE
-Klausel ausgeführt wird.
Siehe auch Abschnitt A.5.4, „Probleme mit alias
“.
Die Klausel FROM
gibt
die Tabelle(n) an, aus der oder denen die Datensätze
abgerufen werden sollen. Wenn Sie mehr als eine Tabelle
angeben, führen Sie einen Join durch. Informationen zur
Join-Syntax finden Sie in Abschnitt 13.2.7.1, „table_references
JOIN
“. Für jede
angegebene Tabelle können Sie optional einen Alias angeben.
tbl_name
[[AS]alias
] [{USE|IGNORE|FORCE} INDEX (key_list
)]
Wie Sie dem Optimierer mit USE INDEX
,
IGNORE INDEX
und FORCE
INDEX
Hinweise zur Auswahl der Indizes geben, ist
in Abschnitt 13.2.7.1, „JOIN
“, beschrieben.
Sie können SET
max_seeks_for_key=
als alternative Möglichkeit verwenden, um MySQL zur
Verwendung von Schlüssel- statt Tabellenscans (sofern
möglich) zu zwingen. Siehe auch
Abschnitt 5.2.2, „Server-Systemvariablen“.
value
Sie können eine Tabelle in der Standarddatenbank als
tbl_name
oder – wenn Sie eine
Datenbank ausdrücklich angeben wollen – als
db_name
.tbl_name
referenzieren. Eine Spalte können Sie als
col_name
,
tbl_name
.col_name
oder
db_name
.tbl_name
.col_name
referenzieren. Sie müssen das Präfix
tbl_name
oder
db_name
.tbl_name
für eine Spaltenreferenzierung nicht angeben, sofern die
Referenzierung eindeutig ist. Beispiele für
Mehrdeutigkeiten, die die spezifischeren Formen der
Spaltenreferenzierung erfordern, finden Sie in
Abschnitt 9.2, „Datenbank-, Tabellen-, Index-, Spalten- und Aliasnamen“.
Für einen Tabellenverweis kann mit
oder
tbl_name
AS
alias_name
tbl_name alias_name
ein Alias
erstellt werden:
SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
Spalten, die für die Ausgabe ausgewählt werden, lassen
sich in ORDER BY
- und GROUP
BY
-Klauseln als Spaltennamen, Spaltenaliase oder
Spaltenpositionen referenzieren. Spaltenpositionen sind
ganze Zahlen, die bei 1 beginnen:
SELECT college, region, seed FROM tournament ORDER BY region, seed; SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s; SELECT college, region, seed FROM tournament ORDER BY 2, 3;
Um in umgekehrter (absteigender) Reihenfolge zu sortieren,
fügen Sie in der ORDER BY
-Klausel das
Schlüsselwort DESC
zum Namen der Spalte
zu, nach der die Sortierung erfolgt: Standardmäßig erfolgt
die Sortierung aufsteigend. Dies kann mit dem Schlüsselwort
ASC
explizit festgelegt werden.
Die Verwendung von Spaltenpositionen ist veraltet, weil die Syntax im SQL-Standard nicht mehr vorhanden ist.
Wenn Sie GROUP BY
verwenden, werden die
Ausgabedatensätze entsprechend den GROUP
BY
-Spalten sortiert, so als ob Sie eine
ORDER BY
-Klausel für dieselben Spalten
angegeben hätten. Um eine Mehrbelastung durch das Sortieren
mit GROUP BY
zu vermeiden, fügen Sie
ORDER BY NULL
hinzu:
SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY NULL;
MySQL erweitert die GROUP BY
-Klausel
dahingehend, dass Sie ASC
und
DESC
auch nach den in der Klausel
benannten Spalten angeben können:
SELECT a, COUNT(b) FROM test_table GROUP BY a DESC;
MySQL erweitert die Verwendung von GROUP
BY
so, dass die Auswahl von Feldern möglich ist,
die in der GROUP BY
-Klausel nicht genannt
sind. Wenn Sie bei einer Abfrage nicht die erwarteten
Ergebnisse erhalten, lesen Sie bitte die Beschreibung von
GROUP BY
in
Abschnitt 12.11, „Funktionen und Modifizierer für die Verwendung in GROUP
BY
-Klauseln“.
GROUP BY
unterstützt den Modifizierer
WITH ROLLUP
. Siehe auch
Abschnitt 12.11.2, „GROUP BY
-Modifizierer“.
Die HAVING
-Klausel wird fast als Letztes
angewandt – unmittelbar bevor die Elemente an den Client
gesendet werden, und ohne Optimierung. (Nur
LIMIT
wird noch nach
HAVING
angewandt.)
Der SQL-Standard sieht vor, dass HAVING
nur Spalten in der GROUP BY
-Klausel oder
solche Spalten referenzieren darf, die in
Zusammenfassungsfunktionen verwendet werden. Allerdings
unterstützt MySQL eine Erweiterung dieses Verhaltens und
gestattet HAVING
ferner die
Referenzierung von Spalten in der
SELECT
-Liste und Spalten in äußeren
Unterabfragen.
Wenn die HAVING
-Klausel eine Spalte
referenziert, die mehrdeutig ist, erscheint eine Warnung. In
der folgenden Anweisung ist col2
mehrdeutig, weil es sowohl als Alias als auch als
Spaltenname verwendet wird:
SELECT COUNT(col1) AS col2 FROM t GROUP BY col2 HAVING col2 = 2;
Hier wird das SQL-Standardverhalten angewandt, d. h., wenn
ein HAVING
-Spaltenname sowohl in einer
GROUP BY
-Klausel als auch als
Spaltenalias in der Liste der Ausgabespalten enthalten ist,
hat die Spalte in der GROUP BY
-Spalte
Vorrang.
Verwenden Sie HAVING
nicht für Elemente,
die in der WHERE
-Klausel aufgeführt sein
sollten. So sollten Sie beispielsweise nicht Folgendes
schreiben:
SELECTcol_name
FROMtbl_name
HAVINGcol_name
> 0;
Formulieren Sie stattdessen wie folgt:
SELECTcol_name
FROMtbl_name
WHEREcol_name
> 0;
Die HAVING
-Klausel kann
Zusammenfassungsfunktionen referenzieren, was der
WHERE
-Klausel nicht möglich ist:
SELECT user, MAX(salary) FROM users GROUP BY user HAVING MAX(salary) > 10;
(Dies funktionierte bei einigen älteren MySQL-Versionen nicht.)
Die LIMIT
-Klausel kann zur Beschränkung
der Anzahl der von der SELECT
-Anweisung
zurückgegebenen Datensätze verwendet werden.
LIMIT
nimmt ein oder zwei numerische
Argumente entgegen, die (außer bei Verwendung vorbereiteter
Anweisungen) beide nichtnegative Integer-Konstanten sein
müssen.
Von den beiden Argumenten gibt das erste den Versatz des ersten zurückzugebenden Datensatzes an, das zweite die maximale Anzahl zurückzugebender Datensätze. Der Versatz des ersten Datensatzes ist 0 (nicht 1):
SELECT * FROM tbl LIMIT 5,10; # Retrieve rows 6-15
Um alle Datensätze beginnend bei einem bestimmten Versatz bis zum Ende der Ergebnismenge zurückzugeben, können Sie als zweiten Parameter eine sehr große Zahl angeben. Die folgende Anweisung ruft alle Datensätze beginnend beim 96. bis zum letzten Datensatz ab:
SELECT * FROM tbl LIMIT 95,18446744073709551615;
Sofern nur ein Argument angegeben ist, gibt der Wert die Anzahl der Datensätze an, die beginnend beim ersten Datensatz zurückgegeben werden sollen:
SELECT * FROM tbl LIMIT 5; # Retrieve first 5 rows
Anders gesagt, ist LIMIT
äquivalent
zu row_count
LIMIT 0,
.
row_count
Bei vorbereiteten Anweisungen können Sie Platzhalter
verwenden. Die folgende Anweisung gibt genau einen Datensatz
aus der Tabelle tbl
zurück:
SET @a=1; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?'; EXECUTE STMT USING @a;
Die folgenden Anweisungen geben den zweiten bis sechsten
Datensatz aus der Tabelle tbl
zurück:
SET @skip=1; SET @numrows=5; PREPARE STMT FROM 'SELECT * FROM tbl LIMIT ?, ?'; EXECUTE STMT USING @skip, @numrows;
Aus Gründen der Kompatibilität mit PostgreSQL unterstützt
MySQL auch die Syntax LIMIT
.
row_count
OFFSET
offset
Die Form SELECT ... INTO OUTFILE
'
der
file_name
'SELECT
-Anweisung schreibt die
ausgewählten Datensätze in eine Datei. Die Datei wird auf
dem Serverhost erstellt, d. h., Sie benötigen die
Berechtigung FILE
, um die Syntax
verwenden zu können. file_name
darf keine vorhandene Datei sein, wodurch u. a. verhindert
werden soll, dass Dateien wie
/etc/passwd
und Datenbanktabellen
zerstört werden.
Die Anweisung SELECT ... INTO OUTFILE
ist
in erster Linie dazu vorgesehen, eine Tabelle sehr schnell
in eine Textdatei auf dem Server zu speichern. Wenn Sie die
resultierende Datei auf einem Clienthost statt auf dem
Serverhost erstellen wollen, dürfen Sie SELECT ...
INTO OUTFILE
nicht verwenden. In diesem Fall
sollten Sie stattdessen einen Befehl wie mysql -e
"SELECT ..." >
benutzen, um
die Datei auf dem Clienthost anzulegen.
file_name
SELECT ... INTO OUTFILE
ist das
Gegenstück zu LOAD DATA INFILE
. Die
Syntax für den
export_options
-Teil der Anweisung
umfasst dieselben FIELDS
- und
LINES
-Klauseln, die bei LOAD
DATA INFILE
benutzt werden. Siehe auch
Abschnitt 13.2.5, „LOAD DATA INFILE
“.
FIELDS ESCAPED BY
steuert, wie
Sonderzeichen geschrieben werden. Wenn das FIELDS
ESCAPED BY
-Zeichen nicht leer ist, dann wird es
bei der Ausgabe als Präfix für die folgenden Zeichen
verwendet:
FIELDS ESCAPED BY
-Zeichen
FIELDS [OPTIONALLY] ENCLOSED
BY
-Zeichen
das erste Zeichen der Werte FIELDS TERMINATED
BY
und LINES TERMINATED BY
ASCII NUL
(das Nullwertbyte;
eigentlich wird auf das Escape-Zeichen folgend ASCII
‘0
’ und kein Nullwertbyte
geschrieben)
Die FIELDS TERMINATED BY
-,
ENCLOSED BY
-, ESCAPED
BY
- oder LINES TERMINATED
BY
-Zeichen müssen mit
Escape-Zeichen gekennzeichnet werden, damit Sie die Datei
zuverlässig wiedereinlesen können. ASCII
NUL
wird gekennzeichnet, um das Ablesen
bei manchen Pagern zu vereinfachen.
Die Ergebnisdatei muss nicht der SQL-Syntax entsprechen, weswegen weitere Zeichen nicht gekennzeichnet werden müssen.
Ist das FIELDS ESCAPED BY
-Zeichen leer,
dann werden keinerlei Zeichen gekennzeichnet und
NULL
wird als NULL
(und nicht als \N
) ausgegeben. Es ist
wahrscheinlich nicht angeraten, ein leeres Escape-Zeichen
anzugeben; dies gilt insbesondere dann, wenn Feldwerte in
Ihren Daten eines der in der obigen Liste enthaltenen
Zeichen enthalten.
Es folgt ein Beispiel, das eine Datei im CSV-Format erzeugt, welches von vielen Programmen verwendet wird:
SELECT a,b,a+b INTO OUTFILE '/tmp/result.txt' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' FROM test_table;
Wenn Sie INTO DUMPFILE
statt
INTO OUTFILE
verwenden, schreibt MySQL
nur einen Datensatz ohne Spalten- oder Zeilentrennzeichen
und ohne Escape-Kennzeichnung in die Datei. Dies ist
praktisch, wenn Sie einen BLOB
-Wert in
die Datei speichern wollen.
Hinweis: In Dateien, die
durch INTO OUTFILE
oder INTO
DUMPFILE
erstellt wurden, kann von allen Benutzern
geschrieben werden. Grund hierfür ist die Tatsache, dass
der MySQL Server keine Datei erstellen kann, deren Besitzer
jemand anders als der Benutzer ist, unter dessen Konto der
Server ausgeführt wird. (Sie sollten aus diesem und anderen
Gründen mysqld
niemals als root
ausführen.) Die Datei muss von allen schreibbar sein, damit
Sie ihren Inhalt modifizieren können.
Die Beschreibung der SELECT
-Syntax am
Anfang dieses Abschnitts zeigt die
INTO
-Klausel gegen Ende der Anweisung.
INTO OUTFILE
oder INTO
DUMPFILE
können auch unmittelbar auf die
FROM
-Klausel folgend angegeben werden.
Eine PROCEDURE
-Klausel benennt eine
Prozedur, die die Daten in der Ergebnismenge verarbeitet.
Ein Beispiel finden Sie in
Abschnitt 26.4.1, „PROCEDURE ANALYSE“.
Wenn Sie FOR UPDATE
mit einer
Speicher-Engine verwenden, die Seiten- oder Datensatzsperren
verwendet, dann werden die von der Abfrage untersuchten
Datensätze bis zum Ende der laufenden Transaktion
schreibgesperrt. Mithilfe von LOCK IN SHARE
MODE
wird eine gemeinsame Sperre gesetzt, die
anderen Transaktionen das Lesen, nicht jedoch das Ändern
oder Löschen der untersuchten Datensätze gestattet. Siehe
auch Abschnitt 14.2.10.5, „Lesevorgänge sperren“.
Sie können auf das Schlüsselwort SELECT
folgend eine Reihe von Optionen angeben, die den Betrieb der
Anweisung beeinflusst.
Die Optionen ALL
, DISTINCT
und DISTINCTROW
geben an, ob doppelte
Datensätze zurückgegeben werden sollen. Wird keine dieser
Optionen angegeben, dann wird ALL
als Vorgabe
vorausgesetzt (d. h., alle passenden Datensätze werden
zurückgegeben). DISTINCT
und
DISTINCTROW
sind Synonyme; sie legen fest,
dass doppelte Datensätze aus der Ergebnismenge entfernt werden.
HIGH_PRIORITY
,
STRAIGHT_JOIN
und Optionen, die mit
SQL_
beginnen, sind MySQL-Erweiterungen zum
SQL-Standard.
HIGH_PRIORITY
gibt
SELECT
Vorrang vor einer Anweisung, die
eine Tabelle aktualisiert. Sie sollten die Option nur bei
Abfragen verwenden, die sehr schnell sind und sofort
erledigt werden müssen. Eine SELECT
HIGH_PRIORITY
-Anweisung, die abgesetzt wird,
während die Tabelle zum Lesen gesperrt ist, wird auch
ausgeführt, wenn eine Aktualisierungsanweisung darauf
wartet, dass die Tabelle frei wird.
HIGH_PRIORITY
kann nicht bei
SELECT
-Anweisungen verwendet werden, die
Teil einer Union sind.
STRAIGHT_JOIN
zwingt den Optimierer zur
Verknüpfung der Tabellen in der Reihenfolge, in der sie in
der FROM
-Klausel angegeben sind. Sie
können hiermit eine Abfrage beschleunigen, wenn der
Optimierer die Tabellen nicht optimal anordnet. Siehe auch
Abschnitt 7.2.1, „EXPLAIN
-Syntax (Informationen über ein
SELECT
erhalten)“. STRAIGHT_JOIN
kann auch in der
table_references
-Liste angegeben
werden. Siehe auch Abschnitt 13.2.7.1, „JOIN
“.
SQL_BIG_RESULT
kann mit GROUP
BY
oder DISTINCT
verwendet
werden. Sie teilen dem Optimierer hierdurch mit, dass die
Ergebnismenge viele Datensätze enthält. In diesem Fall
verwendet MySQL bei Bedarf direkt festplattenbasierte
Temporärtabellen und zieht die Sortierung der Verwendung
einer Temporärtabelle mit einem Schlüssel auf
GROUP BY
-Elemente vor.
SQL_BUFFER_RESULT
erzwingt das Ablegen
des Ergebnisses in einer Temporärtabelle. Auf diese Weise
kann MySQL die Tabellensperren schnell wieder aufheben. Die
Option ist zudem in Fällen hilfreich, in denen die
Übermittlung des Ergebnisses an den Client sehr lange
dauert.
SQL_SMALL_RESULT
kann mit GROUP
BY
oder DISTINCT
verwendet
werden. Sie teilen dem Optimierer hierdurch mit, dass die
Ergebnismenge klein ist. In diesem Fall verwendet MySQL
schnelle Temporärtabellen zur Speicherung der
Ergebnistabelle anstelle einer Sortierung. Normalerweise
werden Sie diese Option nicht benötigen.
SQL_CALC_FOUND_ROWS
weist MySQL an, zu
berechnen, wie viele Datensätze ohne Berücksichtigung
einer ggf. vorhandenen LIMIT
-Klausel in
der Ergebnismenge enthalten wären. Die Anzahl der
Datensätze kann dann mit SELECT
FOUND_ROWS()
abgerufen werden. Siehe auch
Abschnitt 12.10.3, „Informationsfunktionen“.
Mit SQL_CACHE
weisen Sie MySQL an, das
Abfrageergebnis im Abfrage-Cache zu speichern, wenn Sie
einen query_cache_type
-Wert von
2
oder DEMAND
verwenden. Bei einer Abfrage, die UNION
oder Unterabfragen verwendet, betrifft diese Option alle
SELECT
-Klauseln in der Abfrage. Siehe
auch Abschnitt 5.14, „MySQL-Anfragen-Cache“.
SQL_NO_CACHE
weist MySQL an, das
Abfrageergebnis nicht im Abfrage-Cache zu speichern. Siehe
auch Abschnitt 5.14, „MySQL-Anfragen-Cache“. Bei einer Abfrage, die
UNION
oder Unterabfragen verwendet,
betrifft diese Option alle
SELECT
-Klauseln in der Abfrage.
MySQL unterstützt die folgenden
JOIN
-Syntaxen für den
table_references
-Teil von
SELECT
-Anweisungen sowie von
DELETE
- und
UPDATE
-Anweisungen für mehrere Tabellen:
table_references:
table_reference
[,table_reference
] ...table_reference
:table_factor
|join_table
table_factor
:tbl_name
[[AS]alias
] [{USE|IGNORE|FORCE} INDEX (key_list
)] | (table_references
) | { OJtable_reference
LEFT OUTER JOINtable_reference
ONconditional_expr
}join_table
:table_reference
[INNER | CROSS] JOINtable_factor
[join_condition
] |table_reference
STRAIGHT_JOINtable_factor
|table_reference
STRAIGHT_JOINtable_factor
ONcondition
|table_reference
LEFT [OUTER] JOINtable_reference
join_condition
|table_reference
NATURAL [LEFT [OUTER]] JOINtable_factor
|table_reference
RIGHT [OUTER] JOINtable_reference
join_condition
|table_reference
NATURAL [RIGHT [OUTER]] JOINtable_factor
join_condition
: ONconditional_expr
| USING (column_list
)
Eine Tabellenreferenzierung heißt auch Join-Ausdruck.
Die Syntax von table_factor
ist im
Vergleich zum SQL-Standard erweitert. SQL akzeptiert nur
table_reference
, nicht aber eine in
Klammern gesetzte Liste mit Referenzierungen.
Dies ist eine konservative Erweiterung, sofern wir jedes Komma
in einer Liste mit
table_reference
-Elementen als
äquivalent zu einem inneren Join betrachten. Zum Beispiel:
SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)
ist äquivalent mit
SELECT * FROM t1 LEFT JOIN (t2 CROSS JOIN t3 CROSS JOIN t4) ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)
In MySQL ist CROSS JOIN
syntaktisch ein
Äquivalent zu INNER JOIN
(diese lassen
sich gegeneinander austauschen). Nach SQL-Standard hingegen
sind beide nicht äquivalent. INNER JOIN
wird bei einer ON
-Klausel und
CROSS JOIN
andernfalls verwendet.
Klammern können in Join-Ausdrücken, die nur innere Join-Operationen enthalten, ignoriert werden. MySQL unterstützt auch verschachtelte Joins (siehe auch Abschnitt 7.2.10, „Optimierung verschachtelter Joins“).
Im ON
-Teil sollten keine Bedingungen
vorhanden sein, die zur Beschränkung der Datensätze in der
Ergebnismenge verwendet werden; geben Sie solche Bedingungen
besser in der WHERE
-Klausel an. Es gibt
aber Ausnahmen zu dieser Regel.
Die oben gezeigte Syntax { OJ ... LEFT OUTER JOIN
...}
ist nur aus Gründen der Kompatibilität mit
ODBC vorhanden. Die geschweiften Klammern in der Syntax
sollten literal notiert werden, sind also keine Metasyntax,
wie sie andernorts in Syntaxbeschreibungen verwendet wird.
Für einen Tabellenverweis kann mit
oder
tbl_name
AS
alias_name
tbl_name alias_name
ein Alias
erstellt werden:
SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name; SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name;
Die Bedingungsanweisung ON
ist ein
beliebiger Bedingungsausdruck der Form, die in einer
WHERE
-Klausel verwendet werden kann.
Ist für die rechte Tabelle im ON
- oder
USING
-Teil eines LEFT
JOIN
kein passender Datensatz vorhanden, dann
wird für die rechte Tabelle ein Datensatz verwendet, bei
dem alle Spalten auf NULL
gesetzt sind.
Sie können diesen Umstand nutzen, um Datensätze in einer
Tabelle zu finden, die kein Gegenstück in einer anderen
Tabelle aufweisen:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Dieses Beispiel findet alle Datensätze in
table1
mit einem
id
-Wert, der nicht in
table2
vorhanden ist (d. h. alle
Datensätze in table1
ohne
entsprechenden Datensatz in table2
).
Dies setzt voraus, dass table2.id
als
NOT NULL
deklariert wurde. Siehe auch
Abschnitt 7.2.9, „Optimierung von LEFT JOIN
und RIGHT
JOIN
“.
Die
USING(
-Klausel
benennt eine Liste mit Spalten, die in beiden Tabellen
vorhanden sein müssen. Wenn die Tabellen
column_list
)a
und b
jeweils die
Spalten c1
, c2
und
c3
enthalten, dann vergleicht der
folgende Join die entsprechenden Spalten der beiden
Tabellen:
a LEFT JOIN b USING (c1,c2,c3)
Der NATURAL [LEFT] JOIN
beider Tabellen
wird als semantisch äquivalent zu einem INNER
JOIN
oder einem LEFT JOIN
mit
einer USING
-Klausel definiert, die alle
Spalten aufführt, die in beiden Tabellen vorhanden sind.
INNER JOIN
und ,
(Komma) sind semantisch gleichwertig, wenn keine
Join-Bedingung vorhanden ist: Beide erzeugen ein
kartesisches Produkt zwischen den angegebenen Tabellen
(d. h., jeder Datensatz in der ersten Tabelle wird mit
jedem Datensatz in der zweiten Tabelle verknüpft).
RIGHT JOIN
funktioniert analog zu
LEFT JOIN
. Um den Code
datenbankübergreifend portierbar zu halten, wird
empfohlen, LEFT JOIN
anstelle von
RIGHT JOIN
zu verwenden.
STRAIGHT_JOIN
ist bis auf die Tatsache,
dass die linke Tabelle immer vor der rechten gelesen wird,
identisch mit JOIN
. Dies kann für die
(wenigen) Fälle genutzt werden, in denen der
Join-Optimierer die Tabellen in der falschen Reihenfolge
anordnet.
Sie können Hinweise dazu angeben, welchen Index MySQL beim
Abrufen von Informationen aus einer Tabelle verwenden soll.
Durch Angabe von USE INDEX
(
können Sie
MySQL anweisen, nur einen der möglichen Indizes zum Ermitteln
von Datensätzen in der Tabelle zu verwenden. Mit der
alternativen Syntax key_list
)IGNORE INDEX
(
können Sie
MySQL anweisen, einen bestimmten Index nicht zu verwenden.
Solche Hinweise sind nützlich, wenn
key_list
)EXPLAIN
zeigt, dass MySQL aus einer Liste
möglicher Indizes den falschen verwendet.
Sie können auch FORCE INDEX
verwenden.
Diese Option agiert wie USE INDEX
(
, es wird aber
zusätzlich vorausgesetzt, dass ein Tabellenscan
sehr kostspielig ist. Anders gesagt: Ein
Tabellenscan wird nur verwendet, wenn die Datensätze in der
Tabelle nicht unter der Verwendung eines der gegebenen Indizes
gefunden werden können.
key_list
)
USE INDEX
, IGNORE INDEX
und FORCE INDEX
wirken sich erst darauf
aus, welche Indizes verwendet werden, wenn MySQL entschieden
hat, wie Datensätze in der Tabelle ermittelt werden und wie
der Join durchgeführt wird. Sie haben keine Auswirkungen
darauf, ob ein Index benutzt wird, wenn eine ORDER
BY
- oder GROUP BY
-Klausel
aufgelöst wird.
USE KEY
, IGNORE KEY
und
FORCE KEY
sind Synonyme von USE
INDEX
, IGNORE INDEX
und
FORCE INDEX
.
Hier einige Beispiele für Joins:
SELECT * FROM table1,table2 WHERE table1.id=table2.id; SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id; SELECT * FROM table1 LEFT JOIN table2 USING (id); SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id LEFT JOIN table3 ON table2.id=table3.id; SELECT * FROM table1 USE INDEX (key1,key2) WHERE key1=1 AND key2=2 AND key3=3; SELECT * FROM table1 IGNORE INDEX (key3) WHERE key1=1 AND key2=2 AND key3=3;
Hinweis: Natürliche Joins
und Joins mit USING
(einschließlich
Varianten mit äußeren Joins) werden entsprechend Standard
SQL:2003 verarbeitet. Diese Änderungen erhöhen die
Kompatibilität von MySQL mit dem SQL-Standard. Allerdings
kann es bei manchen Joins zu unterschiedlichen Ausgabespalten
kommen. Ferner müssen einige Abfragen, die in älteren
Versionen (vor 5.0.12) zu funktionieren schienen, neu
geschrieben werden, um dem Standard zu entsprechen. Die
folgende Liste enthält weitere Angaben zu verschiedenen
Auswirkungen der aktuellen Join-Verarbeitung im Vergleich zur
Verarbeitung in älteren Versionen. Der Begriff
„älter“ bezeichnet hier Versionen vor MySQL
5.0.12.
Die Spalten eines NATURAL
- oder
USING
-Joins können sich von denen
älterer Versionen unterscheiden. Insbesondere erscheinen
keine redundanten Ausgabespalten mehr, und die Reihenfolge
der Spalten für die Erweiterung SELECT
*
kann anders aussehen.
Beachten Sie die folgenden Anweisungen:
CREATE TABLE t1 (i INT, j INT); CREATE TABLE t2 (k INT, j INT); INSERT INTO t1 VALUES(1,1); INSERT INTO t2 VALUES(1,1); SELECT * FROM t1 NATURAL JOIN t2; SELECT * FROM t1 JOIN t2 USING (j);
In den älteren Versionen erzeugten sie folgende Ausgabe:
+------+------+------+------+ | i | j | k | j | +------+------+------+------+ | 1 | 1 | 1 | 1 | +------+------+------+------+ +------+------+------+------+ | i | j | k | j | +------+------+------+------+ | 1 | 1 | 1 | 1 | +------+------+------+------+
In der ersten SELECT
-Anweisung
erscheint Spalte i
in beiden Tabellen
und wird insofern eine Join-Spalte, d. h., sie sollte
laut SQL-Standard nur einmal (und nicht zweimal) in der
Ausgabe erscheinen. Ähnlich ist die Spalte
j
in der zweiten
SELECT
-Anweisung in der
USING
-Klausel aufgeführt und sollte
ebenfalls nur einmal (und nicht zweimal) in der Ausgabe
auftauchen. In beiden Fällen wird die redundante Spalte
nicht beseitigt. Auch ist die Reihenfolge der Spalten
nicht korrekt im Sinne des SQL-Standards.
Heute erzeugen die Anweisungen folgende Ausgabe:
+------+------+------+ | j | i | k | +------+------+------+ | 1 | 1 | 1 | +------+------+------+ +------+------+------+ | j | i | k | +------+------+------+ | 1 | 1 | 1 | +------+------+------+
Die redundante Spalte ist beseitigt. Auch die Spaltenreihenfolge ist nun korrekt im Sinne des SQL-Standards:
Zuerst werden die Spalten, die in beiden Tabellen vorhanden sind, in der Reihenfolge aufgeführt, in der sie in der ersten Tabelle erscheinen.
Als Zweites erscheinen Spalten, die nur in der ersten Tabelle vorhanden sind, und zwar in der Reihenfolge, in der sie in der Tabelle erscheinen.
Als Drittes erscheinen Spalten, die nur in der zweiten Tabelle vorhanden sind, und zwar in der Reihenfolge, in der sie in der Tabelle erscheinen.
Die Auswertung eines natürlichen Vielfach-Joins
unterscheidet sich auf eine Weise, die ein Neuformulieren
von Abfragen erforderlich machen kann. Angenommen, Sie
haben drei Tabellen t1(a,b)
,
t2(c,b)
und t3(a,c)
,
die jeweils einen Datensatz aufweisen:
t1(1,2)
, t2(10,2)
und t3(7,10)
. Nehmen wir ferner an,
dass Sie folgenden NATURAL JOIN
auf die
drei Tabellen haben:
SELECT ... FROM t1 NATURAL JOIN t2 NATURAL JOIN t3;
In älteren Versionen wurde der linke Operand des zweiten
Joins als t2
betrachtet, wohingegen er
eigentlich der verschachtelte Join (t1 NATURAL
JOIN t2)
sein sollte. Infolgedessen werden die
Spalten von t3
nur auf gemeinsame
Spalten in t2
geprüft; hat
t3
gemeinsame Spalten mit
t1
, dann werden diese nicht als
Equi-Join-Spalten betrachtet. Insofern wurde obige Abfrage
bei älteren Versionen in den folgenden Equi-Join
transformiert:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c;
Diesem Join fehlt aber ein weiteres Equi-Join-Prädikat
(t1.a = t3.a)
. Aufgrund dessen wird als
Ergebnis ein Datensatz ausgegeben – und nicht das
korrekte leere Ergebnis. Die korrekte äquivalente Abfrage
sieht wie folgt aus:
SELECT ... FROM t1, t2, t3 WHERE t1.b = t2.b AND t2.c = t3.c AND t1.a = t3.a;
Wenn Sie in aktuellen MySQL-Versionen dasselbe Abfrageergebnis wie bei den älteren Versionen erhalten, dann formulieren Sie den natürlichen Join als Equi-Join um.
Früher hatten der Kommaoperator (,
)
und JOIN
dieselbe Rangstufe, d. h.,
der Join-Ausdruck t1, t2 JOIN t3
wurde
als ((t1, t2) JOIN t3)
interpretiert.
Jetzt hat JOIN
Vorrang vor dem Komma,
d. h., der Ausdruck wird als (t1, (t2 JOIN
t3))
ausgewertet. Diese Änderung betrifft
Anweisungen, die eine ON
-Klausel
verwenden, denn diese Klausel kann nur Spalten in den
Operanden des Joins referenzieren, und die Änderung in
der Rangstufe wirkt sich darauf aus, wie interpretiert
wird, was diese Operanden sind.
Beispiel:
CREATE TABLE t1 (i1 INT, j1 INT); CREATE TABLE t2 (i2 INT, j2 INT); CREATE TABLE t3 (i3 INT, j3 INT); INSERT INTO t1 VALUES(1,1); INSERT INTO t2 VALUES(1,1); INSERT INTO t3 VALUES(1,1); SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);
In älteren Versionen war die
SELECT
-Anweisung aufgrund der
impliziten Gruppierung von t1,t2
als
(t1,t2)
zulässig. Jetzt hat
JOIN
Vorrang, d. h., die Operanden
für die ON
-Klausel sind
t2
und t3
. Da
t1.i1
keine Spalte in einem der
Operanden ist, ist das Ergebnis der Fehler
Unknown column 't1.i1' in 'on clause'
.
Um die Verarbeitung des Joins zuzulassen, gruppieren Sie
die ersten beiden Tabellen explizit mithilfe von Klammern,
sodass die Operanden für die
ON
-Klausel (t1,t2)
und t3
sind:
SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
Alternativ umgehen Sie die Verwendung des Kommaoperators
und verwenden stattdessen JOIN
:
SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
Diese Änderung gilt auch für INNER
JOIN
, CROSS JOIN
,
LEFT JOIN
und RIGHT
JOIN
: Sie alle haben nun Vorrang vor dem
Kommaoperator.
Früher konnte die ON
-Klausel Spalten
in Tabellen referenzieren, die auf ihrer rechten Seite
aufgeführt wurden. Jetzt kann eine
ON
-Klausel nur ihre Operanden
referenzieren.
Beispiel:
CREATE TABLE t1 (i1 INT); CREATE TABLE t2 (i2 INT); CREATE TABLE t3 (i3 INT); SELECT * FROM t1 JOIN t2 ON (i1 = i3) JOIN t3;
Früher war diese SELECT
-Anweisung
zulässig. Nun schlägt die Anweisung mit dem Fehler
Unknown column 'i3' in 'on clause'
fehl, weil i3
eine Spalte in
t3
ist, die kein Operand der
ON
-Klausel ist. Die Anweisung sollte
wie folgt umgeschrieben werden:
SELECT * FROM t1 JOIN t2 JOIN t3 ON (i1 = i3);
Früher konnte eine USING
-Klausel als
ON
-Klausel neugeschrieben werden, die
die entsprechenden Spalten vergleichen konnte. Die beiden
folgenden Klauseln etwa sind semantisch identisch:
a LEFT JOIN b USING (c1,c2,c3) a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3
Heute haben diese beiden Klauseln nicht mehr dieselbe Bedeutung:
Bezüglich der Ermittlung, welche Datensätze die Join-Bedingung erfüllen, bleiben beide Joins semantisch identisch.
Allerdings ist diese semantische Identität nicht mehr
in Bezug auf die Frage vorhanden, wie die für die
SELECT *
-Erweiterung anzuzeigenden
Spalten bestimmt werden. Der
USING
-Join wählt den
zusammengefassten Wert der entsprechenden Spalten,
während der ON
-Join alle Spalten
aus allen Tabellen auswählt. Bei obigem
USING
-Join wählt SELECT
*
die folgenden Werte aus:
COALESCE(a.c1,b.c1), COALESCE(a.c2,b.c2), COALESCE(a.c3,b.c3)
Beim ON
-Join wählt SELECT
*
die folgenden Werte aus:
a.c1, a.c2, a.c3, b.c1, b.c2, b.c3
Bei einem inneren Join ist
COALESCE(a.c1,b.c1)
das Gleiche wie
a.c1
oder b.c1
,
weil beide Spalten denselben Wert haben. Bei einem
äußeren Join (wie LEFT JOIN
) darf
eine der beiden Spalten NULL
sein.
Diese Spalte wird im Ergebnis weggelassen.
SELECT ... UNION [ALL | DISTINCT] SELECT ... [UNION [ALL | DISTINCT] SELECT ...]
UNION
wird verwendet, um das Ergebnis einer
Anzahl von SELECT
-Anweisungen zu einer
Ergebnismenge zusammenzufassen.
Ausgewählte Spalten, die an den entsprechenden Positionen
jeder SELECT
-Anweisung aufgelistet sind,
sollten vom selben Typ sein. (So sollte etwa die erste von der
ersten Anweisung ausgewählte Spalte denselben Typ haben wie
die erste von den anderen Anweisungen gewählte Spalte.) Die
in der ersten SELECT
-Anweisung verwendeten
Spaltennamen werden als Spaltennamen für die zurückgegebenen
Ergebnisse benutzt.
Die SELECT
-Anweisungen sind normale
Auswahlanweisungen, es gelten jedoch die folgenden
Einschränkungen:
Nur die letzte SELECT
-Anweisung kann
INTO OUTFILE
verwenden.
HIGH_PRIORITY
kann nicht bei
SELECT
-Anweisungen verwendet werden,
die Teil einer Union sind. Wenn Sie es für die erste
SELECT
-Anweisung angeben, hat dies
keine Auswirkungen. Bei einer Angabe für eine
nachfolgende SELECT
-Anweisung tritt ein
Syntaxfehler auf.
Geben Sie das Schlüsselwort ALL
an, dann
enthält das Ergebnis alle passenden Datensätze aus allen
SELECT
-Anweisungen. Wenn Sie
DISTINCT
angeben, werden doppelte
Datensätze aus dem Ergebnis entfernt. Wird kein
Schlüsselwort benutzt, dann entspricht das Standardverhalten
dem von DISTINCT
(Entfernung doppelter
Datensätze).
Das Schlüsselwort DISTINCT
ist optional
ohne Wirkung, ist aber in der Syntax zulässig, da der
SQL-Standard dies vorschreibt. (In MySQL stellt
DISTINCT
das Standardverhalten einer Union
dar.)
Sie können UNION ALL
und UNION
DISTINCT
in derselben Abfrage gemeinsam verwenden.
Derart gemischte UNION
-Typen werden
dahingehend verarbeitet, dass eine
DISTINCT
-Union Vorrang vor einer
ALL
-Union zu ihrer Linken hat. Eine
DISTINCT
-Union kann explizit mit
UNION DISTINCT
oder implizit durch
Verwendung von UNION
ohne nachfolgende
Schlüsselwörter DISTINCT
oder
ALL
erzeugt werden.
Wenn Sie eine ORDER BY
- oder
LIMIT
-Klausel zur Sortierung bzw.
Beschränkung des gesamten Ergebnisses der Union benutzen
wollen, setzen Sie die einzelnen
SELECT
-Anweisungen in Klammern und
platzieren Sie die ORDER BY
- oder
LIMIT
-Klausel an dem Ende. Das folgende
Beispiel verwendet beide Klauseln:
(SELECT a FROM t1 WHERE a=10 AND B=1) UNION (SELECT a FROM t2 WHERE a=11 AND B=2) ORDER BY a LIMIT 10;
Diese Art von ORDER BY
kann keine
Spaltenreferenzierungen verwenden, die einen Tabellennamen
enthalten (d. h. Namen im Format
tbl_name
.col_name
).
Geben Sie stattdessen einen Spaltenalias in der ersten
SELECT
-Anweisung an und referenzieren Sie
diesen Alias in der ORDER BY
-Klausel.
Alternativ können Sie die Spalten auch in der ORDER
BY
-Klausel unter Angabe ihrer Spaltenposition
referenzieren. (Ein Alias ist allerdings vorzuziehen, weil das
Angeben von Spaltenpositionen veraltet ist.)
Ferner muss, wenn einer zu sortierenden
Spalte ein Alias zugewiesen wird, die ORDER
BY
-Klausel den Alias und nicht den Spaltennamen
referenzieren. Die erste der folgenden Anweisungen
funktioniert – im Gegensatz zur zweiten, die mit dem Fehler
Unknown column 'a' in 'order clause'
fehlschlägt:
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b; (SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;
Um ORDER BY
oder LIMIT
auf eine einzelne SELECT
-Anweisung
anzuwenden, setzen Sie die Klausel mit in die Klammern, die
die SELECT
-Anweisung umschließen:
(SELECT a FROMtbl_name
WHERE a=10 AND B=1 ORDER BY a LIMIT 10) UNION (SELECT a FROMtbl_name
WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Das Einfügen von ORDER BY
bei einzelnen
SELECT
-Anweisungen in Klammern hat nur in
Kombination mit LIMIT
Auswirkungen.
Andernfalls wird ORDER BY
wegoptimiert.
Typen und Längen der Spalten in der Ergebnismenge einer Union
berücksichtigen Werte, die von allen
SELECT
-Anweisungen abgerufen wurden.
Betrachten Sie etwa einmal Folgendes:
mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a |
| bbbbbbbbbb |
+---------------+
In einigen früheren Versionen von MySQL würde der zweite Datensatz auf eine Länge von 1 gekürzt.
ANY
, IN
und
SOME
ALL
EXISTS
und NOT EXISTS
FROM
-Klausel
Eine Unterabfrage ist eine SELECT
-Anweisung
innerhalb einer anderen Anweisung.
Seit MySQL 4.1 werden alle Unterabfrageformen und -operationen, die der SQL-Standard vorsieht, ebenso unterstützt wie einige weitere Funktionen, die MySQL-spezifisch sind.
Hier ein Beispiel für eine Unterabfrage:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
In diesem Beispiel ist SELECT * FROM t1 ...
die äußere Abfrage (oder
äußere Anweisung), und (SELECT
column1 FROM t2)
ist die
Unterabfrage. Man sagt, die Unterabfrage
ist in der äußeren Abfrage verschachtelt,
und tatsächlich ist es möglich, Unterabfragen bis zu einer
beträchtlichen Tiefe zu verschachteln. Eine Unterabfrage muss
immer in Klammern stehen.
Unterabfragen haben die folgenden Vorteile:
Sie gestatten Abfragen, die strukturiert sind. Auf diese Weise ist es möglich, jeden Teil einer Anweisung zu isolieren.
Sie bieten alternative Wege zur Durchführung von Operationen, die andernfalls komplexe Joins und Unions erfordern würden.
Sie sind – zumindest nach Meinung vieler – lesbar. Die Unterabfragen waren die eigentliche Innovation, aufgrund derer man auf die Idee kam, SQL seinerzeit als „strukturierte Abfragesprache“ zu bezeichnen.
Hier eine Beispielanweisung, die die wichtigsten Aspekte der Unterabfragensyntax zeigt, wie sie im SQL-Standard spezifiziert ist und von MySQL unterstützt wird:
DELETE FROM t1 WHERE s11 > ANY (SELECT COUNT(*) /* no hint */ FROM t2 WHERE NOT EXISTS (SELECT * FROM t3 WHERE ROW(5*t2.s1,77)= (SELECT 50,11*s1 FROM t4 UNION SELECT 50,77 FROM (SELECT * FROM t5) AS t5)));
Eine Unterabfrage kann einen Skalar (einen einzelnen Wert), einen einzelnen Datensatz, eine einzelne Spalte oder eine Tabelle (d. h. eine oder mehrere Spalten von einem oder mehreren Datensätzen) zurückgeben. Man bezeichnet diese als Skalar-, Spalten-, Datensatz- und Tabellenunterabfragen. Unterabfragen, die einen bestimmten Ergebnistyp zurückgeben, können häufig nur in bestimmten Kontexten verwendet werden, die in den folgenden Abschnitten beschrieben werden.
Es gibt ein paar wenige Einschränkungen bezüglich des Typs der
Anweisungen, in denen Unterabfragen verwendet werden können.
Eine Unterabfrage kann die gleichen Schlüsselwörter oder
Klauseln enthalten wie eine gewöhnliche
SELECT
-Anweisung:
DISTINCT
, GROUP BY
,
ORDER BY
, LIMIT
, Joins,
Indexhinweise, UNION
-Konstrukte, Kommentare,
Funktionen usw.
Eine Einschränkung besteht darin, dass die äußere Anweisung
einer Unterabfrage einen der folgenden Typen aufweisen muss:
SELECT
, INSERT
,
UPDATE
, DELETE
,
SET
oder DO
. Eine weitere
Einschränkung ist die Tatsache, dass Sie eine Tabelle derzeit
nicht ändern und gleichzeitig in einer Unterabfrage eine
Auswahl aus dieser Tabelle treffen können. Dies gilt für
Anweisungen wie DELETE
,
INSERT
, REPLACE
,
UPDATE
und (da Unterabfragen in der
SET
-Klausel verwendet werden können)
LOAD DATA INFILE
. Eine umfassendere
Beschreibung der Einschränkungen bei Unterabfragen finden Sie
in Abschnitt I.3, „Beschränkungen von Unterabfragen“.
In ihrer einfachsten Form ist eine Unterabfrage eine
Skalarunterabfrage, die einen Einzelwert zurückgibt. Eine
Skalarunterabfrage ist ein einfacher Operand, und Sie können
sie fast überall dort benutzen, wo ein einzelner Spaltenwert
oder ein Literal zulässig ist. Sie können dabei
voraussetzen, dass eine solche Unterabfrage die Eigenschaften
aufweist, die alle Operanden haben: einen Datentyp, eine
Länge, eine Angabe dazu, ob sie NULL
sein
darf oder nicht usw. Zum Beispiel:
CREATE TABLE t1 (s1 INT, s2 CHAR(5) NOT NULL); INSERT INTO t1 VALUES(100, 'abcde'); SELECT (SELECT s2 FROM t1);
Die Unterabfrage in dieser SELECT
-Anweisung
gibt einen einzelnen Wert ('abcde'
)
zurück, der den Datentyp CHAR
und die
Länge 5 aufweist, Zeichensatz und Sortierfolge den mit
CREATE TABLE
konfigurierten Vorgaben
entnimmt und die Information enthält, dass der Wert in der
Spalte auch NULL
sein kann. Tatsächlich
können fast alle Unterabfragen NULL
werden. Wäre die im Beispiel verwendete Tabelle leer, dann
wäre der Wert der Unterabfrage NULL
.
Es gibt nur ganz wenig Kontexte, in denen eine skalare
Unterabfrage nicht verwendet werden kann. Wenn eine Anweisung
nur einen literalen Wert zulässt, können Sie keine
Unterabfrage einsetzen. So erfordert beispielsweise
LIMIT
literale Integer-Argumente, und
LOAD DATA INFILE
verlangt einen literalen
String für den Dateinamen. Zur Übermittlung solcher Werte
können Sie Unterabfragen nicht benutzen.
Wenn die Beispiele in den folgenden Abschnitten das recht
spartanische Konstrukt (SELECT column1 FROM
t1)
enthalten, dann vergegenwärtigen Sie sich, dass
Ihr eigener Code wesentlich komplexere und unterschiedlichere
Konstruktionen enthalten kann (und wird).
Nehmen wir an, wir erstellen zwei Tabellen:
CREATE TABLE t1 (s1 INT); INSERT INTO t1 VALUES (1); CREATE TABLE t2 (s1 INT); INSERT INTO t2 VALUES (2);
Nun führen Sie eine SELECT
-Anweisung aus:
SELECT (SELECT s1 FROM t2) FROM t1;
Das Ergebnis ist 2
, weil in Tabelle
t2
eine Spalte s1
vorhanden ist, die den Wert 2
hat.
Eine skalare Unterabfrage kann Teil eines Ausdrucks sein. Denken Sie aber immer an die Klammern – auch dann, wenn die Unterabfrage ein Operand ist, der ein Argument für eine Funktion bereitstellt. Zum Beispiel:
SELECT UPPER((SELECT s1 FROM t1)) FROM t2;
Die häufigste Form einer Unterabfrage hat das folgende Aussehen:
non_subquery_operand
comparison_operator
(subquery
)
Hierbei ist comparison_operator
einer der folgenden Operatoren:
= > < >= <= <>
Zum Beispiel:
... 'a' = (SELECT column1 FROM t1)
Früher befand sich der einzige zulässige Ort für eine Unterabfrage auf der rechten Seite eines Vergleichs; einige wenige alte Datenbanksysteme halten nach wie vor an dieser Regel fest.
Hier ein Beispiel für einen Unterabfragenvergleich in der
gängigen Form, den Sie mit einem Join nicht durchführen
können. Hierbei werden alle Werte in Tabelle
t1
gefunden, die einem Maximalwert in
Tabelle t2
entsprechen:
SELECT column1 FROM t1 WHERE column1 = (SELECT MAX(column2) FROM t2);
Es folgt ein weiteres Beispiel, welches ebenfalls mit einem
Join nicht zu realisieren ist, da für eine der Tabellen eine
Zusammenfassung erfolgt. Gefunden werden hier alle Datensätze
in der Tabelle t1
, die einen Wert
enthalten, der in einer gegebenen Spalte zweimal auftritt:
SELECT * FROM t1 AS t WHERE 2 = (SELECT COUNT(*) FROM t1 WHERE t1.id = t.id);
Bei einem Vergleich, der mit einem dieser Operatoren
durchgeführt wird, muss die Unterabfrage einen Skalar
zurückgeben. Eine Ausnahme besteht lediglich darin, dass
=
mit Datensatzunterabfragen verwendet
werden kann. Siehe auch Abschnitt 13.2.8.5, „Zeilenunterabfragen“.
Syntax:
operand
comparison_operator
ANY (subquery
)operand
IN (subquery
)operand
comparison_operator
SOME (subquery
)
Das Schlüsselwort ANY
, das einem
Vergleichsoperator folgen muss, bedeutet „Gib
TRUE
zurück, wenn der Vergleich für jeden
beliebigen Wert in der Spalte, die die Unterabfrage
zurückgibt, wahr ist“. Zum Beispiel:
SELECT s1 FROM t1 WHERE s1 > ANY (SELECT s1 FROM t2);
Nehmen wir an, dass die Tabelle t1
einen
Datensatz mit dem Inhalt (10)
umfasst. Der
Ausdruck ist wahr, wenn Tabelle t2
(21,14,7)
enthält, weil ein Wert
7
in t2
vorhanden ist,
der kleiner als 10
ist. Der Ausdruck ist
hingegen falsch, wenn Tabelle t2
(20,10)
enthält oder leer ist. Der
Ausdruck ist schließlich unbekannt
(UNKNOWN
), wenn Tabelle
t2
(NULL,NULL,NULL)
enthält.
Das Wort IN
ist ein Alias für =
ANY
. Insofern sind die folgenden beiden Anweisungen
gleichwertig:
SELECT s1 FROM t1 WHERE s1 = ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 IN (SELECT s1 FROM t2);
Allerdings ist NOT IN
kein Alias für
<> ANY
, wohl aber für
<> ALL
. Siehe auch
Abschnitt 13.2.8.4, „Unterabfragen mit ALL
“.
Das Wort SOME
ist ein Alias für
ANY
. Insofern sind die folgenden beiden
Anweisungen gleichwertig:
SELECT s1 FROM t1 WHERE s1 <> ANY (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 <> SOME (SELECT s1 FROM t2);
Das Wort SOME
wird zwar nur selten
verwendet, dieses Beispiel zeigt aber, wofür es nützlich
sein kann. Die meisten Menschen fassen die Phrase „a ist
nicht gleich irgendeinem b“ als „Es gibt kein b,
welches gleich a ist“ auf, aber das ist bei der
SQL-Syntax nicht gemeint. Hier bedeutet dies vielmehr
„Es gibt (mindestens) ein b, dem a nicht gleich
ist“. Indem Sie stattdessen <>
SOME
verwenden, gewährleisten Sie, dass jeder die
tatsächliche Meinung der Abfrage versteht.
Syntax:
operand
comparison_operator
ALL (subquery
)
Das Wort ALL
, das einem Vergleichsoperator
folgen muss, bedeutet „Gib TRUE
zurück, wenn der Vergleich für jeden beliebigen Wert in der
Spalte, die die Unterabfrage zurückgibt, wahr ist“.
Zum Beispiel:
SELECT s1 FROM t1 WHERE s1 > ALL (SELECT s1 FROM t2);
Nehmen wir an, dass die Tabelle t1
einen
Datensatz mit dem Inhalt (10)
umfasst. Der
Ausdruck ist wahr, wenn Tabelle t2
(-5,0,+5)
enthält, weil
10
größer als alle drei Werte in
t2
ist. Der Ausdruck ist hingegen falsch,
wenn Tabelle t2
(12,6,NULL,-100)
enthält, weil es einen
Wert (12
) in Tabelle t2
gibt, der größer als 10
ist. Der Ausdruck
ist unbekannt (d. h.
NULL
), wenn Tabelle t2
(0,NULL,1)
enthält.
Schließlich ist, wenn Tabelle t2
leer ist,
das Ergebnis wahr. Aufgrund dessen ist die folgende Anweisung
wahr, wenn Tabelle t2
leer ist:
SELECT * FROM t1 WHERE 1 > ALL (SELECT s1 FROM t2);
Folgende Anweisung ist hingegen NULL
, wenn
Tabelle t2
leer ist:
SELECT * FROM t1 WHERE 1 > (SELECT s1 FROM t2);
Ferner ist auch folgende Anweisung NULL
,
wenn Tabelle t2
leer ist:
SELECT * FROM t1 WHERE 1 > ALL (SELECT MAX(s1) FROM t2);
Generell sind Tabellen, die
NULL
-Werte enthalten, und
leere Tabellen Grenzfälle. Wenn Sie
Unterabfragencode formulieren, vergewissern Sie sich immer,
dass Sie diese beiden Fälle berücksichtigt haben.
NOT IN
ist ein Alias für <>
ALL
. Insofern sind die folgenden beiden Anweisungen
gleichwertig:
SELECT s1 FROM t1 WHERE s1 <> ALL (SELECT s1 FROM t2); SELECT s1 FROM t1 WHERE s1 NOT IN (SELECT s1 FROM t2);
Bis zu diesem Punkt haben wir ausschließlich Skalar- und Spaltenunterabfragen beschrieben, also Unterabfragen, die einen einzelnen Wert oder eine Wertespalte zurückgeben. Eine Datensatzunterabfrage ist eine Unterabfragenvariante, die einen einzelnen Datensatz zurückgibt – und insofern auch mehrere Spaltenwerte zurückgeben kann. Hier zwei Beispiele:
SELECT * FROM t1 WHERE (1,2) = (SELECT column1, column2 FROM t2); SELECT * FROM t1 WHERE ROW(1,2) = (SELECT column1, column2 FROM t2);
Die gezeigten Abfragen sind beide wahr, wenn Tabelle
t2
einen Datensatz enthält, bei dem
column1 = 1
und column2 =
2
sind.
Die Ausdrücke (1,2)
und
ROW(1,2)
heißen manchmal auch
Datensatzkonstruktoren. Beide sind
äquivalent. Sie sind zudem auch in anderen Kontexten
zulässig. So sind etwa die beiden folgenden Anweisungen
semantisch äquivalent (obwohl derzeit nur die zweite
optimiert werden kann):
SELECT * FROM t1 WHERE (column1,column2) = (1,1); SELECT * FROM t1 WHERE column1 = 1 AND column2 = 1;
Der normale Anwendungsfall von Datensatzkonstruktoren sind
Vergleiche mit Unterabfragen, die zwei oder mehr Spalten
zurückgeben. So entspricht die folgende Abfrage der
Aufforderung „Suche alle Datensätze in Tabelle
t1
, die auch in Tabelle
t2
vorhanden sind“:
SELECT column1,column2,column3 FROM t1 WHERE (column1,column2,column3) IN (SELECT column1,column2,column3 FROM t2);
Wenn eine Unterabfrage irgendwelche Datensätze zurückgibt,
ist EXISTS
wahr und
subquery
NOT EXISTS
ist falsch. Zum
Beispiel:
subquery
SELECT column1 FROM t1 WHERE EXISTS (SELECT * FROM t2);
Traditionell beginnt eine
EXISTS
-Unterabfrage mit SELECT
*
, sie könnte aber auch mit SELECT
5
oder SELECT column1
oder etwas
ganz anderem anfangen: MySQL ignoriert die
SELECT
-Liste in einer solchen Unterabfrage,
mithin macht es keinen Unterschied.
Bei obigem Beispiel ist die Bedingung wahr, wenn
t2
überhaupt Datensätze enthält (und
sogar dann, wenn es sich ausschließlich um
NULL
-Werte handelt). Dies ist aber ein
recht abwegiges Beispiel, weil eine [NOT]
EXISTS
-Unterabfrage fast immer Korrelationen
enthält. Hier einige pragmatischere Beispiele:
Welche Arten von Geschäften sind in einer oder mehreren Städten vorhanden?
SELECT DISTINCT store_type FROM stores WHERE EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
Welche Art von Geschäften ist in keiner Stadt vorhanden?
SELECT DISTINCT store_type FROM stores WHERE NOT EXISTS (SELECT * FROM cities_stores WHERE cities_stores.store_type = stores.store_type);
Welche Art von Geschäften ist in allen Städten vorhanden?
SELECT DISTINCT store_type FROM stores s1 WHERE NOT EXISTS ( SELECT * FROM cities WHERE NOT EXISTS ( SELECT * FROM cities_stores WHERE cities_stores.city = cities.city AND cities_stores.store_type = stores.store_type));
Das letzte Beispiel ist eine doppelt verschachtelte
NOT EXISTS
-Abfrage: Sie enthält eine
NOT EXISTS
-Klausel in einer NOT
EXISTS
-Klausel. Formell beantwortet sie die Frage
„Gibt es eine Stadt mit einem Geschäft, das nicht in
Stores
vorhanden ist?“. Aber es ist
einfacher zu sagen, dass eine verschachtelte NOT
EXISTS
-Klausel die Frage „Ist
x
für alle
y
wahr?“ beantwortet.
Eine korrelierte Unterabfrage ist eine Unterabfrage, die eine Tabelle referenziert, die auch in der äußeren Abfrage erscheint. Zum Beispiel:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2 WHERE t2.column2 = t1.column2);
Beachten Sie, dass die Unterabfrage eine Spalte von
t1
referenziert, obwohl die
FROM
-Klausel der Unterabfrage keine Tabelle
t1
erwählt. Also sucht MySQL außerhalb
der Unterabfrage und findet t1
in der
äußeren Abfrage.
Angenommen, Tabelle t1
enthielte einen
Datensatz, bei dem column1 = 5
und
column2 = 6
sind. Gleichzeitig enthält
Tabelle t2
einen Datensatz, bei dem
column1 = 5
und column2 =
7
sind. Der einfache Ausdruck ... WHERE
column1 = ANY (SELECT column1 FROM t2)
wäre wahr,
aber in diesem Beispiel ist die
WHERE
-Klausel innerhalb der Unterabfrage
falsch (weil nämlich (5,6)
nicht gleich
(5,7)
); also ist auch die Unterabfrage als
Ganzes falsch.
Bereichsregel: MySQL wertet von innen nach außen aus. Zum Beispiel:
SELECT column1 FROM t1 AS x WHERE x.column1 = (SELECT column1 FROM t2 AS x WHERE x.column1 = (SELECT column1 FROM t3 WHERE x.column2 = t3.column1));
In dieser Anweisung muss x.column2
eine
Spalte in der Tabelle t2
sein, weil
SELECT column1 FROM t2 AS x ...
t2
umbenennt. Es ist keine Spalte in
Tabelle t1
, weil SELECT column1
FROM t1 ...
eine äußere Abfrage ist, die
weiter außen ist.
Bei Unterabfragen in HAVING
- oder
ORDER BY
-Klauseln sucht MySQL auch nach
Spaltennamen in der äußeren Auswahlliste.
In bestimmten Fällen wird eine korrelierte Unterabfrage optimiert. Zum Beispiel:
val
IN (SELECTkey_val
FROMtbl_name
WHEREcorrelated_condition
)
Andernfalls sind sie ineffizient und zudem wahrscheinlich recht langsam. Das Umschreiben der Abfrage als Join kann die Leistung unter Umständen verbessern.
Korrelierte Unterabfragen können Ergebnisse von Zusammenfassungsfunktionen in der äußeren Abfrage nicht referenzieren.
Unterabfragen sind in der FROM
-Klausel
einer SELECT
-Anweisung zulässig. Die
eigentliche Syntax lautet:
SELECT ... FROM (subquery
) [AS]name
...
Die [AS]
-Klausel ist
obligatorisch, weil jede Tabelle in einer
name
FROM
-Klausel einen Namen haben muss. Alle
Spalten, die in der
subquery
-Auswahlliste aufgeführt
sind, benötigen eindeutige Namen. Sie finden diese Syntax an
anderer Stelle in diesem Handbuch beschrieben. Dort wird der
Begriff „abgeleitete Tabellen“ verwendet.
Zur Veranschaulichung nehmen wir an, dass Sie folgende Tabelle haben:
CREATE TABLE t1 (s1 INT, s2 CHAR(5), s3 FLOAT);
Eine Unterabfrage in der FROM
-Klausel
verwenden Sie bei der Beispieltabelle wie folgt:
INSERT INTO t1 VALUES (1,'1',1.0); INSERT INTO t1 VALUES (2,'2',2.0); SELECT sb1,sb2,sb3 FROM (SELECT s1 AS sb1, s2 AS sb2, s3*2 AS sb3 FROM t1) AS sb WHERE sb1 > 1;
Ergebnis: 2, '2', 4.0
.
Es folgt ein weiteres Beispiel: Nehmen wir an, Sie wollen den Durchschnitt einer Anzahl von Summen für eine gruppierte Tabelle ermitteln. Folgendes funktioniert nicht:
SELECT AVG(SUM(column1)) FROM t1 GROUP BY column1;
Die nächste Abfrage dagegen übermittelt die gewünschte Information:
SELECT AVG(sum_column1) FROM (SELECT SUM(column1) AS sum_column1 FROM t1 GROUP BY column1) AS t1;
Beachten Sie, dass der Spaltenname, der in der Unterabfrage
verwendet wird (sum_column1
), in der
äußeren Abfrage erkannt wird.
Unterabfragen in der FROM
-Klausel können
einen Skalar, eine Spalte, einen Datensatz oder eine Tabelle
zurückgeben. Unterabfragen in der
FROM
-Klausel dürfen keine korrelierten
Unterabfragen sein.
Unterabfragen in der FROM
-Klausel werden
auch für die EXPLAIN
-Anweisung ausgeführt
(d. h., es werden abgeleitete Temporärtabellen erstellt).
Grund hierfür ist, dass Abfragen höherer Ebenen während der
Optimierungsphase Informationen zu allen Tabellen benötigen.
Es gibt eine Reihe von Fehlern, die sich nur auf Unterabfragen beziehen. Sie werden in diesem Abschnitt beschrieben.
Falsche Anzahl von Spalten aus der Unterabfrage:
ERROR 1241 (ER_OPERAND_COL) SQLSTATE = 21000 Message = "Operand should contain 1 column(s)"
Dieser Fehler tritt in Fällen wie dem folgenden auf:
SELECT (SELECT column1, column2 FROM t2) FROM t1;
Sie können eine Unterabfrage verwenden, die mehrere Spalten zurückgibt, sofern das Ziel ein Vergleich ist. Siehe auch Abschnitt 13.2.8.5, „Zeilenunterabfragen“. Allerdings muss die Unterabfrage in anderen Kontexten ein skalarer Operand sein.
Falsche Anzahl von Datensätzen aus der Unterabfrage:
ERROR 1242 (ER_SUBSELECT_NO_1_ROW) SQLSTATE = 21000 Message = "Subquery returns more than 1 row"
Dieser Fehler tritt bei Anweisungen auf, bei denen die Unterabfrage mehr als einen Datensatz zurückgibt. Betrachten Sie einmal das folgende Beispiel:
SELECT * FROM t1 WHERE column1 = (SELECT column1 FROM t2);
Wenn SELECT column1 FROM t2
nur einen
Datensatz zurückgibt, funktioniert obige Abfrage. Gibt
die Abfrage jedoch mehrere Datensätze zurück, dann tritt
der Fehler 1242 auf. In diesem Fall sollten Sie die
Abfrage wie folgt neu formulieren:
SELECT * FROM t1 WHERE column1 = ANY (SELECT column1 FROM t2);
Falsch verwendete Tabelle in der Unterabfrage:
Error 1093 (ER_UPDATE_TABLE_USED) SQLSTATE = HY000 Message = "You can't specify target table 'x' for update in FROM clause"
Dieser Fehler tritt in Fällen wie dem folgenden auf:
UPDATE t1 SET column2 = (SELECT MAX(column1) FROM t1);
Sie können eine Unterabfrage zur Zuweisung innerhalb
einer UPDATE
-Anweisung verwenden, da
Unterabfragen in UPDATE
- und
DELETE
-Anweisungen ebenso zulässig
sind wie in SELECT
-Anweisungen.
Allerdings können Sie nicht dieselbe Tabelle (in diesem
Fall Tabelle t1
) sowohl in der
FROM
-Klausel der Unterabfrage als auch
als Aktualisierungsziel angeben.
Bei transaktionssicheren Speicher-Engines schlägt bei einem Fehlschlag einer Unterabfrage die gesamte Anweisung fehl. Bei nichttransaktionssicheren Speicher-Engines bleiben Datenänderungen, die vor Auftreten des Fehlers durchgeführt wurden, erhalten.
Die Entwicklung erfolgt kontinuierlich, d. h., Optimierungstipps sind niemals auf Dauer gültig. Die folgende Liste zeigt einige interessante Tricks, mit denen Sie ein wenig herumprobieren können:
Verwendung von Klauseln in Unterabfragen, die die Anzahl oder Reihenfolge der Datensätze in der Unterabfrage betreffen. Zum Beispiel:
SELECT * FROM t1 WHERE t1.column1 IN (SELECT column1 FROM t2 ORDER BY column1); SELECT * FROM t1 WHERE t1.column1 IN (SELECT DISTINCT column1 FROM t2); SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 LIMIT 1);
Ersetzen Sie einen Join durch eine Unterabfrage. Probieren Sie z. B. Folgendes aus.
SELECT DISTINCT column1 FROM t1 WHERE t1.column1 IN ( SELECT column1 FROM t2);
So hätte dies ursprünglich ausgesehen:
SELECT DISTINCT t1.column1 FROM t1, t2 WHERE t1.column1 = t2.column1;
Einige Unterabfragen können aus Gründen der Kompatibilität mit älteren MySQL-Versionen, die Unterabfragen nicht unterstützen, in Joins umgewandelt werden. Allerdings wird hierdurch in einigen Fällen die Leistungsfähigkeit beeinträchtigt. Siehe auch Abschnitt 13.2.8.11, „Umschreiben von Unterabfragen in Joins für frühere MySQL-Versionen“.
Verschieben Sie Klauseln von außen in die Unterabfrage. Verwenden Sie beispielsweise diese Abfrage …
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1 UNION ALL SELECT s1 FROM t2);
… statt dieser:
SELECT * FROM t1 WHERE s1 IN (SELECT s1 FROM t1) OR s1 IN (SELECT s1 FROM t2);
Ein weiteres Beispiel: Verwenden Sie diese Abfrage …
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
… statt dieser:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
Verwenden Sie eine Datensatzunterabfrage statt einer korrelierten Unterabfrage. Verwenden Sie beispielsweise diese Abfrage …
SELECT * FROM t1 WHERE (column1,column2) IN (SELECT column1,column2 FROM t2);
… statt dieser:
SELECT * FROM t1 WHERE EXISTS (SELECT * FROM t2 WHERE t2.column1=t1.column1 AND t2.column2=t1.column2);
Verwenden Sie NOT (a = ANY (...))
statt
a <> ALL (...)
.
Verwenden Sie x = ANY (
statt
table
containing (1,2)
)x=1 OR x=2
.
Verwenden Sie = ANY
statt
EXISTS
.
Bei unkorrelierten Unterabfragen, die immer genau einen
Datensatz zurückgeben, ist IN
immer
langsamer als =
. Verwenden Sie
beispielsweise diese Abfrage …
SELECT * FROM t1 WHERE t1.col_name
= (SELECT a FROM t2 WHERE b =some_const
);
… statt dieser:
SELECT * FROM t1 WHERE t1.col_name
IN (SELECT a FROM t2 WHERE b =some_const
);
Aufgrund dieser Tricks können Programme schneller, aber auch
langsamer werden. Mithilfe von MySQL-Funktionen wie
BENCHMARK()
können Sie überprüfen, was
in Ihrer speziellen Situation hilfreich sein kann. Siehe auch
Abschnitt 12.10.3, „Informationsfunktionen“.
Die folgenden Optimierungen nimmt MySQL selbst vor:
MySQL führt nichtkorrelierte Unterabfragen nur einmal
aus. Mit EXPLAIN
können Sie
sicherstellen, dass eine gegebene Unterabfrage wirklich
nichtkorreliert ist.
MySQL schreibt IN
-,
ALL
-, ANY
- und
SOME
-Unterabfragen neu, um möglichst
davon zu profitieren, dass die Auswahllistenspalten in der
Unterabfrage indiziert sind.
MySQL ersetzt Unterabfragen der folgenden Form durch eine
Indexsuchfunktion, die EXPLAIN
als
speziellen Join-Typ beschreibt
(unique_subquery
oder
index_subquery
):
... IN (SELECTindexed_column
FROMsingle_table
...)
MySQL erweitert Ausdrücke der folgenden Form mit einem
Ausdruck mit MIN()
oder
MAX()
, sofern
NULL
-Werte oder Leermengen vorhanden
sind:
value
{ALL|ANY|SOME} {> | < | >= | <=} (non-correlated subquery
)
Betrachten Sie etwa folgende
WHERE
-Klausel:
WHERE 5 > ALL (SELECT x FROM t)
Diese könnte vom Optimierer wie folgt geändert werden:
WHERE 5 > (SELECT MAX(x) FROM t)
Es gibt ein Kapitel „How MySQL Transforms Subqueries“ („Wie MySQL Unterabfragen transformiert“) im Handbuch „MySQL Internals“ (MySQL-Interna, derzeit nur auf Englisch verfügbar), welches Sie unter http://dev.mysql.com/doc/ erhalten.
Bei älteren MySQL-Versionen (vor Version 4.1) wurden nur
verschachtelte Abfragen der Formen INSERT ... SELECT
...
und REPLACE ... SELECT ...
unterstützt. Zwar trifft dies bei MySQL 5.1
nicht mehr zu, aber nach wie vor werden gelegentlich andere
Möglichkeiten eingesetzt, um auf Mitgliedschaft in einer
Wertemenge zu prüfen. Außerdem ist es unter bestimmten
Umständen nicht nur möglich, eine Abfrage ohne Unterabfrage
zu schreiben, sondern es kann auch effizienter sein, einige
der folgenden Methoden zu verwenden, statt Unterabfragen
einzusetzen. Eine dieser Methode ist das Konstrukt
IN()
:
Betrachten Sie etwa folgende Abfrage:
SELECT * FROM t1 WHERE id IN (SELECT id FROM t2);
Sie kann wie folgt umgeschrieben werden:
SELECT DISTINCT t1.* FROM t1, t2 WHERE t1.id=t2.id;
Ein anderes Beispiel sind folgende Abfragen:
SELECT * FROM t1 WHERE id NOT IN (SELECT id FROM t2); SELECT * FROM t1 WHERE NOT EXISTS (SELECT id FROM t2 WHERE t1.id=t2.id);
Auch sie lassen sich mithilfe von IN()
umschreiben:
SELECT table1.* FROM table1 LEFT JOIN table2 ON table1.id=table2.id WHERE table2.id IS NULL;
Ein LEFT [OUTER] JOIN
kann schneller sein
als die äquivalente Unterabfrage, weil der Server unter
Umständen in der Lage ist, ihn besser zu optimieren – eine
Tatsache, die nicht nur für den MySQL Server gilt. Vor SQL-92
waren äußere Joins nicht vorhanden, d. h., Unterabfragen
stellten für bestimmte Aufgaben die einzige Lösung dar.
Heute bieten MySQL Server und viele andere moderne
Datenbanksysteme eine Vielzahl von Typen für äußere Joins.
MySQL Server unterstützt
DELETE
-Anweisungen über mehrere Tabellen,
die zur effizienten gleichzeitigen Löschung von Datensätzen
basierend auf Daten in einer Tabelle (oder sogar mehreren
Tabellen) benutzt werden. Auch
UPDATE
-Anweisungen über mehrere Tabellen
werden unterstützt.
TRUNCATE [TABLE] tbl_name
TRUNCATE TABLE
leert eine Tabelle
vollständig. Logisch gesehen ist dies äquivalent zu einer
DELETE
-Anweisung, die alle Datensätze
löscht, aber es gibt unter bestimmten Umständen praktische
Unterschiede.
Bei InnoDB
-Tabellen wird TRUNCATE
TABLE
auf DELETE
umgesetzt, sofern
keine Fremdschlüssel-Constraints vorhanden sind, die die
Tabelle referenzieren; andernfalls wird das schnelle Leeren
(durch Löschen und Neuerstellen der Tabelle) verwendet. Der
AUTO_INCREMENT
-Zähler wird von
TRUNCATE TABLE
unabhängig vom Vorhandensein
eines Fremdschlüssel-Constraints zurückgesetzt.
Bei anderen Speicher-Engines unterscheidet sich
TRUNCATE TABLE
in MySQL 5.1 wie
folgt von DELETE
:
Leerungsoperationen löschen die Tabelle und erstellen sie dann neu, was wesentlich schneller ist als das aufeinander folgende Löschen aller Datensätze.
Leerungsoperationen sind nicht transaktionssicher: Wenn Sie eine solche Operation während einer aktiven Transaktion oder einer aktiven Tabellensperrung durchführen wollen, tritt ein Fehler auf.
Die Anzahl gelöschter Datensätze wird nicht zurückgegeben.
Solange die Tabellenformatdatei
gültig ist, lässt sich die Tabelle mit tbl_name
.frmTRUNCATE
TABLE
auch dann als leere Tabelle neu erstellen,
wenn die Daten- oder Indexdateien beschädigt wurden.
Der Tabellen-Handler speichert den zuletzt verwendeten
AUTO_INCREMENT
-Wert nicht, sondern fängt
mit der Zählung von vorne an. Dies gilt auch für
MyISAM
- und
InnoDB
-Tabellen, die Sequenzwerte
normalerweise nicht erneut verwenden.
Bei der Verwendung mit partitionierten Tabellen behält
TRUNCATE TABLE
die Partitionierung bei,
d. h., Daten- und Indexdateien werden gelöscht und neu
erstellt, während die Partitionsdefinitionsdatei
(.par
) hiervon unberührt bleibt.
TRUNCATE TABLE
ist eine Oracle
SQL-Erweiterung, die in MySQL übernommen wurde.
Syntax für eine Tabelle:
UPDATE [LOW_PRIORITY] [IGNORE]tbl_name
SETcol_name1
=expr1
[,col_name2
=expr2
...] [WHEREwhere_condition
] [ORDER BY ...] [LIMITrow_count
]
Syntax für mehrere Tabellen:
UPDATE [LOW_PRIORITY] [IGNORE]table_references
SETcol_name1
=expr1
[,col_name2
=expr2
...] [WHEREwhere_condition
]
Bei der Ein-Tabellen-Syntax aktualisiert die
UPDATE
-Anweisung Spalten in vorhandenen
Datensätzen in tbl_name
mit neuen Werten.
Die SET
-Klausel gibt an, welche Spalten
geändert werden und welche Werte diese erhalten sollen. Sofern
angegeben, bestimmt die WHERE
-Klausel die
Bedingungen dafür, welche Datensätze geändert werden. Ohne
WHERE
-Klausel werden alle Datensätze
aktualisiert. Wenn die ORDER BY
-Klausel
vorhanden ist, werden die Datensätze in der angegebenen
Reihenfolge aktualisiert. Die LIMIT
-Klausel
kann die Anzahl der zu aktualisierenden Datensätze
beschränken.
Bei der Mehrtabellensyntax aktualisiert
UPDATE
in jeder Tabelle
table_references
die Datensätze, die
die Bedingungen erfüllen. In diesem Fall können ORDER
BY
und LIMIT
nicht verwendet
werden.
where_condition
ist ein Ausdruck, der
für jeden zu aktualisierenden Datensatz wahr ist. Er wird wie
in Abschnitt 13.2.7, „SELECT
“, beschrieben angegeben.
Die UPDATE
-Anweisung unterstützt die
folgenden Modifizierer:
Wenn Sie das Schlüsselwort LOW_PRIORITY
angeben, wird die Ausführung von UPDATE
verzögert, bis kein Client mehr aus der Tabelle liest.
Wenn Sie das Schlüsselwort IGNORE
verwenden, bricht die UPDATE
-Anweisung
auch dann nicht ab, wenn während der Aktualisierung Fehler
auftreten. Datensätze, bei denen Konflikte aufgrund von
Schlüsseldubletten auftreten, werden nicht geändert.
Datensätze, bei denen Spalten auf Werte gesetzt werden
würden, die Datenkonvertierungsfehler zur Folge hätten,
werden stattdessen auf den nächstgelegenen gültigen Wert
gesetzt.
Wenn Sie in einem Ausdruck auf eine Spalte in der Tabelle
tbl_name
zugreifen, verwendet
UPDATE
den aktuellen Wert der Spalte. So
erhöht die folgende Anweisung beispielsweise den aktuellen Wert
in der Spalte age
um 1:
UPDATE persondata SET age=age+1;
UPDATE
-Zuordnungen werden von links nach
rechts ausgewertet. Die folgende Anweisung etwa verdoppelt die
Spalte age
und erhöht sie dann um 1:
UPDATE persondata SET age=age*2, age=age+1;
Wenn Sie eine Spalte auf den Wert aktualisieren, den sie ohnehin gerade hat, dann bemerkt MySQL dies und führt keine Aktualisierung durch.
Wenn Sie eine als NOT NULL
deklarierte Spalte
aktualisieren, indem Sie sie auf NULL
setzen,
wird die Spalte stattdessen auf den für den jeweiligen Datentyp
vorgesehenen Standardwert gesetzt und der Warnungszähler
erhöht. Der Vorgabewert ist 0
bei
numerischen Typen, der Leer-String (''
) bei
String-Typen und der „Nullwert“ für Datums- und
Uhrzeittypen.
UPDATE
gibt die Anzahl der tatsächlich
geänderten Datensätze zurück. Die C-API-Funktion
mysql_info()
hingegen gibt die Anzahl der
Datensätze, die gefunden und aktualisiert wurden, sowie die
Anzahl der Warnungen zurück, die während der
UPDATE
-Operation aufgetreten sind.
Sie können LIMIT
verwenden, um den
Geltungsbereich von row_count
UPDATE
einzuschränken.
Eine LIMIT
-Klausel ist eine Beschränkung
für Datensätze. Die Anweisung endet, sobald eine Anzahl von
row_count
Datensätzen gefunden
wurde, die der WHERE
-Klausel entsprechen –
unabhängig davon, ob sie dann auch geändert wurden oder nicht.
Wenn eine UPDATE
-Anweisung eine
ORDER BY
-Klausel enthält, werden die
Datensätze in der in der Klausel angegebenen Reihenfolge
aktualisiert.
Sie können auch UPDATE
-Operationen
durchführen, die sich auf mehrere Tabellen beziehen. Allerdings
können Sie ORDER BY
oder
LIMIT
nicht in einer
UPDATE
-Anweisung für mehrere Tabellen
verwenden. Die Klausel
table_references
listet die Tabellen
auf, die im Join berücksichtigt werden. Die Syntax ist in
Abschnitt 13.2.7.1, „JOIN
“, beschrieben. Hier ein Beispiel:
UPDATE items,month SET items.price=month.price WHERE items.id=month.id;
Das obige Beispiel zeigt einen inneren Join, der den
Kommaoperator verwendet. UPDATE
-Anweisungen
für mehrere Tabellen können jedoch einen beliebigen Join-Typ
verwenden, der für SELECT
-Anweisungen
zulässig ist, also etwa LEFT JOIN
.
Sie benötigen die Berechtigung UPDATE
nur
für diejenigen in einer UPDATE
-Anweisung
für mehrere Tabellen referenzierten Spalten, die tatsächlich
geändert werden. Die Berechtigung SELECT
hingegen benötigen Sie für alle Spalten, die gelesen, aber
nicht modifiziert werden.
Wenn Sie eine UPDATE
-Anweisung für mehrere
Tabellen verwenden, die auch InnoDB
-Tabellen
einbezieht, für die Fremdschlüssel-Constraints vorhanden sind,
dann verarbeitet der MySQL-Optimierer die Tabellen unter
Umständen in einer Reihenfolge, die sich von der ihrer
Parent/Child-Beziehung unterscheidet. In diesem Fall schlägt
die Anweisung fehl, und es wird ein Rollback durchgeführt.
Stattdessen sollten Sie die Änderung dann in nur einer Tabelle
durchführen und sich auf die ON
UPDATE
-Funktionalität verlassen, die
InnoDB
bietet, um andere Tabellen
entsprechend zu ändern. Siehe auch
Abschnitt 14.2.6.4, „Fremdschlüssel-Beschränkungen“.
Zurzeit können Sie in einer Unterabfrage keine Aktualisierungsoperation in einer Tabelle durchführen und gleichzeitig eine Auswahl in einer anderen Tabelle treffen.
{DESCRIBE | DESC}tbl_name
[col_name
|wild
]
DESCRIBE
vermittelt Informationen zu Spalten
in einer Tabelle. Es handelt sich um ein Synonym für
SHOW COLUMNS FROM
. Diese Anweisungen erlauben
auch die Anzeige von Informationen zu Views. (Siehe auch
Abschnitt 13.5.4.3, „SHOW COLUMNS
“.)
col_name
kann ein Spaltenname oder
aber ein String sein, der die SQL-Jokerzeichen
‘%
’ und
‘_
’ enthält, um eine Ausgabe nur
zu Spalten zu erhalten, die dem String entsprechen. Sie müssen
den String nicht in Anführungszeichen setzen, sofern er nicht
Leerzeichen oder andere Sonderzeichen enthält.
mysql> DESCRIBE city;
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| Id | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| Country | char(3) | NO | UNI | | |
| District | char(20) | YES | MUL | | |
| Population | int(11) | NO | | 0 | |
+------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
Field
gibt den Spaltennamen an.
Das Feld Null
zeigt an, ob
NULL
-Werte in der Spalte gespeichert werden
können.
Das Feld Key
gibt an, ob die Spalte indiziert
ist. Mit PRI
wird angegeben, dass die Spalte
Teil des Primärschlüssels der Tabelle ist, mit
UNI
hingegen, dass sie Teil eines eindeutigen
Indexes ist. Der Wert MUL
schließlich
signalisiert, dass mehrere Instanzen eines gegebenen Werts
innerhalb der Spalte zulässig sind.
Ein möglicher Grund für die Anzeige von MUL
in einem eindeutigen Index besteht darin, dass mehrere Spalten
einen zusammengesetzten eindeutigen Index bilden. Dann ist die
Kombination der Spalten eindeutig, während die einzelnen
Spalten durchaus mehrere Instanzen eines gegebenen Werts
enthalten können. Beachten Sie, dass in einem zusammengesetzten
Index nur die links stehende Spalte einen Eintrag im Feld
Key
hat.
Das Feld Default
gibt den Standardwert der
Spalte an.
Das Feld Extra
enthält zusätzliche Angaben,
die zu einer gegebenen Spalte verfügbar sind. Im gezeigten
Beispiel gibt Extra
an, dass die Spalte
Id
mit dem Schlüsselwort
AUTO_INCREMENT
erstellt wurde.
Die Anweisung DESCRIBE
ist aus Gründen der
Kompatibilität mit Oracle vorhanden.
Auch die Anweisungen SHOW CREATE TABLE
und
SHOW TABLE STATUS
bieten Informationen zu
Tabellen. Siehe auch Abschnitt 13.5.4, „SHOW
“.
USE db_name
Die Anweisung USE
weist MySQL an, die
Datenbank db_name
db_name
als
Standarddatenbank (d. h. als aktuelle Datenbank) zu benutzen,
auf die sich nachfolgende Anweisungen beziehen. Die Datenbank
wird bis zum Ende der Sitzung oder aber so lange als Vorgabe
verwendet, bis eine andere USE
-Anweisung
abgesetzt wird:
USE db1; SELECT COUNT(*) FROM mytable; # selects from db1.mytable USE db2; SELECT COUNT(*) FROM mytable; # selects from db2.mytable
Wenn Sie eine bestimmte Datenbank mit USE
zur
Standarddatenbank machen, können Sie trotzdem auf Tabellen in
anderen Datenbanken zugreifen. Im folgenden Beispiel wird auf
die Tabelle author
in der Datenbank
db1
und die Tabelle editor
in der Datenbank db2
zugegriffen:
USE db1; SELECT author_name,editor_name FROM author,db2.editor WHERE author.editor_id = db2.editor.editor_id;
Die Anweisung USE
ist aus Gründen der
Kompatibilität mit Sybase vorhanden.
MySQL unterstützt lokale Transaktionen (über eine gegebene
Clientverbindung) unter Verwendung von Anweisungen wie
SET AUTOCOMMIT
, START
TRANSACTION
, COMMIT
und
ROLLBACK
. Siehe auch Abschnitt 13.4.1, „BEGIN/COMMIT/ROLLBACK
“.
Die Unterstützung von XA-Transaktionen erlaubt MySQL außerdem
die Teilnahme an verteilten Transaktionen. Siehe auch
Abschnitt 13.4.7, „XA-Transaktionen“.
START TRANSACTION | BEGIN [WORK] COMMIT [WORK] [AND [NO] CHAIN] [[NO] RELEASE] ROLLBACK [WORK] [AND [NO] CHAIN] [[NO] RELEASE] SET AUTOCOMMIT = {0 | 1}
Die Anweisungen START TRANSACTION
und
BEGIN
starten eine neue Transaktion.
COMMIT
übergibt die aktuelle Transaktion,
macht also die entsprechenden Änderungen permanent. Mit
ROLLBACK
machen Sie die laufende Transaktion
rückgängig, d. h., alle Änderungen werden zurückgenommen.
Die Anweisung SET AUTOCOMMIT
schließlich
aktiviert oder deaktiviert den standardmäßigen
Autocommit-Modus für die aktuelle Verbindung.
Das optionale Schlüsselwort WORK
wird für
COMMIT
und RELEASE
unterstützt, ebenso die CHAIN
- und
RELEASE
-Klauseln. CHAIN
und RELEASE
können verwendet werden, um den
Transaktionsabschluss besser steuern zu können. Der Wert der
Systemvariablen completion_type
bestimmt das
Standardverhalten beim Transaktionsabschluss. Siehe auch
Abschnitt 5.2.2, „Server-Systemvariablen“.
Die AND CHAIN
-Klausel bewirkt, dass eine neue
Transaktion beginnt, sobald die aktuelle endet. Die neue
Transaktion hat dabei dieselbe Isolierungsstufe wie die zuvor
beendete Transaktion. Die RELEASE
-Klausel
bewirkt, dass der Server die aktuelle Clientverbindung nach
Abschluss der aktuellen Transaktion beendet. Das Schlüsselwort
NO
unterdrückt den Abschluss von
CHAIN
oder RELEASE
. Dies
kann nützlich sein, wenn aufgrund der Einstellung der
Systemvariablen completion_type
der Abschluss
von CHAIN
oder RELEASE
standardmäßig erzwungen wird.
Standardmäßig läuft MySQL im Autocommit-Modus. Das bedeutet, dass, sobald eine Anweisung ausgeführt wird, die eine Tabelle aktualisiert (also ändert), MySQL diese Änderung auf Festplatte speichert.
Verwenden Sie eine transaktionssichere Speicher-Engine (wie
InnoDB
, BDB
oder
NDB Cluster
), dann können Sie den
Autocommit-Modus mit der folgenden Anweisung deaktivieren:
SET AUTOCOMMIT=0;
Nach der Deaktivierung des Autocommit-Modus durch Setzen der
AUTOCOMMIT
-Variablen auf Null müssen Sie
Ihre Änderungen mit COMMIT
auf Festplatte
speichern oder mit ROLLBACK
rückgängig
machen, wenn Sie die seit Beginn der Transaktion vorgenommenen
Änderungen nicht übernehmen wollen.
Um den Autocommit-Modus für eine einzelne Abfolge von
Anweisungen zu deaktivieren, verwenden Sie die Anweisung
START TRANSACTION
:
START TRANSACTION; SELECT @A:=SUM(salary) FROM table1 WHERE type=1; UPDATE table2 SET summary=@A WHERE type=1; COMMIT;
Bei START TRANSACTION
bleibt Autocommit
deaktiviert, bis Sie die Transaktion mit
COMMIT
oder ROLLBACK
beenden. Der Autocommit-Modus kehrt dann in seinen vorherigen
Status zurück.
BEGIN
und BEGIN WORK
werden als Aliase für START TRANSACTION
benutzt, um eine Transaktion zu starten. START
TRANSACTION
ist die SQL-Standardsyntax und wird als
Möglichkeit zur Durchführung spontaner Transaktionen
empfohlen.
Die BEGIN
-Anweisung unterscheidet sich von
der Verwendung des Schlüsselworts BEGIN
,
welches eine mehrteilige BEGIN ...
END
-Anweisung einleitet. Mit Letzterem wird keine
Transaktion begonnen. Siehe auch Abschnitt 19.2.5, „BEGIN ... END
-Syntax für komplexe Anweisungen“.
Sie können eine Transaktion auch wie folgt einleiten:
START TRANSACTION WITH CONSISTENT SNAPSHOT;
Die Klausel WITH CONSISTENT SNAPSHOT
startet
eine konsistente Leseoperation für Speicher-Engines, die diese
unterstützen. Derzeit betrifft dies nur
InnoDB
. Der Effekt ist derselbe wie beim
Absetzen einer START TRANSACTION
-Anweisung
gefolgt von einer SELECT
-Anweisung für eine
beliebige InnoDB
-Tabelle. Siehe auch
Abschnitt 14.2.10.4, „Konsistentes Lesen“.
Die Klausel WITH CONSISTENT SNAPSHOT
ändert
die aktuelle Isolationsstufe der Transaktion nicht, d. h., eine
konsistente Momentaufnahme wird nur dann erstellt, wenn die
aktuelle Isolationsstufe konsistente Leseoperationen gestattet
(REPEATABLE READ
oder
SERIALIZABLE
).
Bei Beginn einer Transaktion wird implizit UNLOCK
TABLES
ausgeführt.
Beste Ergebnisse erhalten Sie, wenn Sie Transaktionen nur bei Tabellen durchführen, die mit einer einzelnen transaktionssicheren Speicher-Engine verwaltet werden. Andernfalls können die folgenden Probleme auftreten:
Wenn Ihre Tabellen mehrere transaktionssichere
Speicher-Engines verwenden (z. B. InnoDB
und BDB
) und die Isolationsstufe nicht
SERIALIZABLE
ist, besteht die
Möglichkeit, dass, wenn eine Transaktion übergeben wird,
eine andere laufende Transaktion, die dieselben Tabellen
benutzt, nur einen Teil der durch die erste Transaktion
vorgenommenen Änderungen erkennt. Die Atomizität der
Transaktionen ist mithin bei Verwendung mehrerer Engines
nicht gewährleistet, und es können Inkonsistenzen
auftreten. (Wenn Transaktionen mehrerer Engines nicht
häufig vorkommen, können Sie die Isolationsstufe mit
SET TRANSACTION ISOLATION LEVEL
für eine
Transaktion nach Bedarf auf SERIALIZABLE
setzen.)
Verwenden Sie in einer Transaktion nichttransaktionssichere Tabellen, dann werden alle Änderungen an diesen Tabellen unabhängig vom Status des Autocommit-Modus sofort gespeichert.
Wenn Sie nach Aktualisierung einer nichttransaktionssicheren
Tabelle in einer Transaktion eine
ROLLBACK
-Anweisung absetzen, erscheint
die Warnung
ER_WARNING_NOT_COMPLETE_ROLLBACK
.
Änderungen an transaktionssicheren Tabellen werden in
diesem Fall rückgängig gemacht, nicht jedoch Änderungen
an nichttransaktionssicheren Tabellen.
Jede Transaktion wird nach Absetzen von
COMMIT
am Stück in das Binärlog
geschrieben. Transaktionen, die per Rollback rückgängig
gemacht wurden, werden nicht geloggt.
(Ausnahme: Für Modifikationen
an nicht transaktionssicheren Tabellen kann kein Rollback
durchgeführt werden. Wenn eine Transaktion, für die ein
Rollback erfolgt, Änderungen an nicht transaktionssicheren
Tabellen enthält, dann wird die gesamte Transaktion am Ende mit
einer ROLLBACK
-Anweisung geloggt, um
sicherzustellen, dass die Modifikationen an diesen Tabellen
repliziert werden.) Siehe auch Abschnitt 5.12.3, „Die binäre Update-Logdatei“.
Sie können die Isolationsstufe für Transaktionen mit
SET TRANSACTION ISOLATION LEVEL
ändern.
Siehe auch Abschnitt 13.4.6, „SET TRANSACTION
“.
Ein Rollback kann ein relativ langsamer Vorgang sein, der zudem
stattfinden kann, ohne dass der Benutzer dies explizit
angefordert hat (z. B. wenn ein Fehler aufgetreten ist).
Aufgrund dieser Tatsache zeigt SHOW
PROCESSLIST
in der Spalte State
für die Verbindung Rolling back
an, solange
implizite oder (durch die SQL-Anweisung
ROLLBACK
) explizite Rollbacks durchgeführt
werden.
Es gibt Anweisungen, für die kein Rollback möglich ist. Hierzu gehören DDL-Anweisungen (Data Definition Language), z. B. solche, mit denen Datenbanken erstellt oder gelöscht oder Tabellen oder gespeicherte Routinen erstellt, gelöscht oder geändert werden.
Sie sollten Ihre Transaktionen so entwickeln, dass solche
Anweisungen nicht vorhanden sind. Wenn Sie eine Anweisung früh
in einer Transaktion absetzen, für die kein Rollback möglich
ist, und dann später eine andere Anweisung fehlschlägt, dann
können durch Absetzen der ROLLBACK
-Anweisung
nicht alle Auswirkungen der Transaktion rückgängig gemacht
werden.
Alle folgenden Anweisungen (und ggf. auch ihre Synonyme) beenden
eine Transaktion implizit – so als ob Sie vor Ausführung der
Anweisung eine COMMIT
-Anweisung abgesetzt
hätten:
ALTER FUNCTION
, ALTER
PROCEDURE
, ALTER TABLE
,
BEGIN
, CREATE
DATABASE
, CREATE FUNCTION
,
CREATE INDEX
, CREATE
PROCEDURE
, CREATE TABLE
,
DROP DATABASE
, DROP
FUNCTION
, DROP INDEX
,
DROP PROCEDURE
, DROP
TABLE
, LOAD MASTER DATA
,
LOCK TABLES
, RENAME
TABLE
, SET AUTOCOMMIT=1
,
START TRANSACTION
, TRUNCATE
TABLE
, UNLOCK TABLES
.
UNLOCK TABLES
übergibt eine Transaktion
nur dann, wenn zum betreffenden Zeitpunkt Tabellen gesperrt
sind.
Die Anweisung CREATE TABLE
in
InnoDB
wird als einzelne Transaktion
verarbeitet. Das bedeutet, dass eine
ROLLBACK
-Anweisung seitens des Benutzers
die CREATE TABLE
-Anweisungen, die der
Benutzer während der Transaktion abgesetzt hat, nicht
rückgängig machen kann.
Transaktionen können nicht verschachtelt werden. Dies ist eine
Folge des impliziten COMMIT
, das für jede
laufende Transaktion ausgeführt wird, wenn Sie eine
START TRANSACTION
-Anweisung (oder ein
entsprechendes Synonym) absetzen.
SAVEPOINTidentifier
ROLLBACK [WORK] TO SAVEPOINTidentifier
RELEASE SAVEPOINTidentifier
InnoDB
unterstützt die SQL-Anweisungen
SAVEPOINT
, ROLLBACK TO
SAVEPOINT
, RELEASE SAVEPOINT
und
das optionale Schlüsselwort WORK
für
ROLLBACK
.
Die SAVEPOINT
-Anweisung setzt einen benannten
Transaktionsspeicherpunkt mit dem Namen
identifier
. Hat die laufende
Transaktion einen Speicherpunkt gleichen Namens, dann wird der
alte Speicherpunkt gelöscht und ein neuer gesetzt.
Die Anweisung ROLLBACK TO SAVEPOINT
macht
eine Transaktion bis zum benannten Speicherpunkt rückgängig.
Änderungen, die die aktuelle Transaktion an Datensätzen nach
dem Speicherpunkt vorgenommen hat, werden im Rollback
rückgängig gemacht; allerdings hebt InnoDB
Datensatzsperren, die nach dem Speicherpunkt im Speicher
abgelegt wurden, nicht auf. (Beachten Sie,
dass bei einem neu eingefügten Datensatz die Sperrinformation
in dem im Datensatz gespeicherten Transaktionsbezeichner
enthalten ist, d. h., die Sperre wird nicht separat im Speicher
abgelegt. In diesem Fall wird die Datensatzsperre beim
Rückgängigmachen aufgehoben.) Speicherpunkte, die zeitlich
nach dem genannten Speicherpunkt liegen, werden gelöscht.
Wenn die ROLLBACK TO SAVEPOINT
-Anweisung den
folgenden Fehler zurückgibt, heißt das, dass es keinen
Speicherpunkt des angegebenen Namens gibt:
ERROR 1181: Got error 153 during ROLLBACK
Die Anweisung RELEASE SAVEPOINT
entfernt den
genannten Speicherpunkt aus der Menge der Speicherpunkte für
die laufende Transaktion. Es findet weder eine Übergabe noch
ein Rollback statt. Existiert der Speicherpunkt nicht, dann
tritt ein Fehler auf.
Alle Speicherpunkte der aktuellen Transaktion werden gelöscht,
wenn Sie eine COMMIT
- oder
ROLLBACK
-Anweisung absetzen, die keinen
Speicherpunkt benennt.
Seit MySQL 5.0.17 wird eine neue Speicherpunktstufe erstellt, wenn eine gespeicherte Funktion aufgerufen oder ein Trigger aktiviert wird. Die Speicherpunkte der vorherigen Stufen sind dann nicht mehr verfügbar, damit Konflikte mit Speicherpunkten der neuen Stufe vermieden werden. Wenn die Funktion oder der Trigger beendet wird, werden alle hierdurch erstellten Speicherpunkte gelöscht und die vorherige Speicherpunktstufe wird wiederhergestellt.
LOCK TABLEStbl_name
[ASalias
] {READ [LOCAL] | [LOW_PRIORITY] WRITE} [,tbl_name
[ASalias
] {READ [LOCAL] | [LOW_PRIORITY] WRITE}] ... UNLOCK TABLES
LOCK TABLES
sperrt Tabellen für den
aktuellen Thread. Wenn eine Tabelle von anderen Threads gesperrt
ist, wird der laufende Vorgang angehalten, bis alle Sperren
erwirkt werden können. UNLOCK TABLES
hebt
Sperren auf, die vom aktuellen Thread gehalten werden. Die
Sperren aller Tabellen, die vom aktuellen Thread gesperrt
werden, werden implizit aufgehoben, wenn der Thread eine andere
LOCK TABLES
-Anweisung absetzt oder die
Verbindung zum Server geschlossen wird.
Eine Tabellensperre schützt nur gegen unangemessene Lese- und
Schreiboperationen durch andere Clients. Der Client, der die
Sperre (auch eine Lesesperre) hält, kann Operationen auf
Tabellenebene – wie etwa DROP TABLE
–
durchführen.
Beachten Sie die folgenden Angaben zur Verwendung von
LOCK TABLES
bei transaktionssicheren
Tabellen:
LOCK TABLES
ist nicht transaktionssicher
und übergibt implizit alle aktiven Transaktionen, bevor
versucht wird, die Sperre für die Tabelle zu erwirken. Auch
das Starten einer Transaktion (z. B. bei START
TRANSACTION
) führt implizit eine UNLOCK
TABLES
-Anweisung aus. (Siehe auch
Abschnitt 13.4.3, „Anweisungen, die implizite Commits verursachen“.)
Die korrekte Vorgehensweise bei der Verwendung von
LOCK TABLES
in Verbindung mit
transaktionssicheren Tabellen wie InnoDB
besteht darin, AUTOCOMMIT = 0
zu setzen
und UNLOCK TABLES
erst dann aufzurufen,
wenn die Transaktion explizit übergeben werden soll. Wenn
Sie LOCK TABLES
aufrufen, setzt
InnoDB
intern eine eigene Tabellensperre.
Auch MySQL setzt eine eigene Tabellensperre.
InnoDB
hebt seine Sperre beim nächsten
Commit-Vorgang auf; damit MySQL seinerseits die Sperre
aufhebt, müssen Sie UNLOCK TABLES
aufrufen. Sie sollten AUTOCOMMIT = 1
nicht setzen, weil InnoDB
dann seine
Tabellensperre direkt nach dem Aufruf von LOCK
TABLES
aufhebt; auf diese Weise kann es zu einer
vollständigen Sperrung kommen. Beachten Sie, dass bei
AUTOCOMMIT = 1
die
InnoDB
-Tabellensperre überhaupt nicht
gesetzt wird, damit ältere Anwendungen sich nicht
versehentlich vollständig ausschließen.
ROLLBACK
hebt die Sperren bei den
nichttransaktionssicheren Tabellen von MySQL nicht auf.
Um LOCK TABLES
zu verwenden, benötigen Sie
die Berechtigungen LOCK TABLES
und
SELECT
für die betreffenden Tabellen.
Die wichtigsten Gründe zur Verwendung von LOCK
TABLES
sind die Emulation von Transaktionen oder die
Beschleunigung der Aktualisierung von Tabellen. Wir werden dies
weiter unten ausführlicher erläutern.
Wenn ein Thread eine Lesesperre für eine Tabelle erwirkt, kann dieser Thread (wie auch alle übrigen Threads) aus der Tabelle nur lesen. Wenn ein Thread eine Schreibsperre für eine Tabelle erwirkt, dann kann nur der Thread, der die Sperre hält, in die Tabelle schreiben. Anderen Threads wird dies untersagt, bis die Sperre aufgehoben ist.
Der Unterschied zwischen READ LOCAL
und
READ
besteht darin, dass READ
LOCAL
bei aktiver Sperre die Ausführung von
INSERT
-Anweisungen (also nebenläufigen
Einfügeoperationen) zulässt, sofern sie keine Konflikte
auslösen. Allerdings kann diese Funktion nicht verwendet
werden, um die Datenbankdateien bei aktiver Sperre außerhalb
von MySQL zu manipulieren. Bei
InnoDB
-Tabellen entspricht READ
LOCAL
READ
.
Wenn Sie LOCK TABLES
einsetzen, müssen Sie
alle Tabellen sperren, die Sie in Ihren Abfragen zu benutzen
beabsichtigen. Solange die mit einer LOCK
TABLES
-Anweisung erwirkten Sperren gültig sind,
können Sie nicht auf Tabellen zugreifen, die nicht durch die
Anweisung gesperrt wurden. Ferner können Sie eine gesperrte
Tabelle auch nicht mehrfach in derselben Abfrage verwenden.
Benutzen Sie stattdessen Aliase. In diesem Fall müssen Sie
allerdings für jeden Alias separat eine Sperre erwirken.
mysql>LOCK TABLE t WRITE, t AS t1 WRITE;
mysql>INSERT INTO t SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>INSERT INTO t SELECT * FROM t AS t1;
Wenn Ihre Abfragen eine Tabelle unter Verwendung eines Alias referenzieren, müssen Sie die Tabelle sperren, die denselben Alias benutzt. Die Tabelle zu sperren, ohne den Alias anzugeben, funktioniert nicht:
mysql>LOCK TABLE t READ;
mysql>SELECT * FROM t AS myalias;
ERROR 1100: Table 'myalias' was not locked with LOCK TABLES
Umgekehrt müssen Sie, wenn Sie eine Tabelle unter Verwendung eines Alias sperren, diese Tabelle unter Verwendung dieses Alias in Ihren Abfragen referenzieren:
mysql>LOCK TABLE t AS myalias READ;
mysql>SELECT * FROM t;
ERROR 1100: Table 't' was not locked with LOCK TABLES mysql>SELECT * FROM t AS myalias;
WRITE
-Sperren haben in der Regel Vorrang vor
READ
-Sperren. Hierdurch soll sichergestellt
werden, dass Aktualisierungen so schnell wie möglich
verarbeitet werden. Das bedeutet, dass, wenn ein Thread eine
READ
-Sperre erwirkt und dann ein anderer
Thread eine WRITE
-Sperre anfordert,
nachfolgende READ
-Sperranforderungen warten
müssen, bis der WRITE
-Thread die Sperre
wieder aufgehoben hat. Sie können mit LOW_PRIORITY
WRITE
-Sperren anderen Threads das Erwirken von
READ
-Sperren gestatten, während der Thread
auf die WRITE
-Sperre wartet.
LOW_PRIORITY WRITE
-Sperren sollten Sie nur
dann verwenden, wenn Sie sicher sind, dass zu einem
nachfolgenden Zeitpunkt keine Threads mehr eine
READ
-Sperre halten werden.
LOCK TABLES
funktioniert wie folgt:
Alle zu sperrenden Tabellen werden in einer intern definierten Reihenfolge sortiert. Aus Sicht des Benutzers ist diese Reihenfolge undefiniert.
Wenn eine Tabelle mit einer Lese- und einer Schreibsperre gesperrt ist, wird die Schreib- vor der Lesesperre gesetzt.
Es wird immer nur eine Tabelle gleichzeitig gesperrt, bis der Thread alle Sperren erhalten hat.
Diese Vorgehensweise gewährleistet, dass ein Aussperren ausgeschlossen ist. Es gibt jedoch ein paar andere Aspekte, die Sie bezüglich der Vorgehensweise beachten sollten:
Wenn Sie eine LOW_PRIORITY WRITE
-Sperre für
eine Tabelle verwenden, bedeutet dies lediglich, dass MySQL auf
diese bestimmte Sperre wartet, bis keine Threads mehr vorhanden
sind, die eine READ
-Sperre benötigen. Wenn
der Thread die WRITE
-Sperre erwirkt hat und
darauf wartet, die Sperre für die nächste Tabelle in der
Sperrliste zu erwirken, warten alle anderen Threads darauf, dass
die WRITE
-Sperre aufgehoben wird. Wenn dies
in Bezug auf Ihre Anwendung ein schwerwiegendes Problem
darstellen sollte, dann sollten Sie in Betracht ziehen, einige
Ihrer Tabellen in transaktionssichere Tabellen umzuwandeln.
Sie können einen Thread, der auf eine Tabellensperre wartet,
problemlos mit KILL
terminieren. Siehe auch
Abschnitt 13.5.5.3, „KILL
“.
Beachten Sie, dass Sie keine Tabellen
sperren sollen, die Sie mit INSERT DELAYED
verwenden, weil die Einfügeoperation in diesem Fall durch einen
separaten Thread durchgeführt wird.
Normalerweise müssen Sie Tabellen nicht sperren, weil alle
UPDATE
-Anweisungen für sich atomisch sind:
Kein anderer Thread kann eine andere derzeit ausgeführte
SQL-Anweisung unterbrechen. Allerdings gibt es einige wenige
Fälle, in denen das Sperren von Tabellen von Vorteil sein kann:
Wenn Sie viele Operationen für eine Anzahl von
MyISAM
-Tabellen ausführen wollen, geht
dies schneller, wenn Sie die zu verwendenden Tabellen
sperren. Das Sperren von MyISAM
-Tabellen
beschleunigt das Einfügen, Aktualisieren und Löschen in
diesen Tabellen. Der Nachteil besteht darin, dass kein
Thread eine READ
-gesperrte Tabelle
ändern kann (einschließlich derjenigen, die die Sperre
hält) und dass kein Thread auf eine
WRITE
-gesperrte Tabelle mit Ausnahme
derjenigen zugreifen kann, die die Sperre hält.
Der Grund dafür, dass MyISAM
-Operationen
unter LOCK TABLES
schneller ausgeführt
werden, besteht darin, dass MySQL den Schlüssel-Cache
gesperrter Tabellen erst beim Aufruf von UNLOCK
TABLES
synchronisiert. Normalerweise wird der
Schlüssel-Cache nach jeder SQL-Anweisung synchronisiert.
Wenn Sie eine Speicher-Engine in MySQL verwenden, die
Transaktionen nicht unterstützt, müssen Sie LOCK
TABLES
einsetzen, um sicherzustellen, dass kein
anderer Thread zwischen eine SELECT
- und
eine UPDATE
-Anweisung gelangt. Folgendes
Beispiel erfordert LOCK TABLES
, um sicher
ausgeführt werden zu können:
LOCK TABLES trans READ, customer WRITE; SELECT SUM(value) FROM trans WHERE customer_id=some_id
; UPDATE customer SET total_value=sum_from_previous_statement
WHERE customer_id=some_id
; UNLOCK TABLES;
Ohne LOCK TABLES
könnte ein anderer
Thread unter Umständen zwischen der Ausführung der
SELECT
- und der Ausführung der
UPDATE
-Anweisung einen neuen Datensatz in
die trans
-Tabelle einfügen.
Sie können die Verwendung von LOCK TABLES
in
vielen Fällen umgehen, indem Sie relative Updates
(UPDATE customer SET
)
oder die Funktion value
=value
+new_value
LAST_INSERT_ID()
verwenden.
Siehe auch Abschnitt 1.9.5.3, „Transaktionen“.
Sie können das Sperren von Tabellen in manchen Fällen auch
umgehen, indem Sie Funktionen für beratende Sperrungen auf
Benutzerebene (GET_LOCK()
und
RELEASE_LOCK()
) verwenden. Diese Sperren
werden in einer Hash-Tabelle auf dem Server gespeichert und mit
pthread_mutex_lock()
und
pthread_mutex_unlock()
mit dem Ziel einer
hohen Geschwindigkeit implementiert. Siehe auch
Abschnitt 12.10.4, „Verschiedene Funktionen“.
Weitere Informationen zu Methoden beim Sperren finden Sie in Abschnitt 7.3.1, „Wie MySQL Tabellen sperrt“.
Sie können mit der Anweisung FLUSH TABLES WITH READ
LOCK
Lesesperren für alle Tabellen in allen
Datenbanken setzen. Siehe auch Abschnitt 13.5.5.2, „FLUSH
“. Dies ist
eine recht praktische Möglichkeit der Datensicherung, wenn Sie
ein Dateisystem wie Veritas einsetzen, das rechtzeitig
Schnappschüsse erstellt.
Hinweis: Wenn Sie
ALTER TABLE
für eine gesperrte Tabelle
ausführen, kann die Sperre unter Umständen aufgehoben werden.
Siehe auch Abschnitt A.7.1, „Probleme mit ALTER TABLE
“.
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
Diese Anweisung bestimmt die Transaktionsisolationsstufe für die nächste Transaktion, global oder für die aktuelle Sitzung.
Das Standardverhalten von SET TRANSACTION
besteht darin, die Isolationsstufe für die nächste (d. h.
noch nicht gestartete) Transaktion einzustellen. Wenn Sie das
Schlüsselwort GLOBAL
verwenden, setzt die
Anweisung die Standardtransaktionsstufe global für alle neuen
Verbindungen, die nachfolgend hergestellt werden. Vorhandene
Verbindungen werden hiervon nicht berührt. Für diesen Zweck
benötigen Sie die Berechtigung SUPER
. Bei
Verwendung des Schlüsselworts SESSION
wird
die standardmäßige Transaktionsstufe für alle zukünftigen
Transaktionen gesetzt, die über die aktuelle Verbindung
durchgeführt werden.
Beschreibungen aller
InnoDB
-Transaktionsisolationsstufen finden
Sie in Abschnitt 14.2.10.3, „InnoDB
und TRANSACTION ISOLATION
LEVEL
“.
InnoDB
unterstützt in MySQL 5.1
alle Stufen. Die Standardstufe ist REPEATABLE
READ
.
Um die globale Standardisolationsstufe für
mysqld festzulegen, verwenden Sie die Option
--transaction-isolation
. Siehe auch
Abschnitt 5.2.1, „Befehlsoptionen für mysqld“.
Die Unterstützung von XA-Transaktionen ist für die
InnoDB
-Speicher-Engine verfügbar. Die
XA-Implementierung bei MySQL basiert auf dem X/Open CAE-Dokument
Distributed Transaction Processing: The XA
Specification („Verteilte
Transaktionsverarbeitung: Die XA-Spezifikation“). Dieses
Dokument wurde von The Open Group veröffentlicht und ist unter
http://www.opengroup.org/public/pubs/catalog/c193.htm
erhältlich. Die Grenzen der aktuellen XA-Implementierung sind
in Abschnitt I.5, „Beschränkungen bei XA-Transaktionen“ beschrieben.
Clientseitig gibt es keine besonderen Anforderungen. Die
XA-Schnittstelle zu einem MySQL Server besteht aus
SQL-Anweisungen, die mit dem Schlüsselwort
XA
beginnen. MySQL-Clientprogramme müssen
SQL-Anweisungen senden und die Semantik der
XA-Anweisungsschnittstelle verstehen können. Sie müssen nicht
mit einer aktuellen Clientbibliothek verknüpft sein: Es können
auch ältere Clientbibliotheken verwendet werden.
Derzeit unterstützt MySQL Connector/J 5.0.0 XA direkt (mithilfe einer Klassenschnittstelle, die die XA-SQL-Anweisungsschnittstelle für Sie verwaltet).
XA unterstützt verteilte Transaktionen, d. h., mehrere separate transaktionssichere Ressourcen können an einer globalen Transaktion teilnehmen. Transaktionssichere Ressourcen sind häufig relationale Datenbanksysteme, es gibt aber auch andere Ressourcentypen.
Eine globale Transaktion umfasst mehrere Aktionen, die für sich
transaktionssicher sind; sie alle aber müssen entweder als
Gruppe erfolgreich abgeschlossen werden, oder sie werden im
Rahmen eines Rollbacks gemeinsam rückgängig gemacht. Im
Endeffekt erweitert dies die ACID-Eigenschaften um eine
„Ebene nach oben“, sodass mehrere
ACID-Transaktionen konzertiert als Komponenten einer globalen
Operation ausgeführt werden, die ebenfalls ACID-Eigenschaften
hat. (Allerdings müssen Sie bei einer verteilten Transaktion
die Isolationsstufe SERIALIZABLE
benutzen, um
ACID-Eigenschaften zu erhalten. Bei nichtverteilten
Transaktionen ist REPEATABLE READ
ausreichend, nicht aber bei verteilten Transaktionen.)
Es folgen einige Beispiele für verteilte Transaktionen:
Eine Anwendung kann als Integrations-Tool agieren, welches einen Messaging-Dienst mit einem relationalen Datenbanksystem kombiniert. Die Anwendung stellt sicher, dass Transaktionen, die Versand, Abruf und Verarbeitung von Mitteilungen in Verbindung mit einer transaktionssicheren Datenbank regeln, auch alle in einer globalen Transaktion erfolgen. Man könnte sich dies als „transaktionssichere E-Mail“ vorstellen.
Eine Anwendung führt Aktionen durch, die verschiedene Datenbankserver betrifft, z. B. einen MySQL und einen Oracle-Server (oder auch mehrere MySQL Server). Hierbei müssen Aktionen, die mehrere Server betreffen, als Teil einer globalen Transaktion statt als separate Transaktionen stattfinden, die auf jedem Server getrennt ausgeführt werden.
Eine Bank speichert Kontendaten in einem relationalen Datenbanksystem. Empfang und Versand von Geld erfolgen über Bankautomaten. Es muss dabei gewährleistet sein, dass alle Vorgänge an den Automaten auf den Konten umgesetzt werden. Dies ist aber nicht allein mit dem Datenbanksystem möglich: Ein globaler Transaktionsmanager integriert Bankautomat- und Datenbankressourcen, um die Gesamtkonsistenz der Finanztransaktionen sicherzustellen.
Anwendungen, die globale Transaktionen verwenden, umfassen einen oder mehrere Ressourcenmanager und einen Transaktionsmanager:
Der Ressourcenmanager (RM) ermöglicht den Zugriff auf transaktionssichere Ressourcen. Ein Datenbankserver ist eine Art von Ressourcenmanager. Transaktionen, die vom RM verwaltet werden, müssen entweder im Rahmen eines Commits geschrieben oder im Zuge eines Rollbacks rückgängig gemacht werden können.
Ein Transaktionsmanager (TM) koordiniert die Transaktionen, die Teil einer globalen Transaktion sind. Er kommuniziert mit den RMs, die die einzelnen Transaktionen verwalten. Die einzelnen Transaktionen innerhalb einer globalen Transaktion sind die „Verzweigungen“ der globalen Transaktion. Globale Transaktionen und ihre Verzweigungen werden anhand eines Namensschemas unterschieden, welches weiter unten beschrieben werden wird.
Die MySQL-Implementierung von XA erlaubt es einem MySQL Server, als RM zu agieren, der XA-Transaktionen innerhalb einer globalen Transaktion verwaltet. Ein Clientprogramm, das eine Verbindung mit dem MySQL Server herstellt, agiert als TM.
Um eine globale Transaktion auszuführen, ist es erforderlich zu wissen, welche Komponenten betroffen sind, und jede dieser Komponenten an einen Punkt zu bringen, an dem sie übergeben oder rückgängig gemacht werden kann. Abhängig davon, was jede Komponente bezüglich ihres Erfolgs oder Fehlschlags meldet, müssen sie alle als atomische Gruppe übergeben oder rückgängig gemacht werden: Es müssen also entweder alle Komponenten geschrieben werden oder alle Komponenten werden im Zuge eines Rollbacks ungeschehen gemacht. Um eine globale Transaktion verwalten zu können, muss berücksichtigt werden, dass jede Komponente fehlschlagen oder auch das sie verbindende Netzwerk ausfallen kann.
Der Prozess zur Ausführung einer globalen Transaktion basiert auf 2PC (2-Phase Commit, Übergabe in zwei Phasen). Dies findet statt, nachdem die von den Verzweigungen der globalen Transaktion durchgeführten Vorgänge erledigt sind.
In der ersten Phase werden alle Verzweigungen vorbereitet: Sie werden vom TM angewiesen, sich für die Übergabe bereitzuhalten. Normalerweise bedeutet dies, dass jeder RM, der eine Verzweigung verwaltet, die Aktionen für diese Verzweigung in einem zuverlässigen Speicher ablegt. Die Verzweigungen geben an, ob dies jeweils für sie möglich ist. Die Ergebnisse werden in der zweiten Phase verwendet.
In der zweiten Phase weist der TM die RMs an, eine Übergabe oder einen Rollback durchzuführen. Wenn alle Verzweigungen bei der Vorbereitung angegeben haben, dass sie für eine Übergabe bereit sind, werden sie alle zur Übergabe angewiesen. Hat jedoch mindestens eine Verzweigung im Zuge der Vorbereitung gemeldet, dass bei ihr keine Übergabe möglich ist, dann werden alle Verzweigungen zu einem Rollback angewiesen.
In manchen Fällen verwendet eine globale Transaktion unter Umständen nur eine einphasige Übergabe (1PC). Stellt beispielsweise ein TM fest, dass eine globale Transaktion nur eine einzige transaktionssichere Ressource (also nur eine Verzweigung) umfasst, dann kann diese Ressource zur selben Zeit zur Vorbereitung und Übergabe angewiesen werden.
Um XA-Transaktionen in MySQL durchzuführen, verwenden Sie die folgenden Anweisungen:
XA {START|BEGIN}xid
[JOIN|RESUME] XA ENDxid
[SUSPEND [FOR MIGRATE]] XA PREPARExid
XA COMMITxid
[ONE PHASE] XA ROLLBACKxid
XA RECOVER
Bei XA START
werden die Klauseln
JOIN
und RESUME
nicht
unterstützt.
Bei XA END
wird die Klausel
SUSPEND [FOR MIGRATE]
nicht unterstützt.
Jede XA-Anweisung beginnt mit dem Schlüsselwort
XA
. Die meisten dieser Anweisungen
erfordern einen xid
-Wert.
xid
ist ein
XA-Transaktionsbezeichner. Er gibt an, für welche Transaktion
die Anweisung gilt. xid
-Werte
werden vom Client übergeben oder auf dem MySQL Server
erzeugt. Ein xid
-Wert besteht aus
einem bis drei Teilen:
xid
:gtrid
[,bqual
[,formatID
]]
gtrid
ist ein globaler
Transaktionsbezeichner, bqual
ein
Verzweigungsbezeichner und formatID
eine Zahl, die das Format angibt, welches von den
gtrid
- und
bqual
-Werten verwendet wird. Wie
aus der Syntax hervorgeht, sind
bqual
und
formatID
optional. Der Standardwert
von bqual
ist
''
, sofern nichts anderes angegeben ist.
Der Standardwert von formatID
ist
1, sofern nichts anderes angegeben ist.
gtrid
und
bqual
müssen String-Literale sein,
die jeweils bis zu 64 Byte (nicht Zeichen) lang sein dürfen.
gtrid
und
bqual
können auf unterschiedliche
Art und Weise angegeben werden. Sie können einen String in
Anführungszeichen ('ab'
), einen
Hexadezimal-String (0x6162
,
X'ab'
) oder einen Bitwert
(b'
)
angeben.
nnnn
'
formatID
ist ein vorzeichenloser
Integer.
Die gtrid
- und
bqual
-Werte werden von den
XA-Supportroutinen auf dem MySQL Server als Bytewerte
interpretiert. Allerdings benutzt der Server bei der Analyse
einer SQL-Anweisung, die eine XA-Anweisung enthält, einen
speziellen Zeichensatz. Wenn Sie sichergehen wollen, notieren
Sie gtrid
und
bqual
als Hexadezimal-String.
xid
-Werte werden normalerweise vom
TM erzeugt. Die Werte, die von einem TM erzeugt werden,
müssen sich von denen unterscheiden, die von anderen TMs
gebildet werden. Ein gegebener TM muss seine eigenen
xid
-Werte in einer Werteliste, die
von der Anweisung XA RECOVER
zurückgegeben
wird, erkennen können.
XA START
startet eine XA-Transaktion mit dem gegebenen
xid
xid
-Wert. Jede XA-Transaktion
benötigt einen eindeutigen
xid
-Wert, d. h., der Wert darf
nicht gleichzeitig von einer anderen XA-Transaktion verwendet
werden. Diese Eindeutigkeit wird mithilfe der Werte
gtrid
und
bqual
erzielt. Alle nachfolgenden
XA-Anweisungen für die XA-Transaktion müssen unter
Verwendung desselben xid
-Werts
angegeben werden, der in der XA
START
-Anweisung übergeben wurde. Verwenden Sie eine
dieser Anweisungen und geben dabei keinen
xid
-Wert an, der einer laufenden
XA-Transaktion entspricht, dann tritt ein Fehler auf.
Eine oder mehrere XA-Transaktionen können Teil derselben
globalen Transaktion sein. Alle XA-Transaktionen in einer
gegebenen globalen Transaktion müssen denselben
gtrid
-Wert im
xid
-Wert benutzen. Aus diesem Grund
müssen gtrid
-Werte global
eindeutig sein, damit keine Mehrdeutigkeiten darüber
aufkommen können, zu welcher globalen Transaktion eine
gegebene XA-Transaktion gehört. Der Teil
bqual
des
xid
-Werts muss sich für jede
XA-Transaktion innerhalb einer globalen Transaktion
unterscheiden. (Die Anforderung, dass
bqual
-Werte unterschiedlich sein
müssen, stellt eine Einschränkung der aktuellen
XA-Implementierung in MySQL dar. Sie ist nicht Teil der
XA-Spezifikation.)
Die Anweisung XA RECOVER
gibt Informationen
zu denjenigen XA-Transaktionen auf dem MySQL Server zurück,
die den Status PREPARED
haben. (Siehe auch
Abschnitt 13.4.7.2, „XA-Transaktionszustände“.) Die Ausgabe enthält einen
Datensatz für jede derartige XA-Transaktion auf dem Server
– unabhängig davon, welcher Client sie gestartet hat.
Die Ausgabedatensätze von XA RECOVER
sehen
wie folgt aus (für einen
xid
-Beispielwert, der aus den
Teilen 'abc'
, 'def'
und
7
besteht):
mysql> XA RECOVER;
+----------+--------------+--------------+--------+
| formatID | gtrid_length | bqual_length | data |
+----------+--------------+--------------+--------+
| 7 | 3 | 3 | abcdef |
+----------+--------------+--------------+--------+
Die Ausgabespalten haben die nachfolgend beschriebenen Bedeutungen:
formatID
ist der
formatID
-Teil der Transaktion
xid
.
gtrid_length
ist die Länge des
gtrid
-Teils der Transaktion
xid
in Byte.
bqual_length
ist die Länge des
bqual
-Teils der Transaktion
xid
in Byte.
data
ist die Verkettung der Teile
gtrid
und
bqual
der Transaktion
xid
.
Eine XA-Transaktion umfasst die folgenden Phasen:
Starten Sie mit XA START
eine
XA-Transaktion und versetzen Sie sie in den Status
ACTIVE
.
Sobald die XA-Transaktion aktiv ist, setzen Sie die
SQL-Anweisungen für die Transaktion ab. Zuletzt setzen
Sie eine XA END
-Anweisung ab, mit der
Sie die Transaktion in den Zustand IDLE
versetzen.
Bei einer XA-Transaktion in diesem Zustand können Sie
entweder eine XA PREPARE
-Anweisung oder
eine XA COMMIT ... ONE PHASE
-Anweisung
absetzen:
XA PREPARE
versetzt die Transaktion
in den Zustand PREPARED
. Bei
Eingabe einer XA RECOVER
-Anweisung
an dieser Stelle wird der
xid
-Wert der Transaktion in
die Ausgabe integriert, weil XA
RECOVER
alle XA-Transaktionen auflistet,
deren Zustand PREPARED
ist.
XA COMMIT ... ONE PHASE
bereit die
Transaktion vor und übergibt sie dann direkt. Der
xid
-Wert wird von
XA RECOVER
nicht aufgelistet, weil
die Transaktion endet.
Bei einer XA-Transaktion im Zustand
PREPARED
können Sie eine XA
COMMIT
-Anweisung absetzen, um sie zu übergeben
und zu beenden, oder Sie machen sie mit einer XA
ROLLBACK
-Anweisung rückgängig (sie wird dann
ebenfalls beendet).
Es folgt eine einfache XA-Transaktion, die im Rahmen einer globalen Transaktion einen Datensatz in eine Tabelle einfügt:
mysql>XA START 'xatest';
Query OK, 0 rows affected (0.00 sec) mysql>INSERT INTO mytable (i) VALUES(10);
Query OK, 1 row affected (0.04 sec) mysql>XA END 'xatest';
Query OK, 0 rows affected (0.00 sec) mysql>XA PREPARE 'xatest';
Query OK, 0 rows affected (0.00 sec) mysql>XA COMMIT 'xatest';
Query OK, 0 rows affected (0.00 sec)
Im Kontext einer gegebenen Clientverbindung schließen sich
XA-Transaktionen und lokale Transaktionen (also
Nicht-XA-Transaktionen) gegenseitig aus. Wenn beispielsweise
mit XA START
eine XA-Transaktion gestartet
wurde, dann kann eine lokale Transaktion erst begonnen werden,
wenn die XA-Transaktion übergeben oder rückgängig gemacht
wurde. Umgekehrt können, wenn eine lokale Transaktion mit
START TRANSACTION
begonnen wurde,
XA-Anweisungen erst dann verwendet werden, wenn die
Transaktion übergeben oder rückgängig gemacht wurde.
MySQL-Kontendaten sind in Tabellen der Datenbank
mysql
gespeichert. Diese Datenbank und das
Zugriffssteuerungssystem sind in
Kapitel 5, Datenbankverwaltung, ausführlich
beschrieben. Sie finden dort weitere Informationen.
Wichtig: Einige Releases von MySQL enthalten Änderungen an der Struktur der Grant-Tabellen, damit neue Berechtigungen oder Funktionen hinzugefügt werden können. Wenn Sie ein Upgrade auf eine neue MySQL-Version durchführen, sollten Sie Ihre Grant-Tabellen aktualisieren, damit sichergestellt ist, dass diese auf der aktuellen Struktur basieren und auf diese Weise neue Funktionalitäten nutzen können. Siehe auch Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.
CREATE USERuser
[IDENTIFIED BY [PASSWORD] 'password
'] [,user
[IDENTIFIED BY [PASSWORD] 'password
']] ...
Die CREATE USER
-Anweisung erstellt neue
MySQL-Konten. Um sie zu verwenden, benötigen Sie die globale
Berechtigung CREATE USER
oder die
Berechtigung INSERT
für die Datenbank
mysql
. Für jedes Konto richtet
CREATE USER
einen neuen Datensatz in der
Tabelle mysql.user
ein, der keine
Berechtigungen hat. Ist das Konto bereits vorhanden, dann
tritt ein Fehler auf. Jedes Konto wird im selben Format wie
bei der GRANT
-Anweisung benannt (z. B.
'jeffrey'@'localhost'
). Die Benutzer- und
Hostbestandteile des Kontonamens entsprechen den Werten der
Spalten User
und Host
des kontenspezifischen Datensatzes in der Tabelle
user
.
Das Konto erhält ein Passwort mit der optionalen
IDENTIFIED BY
-Klausel. Der Wert
user
und das Passwort werden auf
gleiche Weise übergeben wie bei der
GRANT
-Anweisung. Insbesondere müssen Sie
das Schlüsselwort PASSWORD
weglassen, um
das Passwort im Klartext angeben zu können. Wenn Sie das
Passwort hingegen als von der Funktion
PASSWORD()
zurückgegebenen Hash-Wert
angeben wollen, schließen Sie das Schlüsselwort
PASSWORD
mit ein. Siehe auch
Abschnitt 13.5.1.3, „GRANT
und REVOKE
“.
DROP USERuser
[,user
] ...
Die Anweisung DROP USER
entfernt ein oder
mehrere MySQL-Konten. Sie löscht die Berechtigungsdatensätze
des Kontos aus allen Grant-Tabellen. Um diese Anweisung zu
verwenden, benötigen Sie die globale Berechtigung
CREATE USER
oder die Berechtigung
DELETE
für die Datenbank
mysql
. Jedes Konto wird im selben Format
wie bei der GRANT
-Anweisung benannt (z. B.
'jeffrey'@'localhost'
). Die Benutzer- und
Hostbestandteile des Kontonamens entsprechen den Werten der
Spalten User
und Host
des kontenspezifischen Datensatzes in der Tabelle
user
.
Mit DROP USER
können Sie ein Konto und
seine Berechtigungen wie folgt entfernen:
DROP USER user
;
Wichtig
: DROP USER
schließt offene
Benutzersitzungen nicht automatisch. Stattdessen wird, wenn
ein zu löschender Benutzer gerade eine offene Sitzung hat,
die Anweisung erst umgesetzt, wenn die Sitzung dieses
Benutzers beendet wurde. Sobald die Sitzung beendet ist, wird
der Benutzer gelöscht: Nachfolgende Versuche des Benutzers,
sich anzumelden, schlagen dann fehl. Dies ist
bewusst so implementiert.
GRANTpriv_type
[(column_list
)] [,priv_type
[(column_list
)]] ... ON [object_type
] {tbl_name
| * | *.* |db_name
.*} TOuser
[IDENTIFIED BY [PASSWORD] 'password
'] [,user
[IDENTIFIED BY [PASSWORD] 'password
']] ... [REQUIRE NONE | [{SSL| X509}] [CIPHER 'cipher
' [AND]] [ISSUER 'issuer
' [AND]] [SUBJECT 'subject
']] [WITHwith_option
[with_option
] ...]object_type
= TABLE | FUNCTION | PROCEDUREwith_option
= GRANT OPTION | MAX_QUERIES_PER_HOURcount
| MAX_UPDATES_PER_HOURcount
| MAX_CONNECTIONS_PER_HOURcount
| MAX_USER_CONNECTIONScount
Die GRANT
-Anweisung erlaubt
Systemadministratoren die Erstellung von MySQL-Benutzerkonten
und die Vergabe von Rechten an diese Konten. Um
GRANT
verwenden zu können, benötigen Sie
die Berechtigung GRANT OPTION
sowie alle
Berechtigungen, die Sie selbst gewähren. Die
REVOKE
-Anweisung ist in diesem Zusammenhang
ebenfalls zu nennen: Sie gestattet Administratoren das
Entfernen von Kontenberechtigungen. Siehe auch
Abschnitt 13.5.1.5, „REVOKE
“.
MySQL-Kontendaten sind in Tabellen der Datenbank
mysql
gespeichert. Diese Datenbank und das
Zugriffssteuerungssystem sind in
Kapitel 5, Datenbankverwaltung, ausführlich
beschrieben. Sie finden dort weitere Informationen.
Wichtig: Einige Releases von MySQL enthalten Änderungen an der Struktur der Grant-Tabellen, damit neue Berechtigungen oder Funktionen hinzugefügt werden können. Wenn Sie ein Upgrade auf eine neue MySQL-Version durchführen, sollten Sie Ihre Grant-Tabellen aktualisieren, damit sichergestellt ist, dass diese auf der aktuellen Struktur basieren und auf diese Weise neue Funktionalitäten nutzen können. Siehe auch Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“.
Wenn in den Grant-Tabellen Berechtigungsdatensätze vorhanden
sind, die Datenbank- oder Tabellennamen mit gemischter
Groß-/Kleinschreibung enthalten, und die Systemvariable
lower_case_table_names
auf einen
Nicht-Null-Wert gesetzt ist, dann können diese Berechtigungen
nicht mit REVOKE
widerrufen werden. Es ist
dann erforderlich, die Grant-Tabellen direkt zu manipulieren.
(GRANT
erstellt solche Datensätze zwar
nicht, wenn lower_case_table_names
eingestellt ist, aber unter Umständen wurden derartige
Datensätze bereits vor Einstellen der Variablen erstellt.)
Berechtigungen können auf unterschiedlichen Ebenen gewährt werden:
Globale Ebene
Globale Berechtigungen gelten für alle Datenbanken auf
einem gegebenen Server. Sie werden in der Tabelle
mysql.user
gespeichert. GRANT
ALL ON *.*
und REVOKE ALL ON
*.*
gewähren bzw. widerrufen nur globale
Berechtigungen.
Datenbankebene
Datenbankberechtigungen gelten für alle Objekte in einer
gegebenen Datenbank. Sie werden in den Tabellen
mysql.db
und
mysql.host
gespeichert. GRANT
ALL ON
und
db_name
.*REVOKE ALL ON
gewähren
bzw. widerrufen nur Datenbankberechtigungen.
db_name
.*
Tabellenebene
Tabellenberechtigungen gelten für alle Spalten in einer
gegebenen Tabelle. Sie werden in der Tabelle
mysql.tables_priv
gespeichert.
GRANT ALL ON
und
db_name.tbl_name
REVOKE ALL ON
gewähren bzw. widerrufen nur Tabellenberechtigungen.
db_name.tbl_name
Spaltenebene
Spaltenberechtigungen gelten für einzelne Spalten in
einer gegebenen Tabelle. Sie werden in der Tabelle
mysql.columns_priv
gespeichert. Wenn
Sie REVOKE
verwenden, müssen Sie
dieselben Spalten angeben, denen die Berechtigungen zuvor
gewährt wurden.
Routinenebene
Die Berechtigungen CREATE ROUTINE
,
ALTER ROUTINE
,
EXECUTE
und GRANT
gelten für gespeicherte Routinen (Funktionen und
Prozeduren). Sie können auf der globalen und der
Datenbankebene gewährt werden. Ferner lassen sich diese
Berechtigungen mit Ausnahme von CREATE
ROUTINE
auf Routinenebene für einzelne Routinen
gewähren und werden in der Tabelle
mysql.procs_priv
gespeichert.
Die Klausel object_type
sollte als
TABLE
, FUNCTION
bzw. als
PROCEDURE
angegeben werden, wenn das
nachfolgende Objekt eine Tabelle, eine gespeicherte Funktion
oder eine gespeicherte Prozedur ist.
Für die Anweisungen GRANT
und
REVOKE
kann
priv_type
wie folgt angegeben
werden:
Berechtigung | Bedeutung |
ALL [PRIVILEGES] | Setzt alle einfachen Berechtigungen außer GRANT
OPTION . |
ALTER | Erlaubt die Verwendung von ALTER TABLE . |
ALTER ROUTINE | Erlaubt die Änderung oder Löschung gespeicherter Routinen. |
CREATE | Erlaubt die Verwendung von CREATE TABLE . |
CREATE ROUTINE | Erlaubt die Erstellung gespeicherter Routinen. |
CREATE TEMPORARY TABLES | Erlaubt die Verwendung von CREATE TEMPORARY TABLE . |
CREATE USER | Erlaubt die Verwendung von CREATE USER , DROP
USER , RENAME USER und
REVOKE ALL PRIVILEGES . |
CREATE VIEW | Erlaubt die Verwendung von CREATE VIEW . |
DELETE | Erlaubt die Verwendung von DELETE . |
DROP | Erlaubt die Verwendung von DROP TABLE . |
EVENT | Erlaubt die Erstellung von Ereignissen für den Ereignisplaner. |
EXECUTE | Erlaubt dem Benutzer die Ausführung gespeicherter Routinen. |
FILE | Erlaubt die Verwendung von SELECT ... INTO OUTFILE
und LOAD DATA INFILE . |
INDEX | Erlaubt die Verwendung von CREATE INDEX und
DROP INDEX . |
INSERT | Erlaubt die Verwendung von INSERT . |
LOCK TABLES | Erlaubt die Verwendung von LOCK TABLES für Tabellen,
für die Sie die Berechtigung
SELECT haben. |
PROCESS | Erlaubt die Verwendung von SHOW FULL PROCESSLIST . |
REFERENCES | Nicht implementiert. |
RELOAD | Erlaubt die Verwendung von FLUSH . |
REPLICATION CLIENT | Erlaubt dem Benutzer, die Positionen von Slave- oder Master-Servern zu erfragen. |
REPLICATION SLAVE | Für Replikationsslaves erforderlich (zum Lesen von Binärlogeinträgen auf dem Master). |
SELECT | Erlaubt die Verwendung von SELECT . |
SHOW DATABASES | SHOW DATABASES zeigt alle Datenbanken. |
SHOW VIEW | Erlaubt die Verwendung von SHOW CREATE VIEW . |
SHUTDOWN | Erlaubt die Verwendung von mysqladmin shutdown. |
SUPER | Erlaubt die Verwendung der Anweisungen CHANGE MASTER ,
KILL , PURGE MASTER
LOGS und SET GLOBAL und
des Befehls mysqladmin debug.
Erlaubt ferner die (einmalige) Verbindungsherstellung
auch in dem Fall, dass der Wert für
max_connections erreicht wurde. |
TRIGGER | Erlaubt dem Benutzer das Erstellen und Löschen von Triggern. |
UPDATE | Erlaubt die Verwendung von UPDATE . |
USAGE | Synonym für „keine Berechtigungen“ |
GRANT OPTION | Erlaubt die Gewährung von Berechtigungen. |
Die Berechtigungen EVENT
und
TRIGGER
wurden in MySQL 5.1.6 hinzugefügt.
Ein Trigger ist mit einer Tabelle verknüpft, d. h., um einen
Trigger zu erstellen oder zu löschen, benötigen Sie die
Berechtigung TRIGGER
für die Tabelle,
nicht für den Trigger. (Vor MySQL 5.1.6 war für das
Erstellen und Löschen von Triggern die Berechtigung
SUPER
erforderlich.)
Die Berechtigung REFERENCES
wird derzeit
nicht benutzt.
USAGE
kann angegeben werden, wenn Sie einen
Benutzer ohne Berechtigungen erstellen wollen.
Verwenden Sie SHOW GRANTS
, um zu bestimmen,
welche Berechtigungen ein Konto hat. Siehe auch
Abschnitt 13.5.4.11, „SHOW GRANTS
“.
Sie können globale Berechtigungen mit der Syntax ON
*.*
oder Berechtigungen auf Datenbankebene mit der
Syntax ON
konfigurieren.
Wenn Sie db_name
.*ON *
angeben und eine
Standarddatenbank festgelegt haben, werden die Berechtigungen
in dieser Datenbank gewährt.
(Warnung: Wenn Sie
ON *
angeben und keine
Standarddatenbank ausgewählt haben, werden die Berechtigungen
global gewährt.)
Die Berechtigungen FILE
,
PROCESS
, RELOAD
,
REPLICATION CLIENT
, REPLICATION
SLAVE
, SHOW DATABASES
,
SHUTDOWN
und SUPER
sind
administrative Berechtigungen, die nur global gewährt werden
können (hierzu wird die Syntax ON *.*
verwendet).
Andere Berechtigungen können wahlweise global oder auf individuellen Ebenen festgelegt werden.
Die priv_type
-Werte, die Sie für
eine Tabelle angeben können, sind SELECT
,
INSERT
, UPDATE
,
DELETE
, CREATE
,
DROP
, GRANT OPTION
,
INDEX
, ALTER
,
CREATE VIEW
, SHOW VIEW
und TRIGGER
.
Die priv_type
-Werte, die Sie (bei
Verwendung einer
column_list
-Klausel) für eine
Spalte angeben können, sind SELECT
,
INSERT
und UPDATE
.
Die priv_type
-Werte, die Sie auf
der Routinenebene angeben können, sind ALTER
ROUTINE
, EXECUTE
und
GRANT OPTION
. CREATE
ROUTINE
ist keine Berechtigung auf Routinenebene,
weil Sie diese Berechtigung bereits zur Erstellung einer
Routine benötigen.
Auf der globalen, der Datenbank-, der Tabellen- und der
Routinenebene weist GRANT ALL
nur
diejenigen Berechtigungen zu, die auf der gewährten Ebene
vorhanden sind. So ist beispielsweise GRANT ALL ON
eine Anweisung
auf Datenbankebene, d. h., es lassen sich hiermit keine nur
auf globaler Ebene vorhandenen Berechtigungen (wie z. B.
db_name
.*FILE
) gewähren.
MySQL gestattet die Konfiguration von Berechtigungen auch für
Datenbankobjekte, die nicht existieren. In diesen Fällen muss
zu den zu gewährenden Berechtigungen auch die Berechtigung
CREATE
gehören. Dies ist bewusst
so implementiert und soll es dem
Datenbankadministrator gestatten, Benutzerkonten und
Berechtigungen für Datenbankobjekte vorzubereiten, die erst
später erstellt werden.
Wichtig: Wenn Sie eine Tabelle oder Datenbank löschen, widerruft MySQL Berechtigungen nicht automatisch. Wenn Sie allerdings eine Routine löschen, werden alle Berechtigungen auf Routinenebene widerrufen, die für diese Routine gewährt wurden.
Hinweis: Die Jokerzeichen
‘_
’ und
‘%
’ sind bei der Angabe von
Datenbanknamen in GRANT
-Anweisungen, die
Berechtigungen auf der globalen und der Datenbankebene
gewähren, zulässig. Das bedeutet beispielsweise, dass Sie,
wenn Sie das Zeichen ‘_
’ als
Bestandteil eines Datenbanknamens verwenden wollen, dieses
Zeichen als ‘\_
’ in der
GRANT
-Anweisung angeben müssen, damit der
Benutzer nicht auf weitere Datenbanken zugreifen kann, die dem
entstandenen Muster entsprechen (z. B. GRANT ... ON
`foo\_bar`.* TO ...
).
Um das Gewähren von Rechten an Benutzer über beliebige Hosts
zu gestatten, unterstützt MySQL die Angabe des
user
-Werts in der Form
.
Wenn ein user_name
@host_name
user_name
- oder
host_name
-Wert als vorzeichenloser
Bezeichner zulässig ist, müssen Sie ihn nicht in
Anführungszeichen setzen. Allerdings sind Anführungszeichen
erforderlich, um einen
user_name
-String mit Sonderzeichen
(z. B. ‘-
’) oder einen
host_name
-String mit Sonder- oder
Jokerzeichen (wie ‘%
’)
anzugeben. Ein Beispiel hierfür wäre
'test-user'@'test-hostname'
. Setzen Sie
Benutzer- und Hostnamen separat in Anführungszeichen.
Sie können Jokerzeichen im Hostnamen verwenden. So bezeichnet
etwa
jeden user_name
@'%.loc.gov'user_name
auf einem
beliebigen Host in der Domäne loc.gov
, und
bezeichnet user_name
@'144.155.166.%'user_name
auf einem
beliebigen Host im Klasse-C-Subnetz
144.155.166
.
Die einfache Form user_name
ist ein
Synonym für
.
user_name
@'%'
MySQL unterstützt keine Jokerzeichen in
Benutzernamen. Anonyme Benutzer werden durch
Einfügen von Einträgen mit User=''
in die
Tabelle mysql.user
oder durch Erstellen
eines Benutzers mit einem leeren Namen mit der
GRANT
-Anweisung definiert:
GRANT ALL ON test.* TO ''@'localhost' ...
Wenn Sie Werte in Anführungszeichen angeben, setzen Sie
Datenbank-, Tabellen-, Spalten- und Routinenamen als
Bezeichner in Backticks (‘`
’).
Host- und Benutzernamen sowie Passwörter werden als Strings
in einfache Anführungszeichen
(‘'
’) gesetzt.
Warnung: Wenn Sie anonymen
Benutzern eine Verbindung zum MySQL Server gestatten wollen,
sollten Sie auch allen lokalen Benutzern als
Berechtigungen gewähren. Andernfalls wird das anonyme
Benutzerkonto für user_name
@localhostlocalhost
in der Tabelle
mysql.user
verwendet, wenn benannte
Benutzer versuchen, sich über das lokale System am MySQL
Server anzumelden (die Tabelle wird bei der Installation von
MySQL erstellt). Detaillierte Informationen finden Sie in
Abschnitt 5.8.5, „Zugriffskontrolle, Phase 1: Verbindungsüberprüfung“.
Sie können feststellen, ob dies für Sie zutrifft, indem Sie die folgende Abfrage ausführen, die alle ggf. vorhandenen anonymen Benutzer auflistet:
SELECT Host, User FROM mysql.user WHERE User='';
Wenn Sie das lokale anonyme Benutzerkonto löschen wollen, um das beschriebene Problem zu umgehen, dann verwenden Sie folgende Anweisungen:
DELETE FROM mysql.user WHERE Host='localhost' AND User=''; FLUSH PRIVILEGES;
GRANT
unterstützt Hostnamen mit einer
Länge von bis zu 60 Zeichen. Die Namen von Datenbanken,
Tabellen, Spalten und Routinen dürfen bis zu 64 Zeichen lang
sein. Benutzernamen können bis zu 16 Zeichen umfassen.
Hinweis: Die
zulässige Länge für Benutzernamen kann nicht durch
Änderungen an der Tabelle mysql.user
modifiziert werden. Wenn Sie dies dennoch versuchen, kann dies
zu unvorhersehbaren Folgen führen, die schlimmstenfalls sogar
ein Anmelden von Benutzern am MySQL Server verhindern
können. Sie sollten die Tabellen in der
mysql
-Datenbank grundsätzlich nicht auf
eine andere als die von MySQL AB vorgeschriebene, in
Abschnitt 5.6, „mysql_fix_privilege_tables — Upgrade von MySQL-Systemtabellen“, geschilderte
Weise ändern.
Die Berechtigungen für eine Tabelle, eine Spalte oder eine
Routine werden kumulativ über ein logisches
OR
der Berechtigungen auf jeder der
einzelnen Ebenen gebildet. Wenn die Tabelle
mysql.user
beispielsweise angibt, dass ein
Benutzer die globale Berechtigung SELECT
hat, kann ihm diese Berechtigung nicht auf der Datenbank-, der
Tabellen- oder der Spaltenebene verweigert werden.
Die Berechtigungen für eine Spalte lassen sich wie folgt berechnen:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges OR routine privileges
In den meisten Fällen gewähren Sie einem Benutzer nur auf einer dieser Berechtigungsebenen Rechte – das Leben ist also normalerweise nicht so kompliziert. Ausführlich beschrieben wird die Überprüfung von Berechtigungen in Abschnitt 5.8, „Allgemeine Sicherheitsaspekte und das MySQL-Zugriffsberechtigungssystem“.
Wenn Sie Berechtigungen für eine Kombination aus Benutzer-
und Hostnamen gewähren, die nicht in der Tabelle
mysql.user
vorhanden ist, wird ein Eintrag
hinzugefügt und verbleibt dort, bis er mit einer
DELETE
-Anweisung gelöscht wird. Anders
gesagt, GRANT
kann Einträge in der Tabelle
user
erstellen; diese lassen sich aber
nicht mit REVOKE
entfernen, sondern müssen
explizit mit DROP USER
oder
DELETE
gelöscht werden.
Warnung: Wenn Sie einen neuen
Benutzer ohne IDENTIFIED BY
-Klausel
erstellen, hat der Benutzer kein Passwort. Dies ist sehr
unsicher. Sie können jedoch den SQL-Modus
NO_AUTO_CREATE_USER
aktivieren: Hierbei
wird verhindert, dass GRANT
Benutzer
automatisch erstellt, wenn diesem nicht mit der
IDENTIFIED BY
-Klausel ein nichtleeres
Passwort zugewiesen wird.
Wenn ein neuer Benutzer erstellt wird oder Sie globale
Gewährungsberechtigungen haben, dann wird das Passwort des
Benutzers auf das in der IDENTIFIED
BY
-Klausel gewählte Passwort gesetzt (sofern
vorhanden). Hat der Benutzer bereits ein Passwort, so wird
dieses durch das neue Passwort ersetzt.
Passwörter können auch mit der Anweisung SET
PASSWORD
eingestellt werden. Siehe auch
Abschnitt 13.5.1.6, „SET PASSWORD
“.
In der IDENTIFIED BY
-Klausel sollte das
Passwort als literaler Passwortwert übergeben werden. Es ist
– anders als bei der SET
PASSWORD
-Anweisung – nicht erforderlich, die
Funktion PASSWORD()
zu verwenden. Zum
Beispiel:
GRANT ... IDENTIFIED BY 'mypass';
Wenn Sie das Passwort nicht unverschlüsselt senden wollen und
den Hash-Wert kennen, den PASSWORD()
für
das Passwort zurückgeben würde, dann können Sie diesen
Hash-Wert nach dem Schlüsselwort PASSWORD
angeben:
GRANT ... IDENTIFIED BY PASSWORD '*6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4';
In einem C-Programm können Sie den Hash-Wert mit der
C-API-Funktion make_scrambled_password()
ermitteln.
Wenn Sie Berechtigungen für eine Datenbank gewähren, wird
bei Bedarf ein Eintrag in der Tabelle
mysql.db
erstellt. Wenn alle Berechtigungen
für die Datenbank mit REVOKE
entfernt
werden, wird dieser Eintrag gelöscht.
Die Berechtigung SHOW DATABASES
ermöglicht
dem Konto die Anzeige von Datenbanknamen durch Absetzen einer
SHOW DATABASE
-Anweisung. Konten, die diese
Berechtigung nicht haben, sehen nur solche Datenbanken, für
die sie Berechtigungen haben; wurde der Server mit der Option
--skip-show-database
gestartet, dann kann die
Anweisung überhaupt nicht verwendet werden.
Wenn ein Benutzer keine Berechtigungen für eine Tabelle hat,
wird, wenn er (z. B. mit SHOW TABLES
) eine
Liste der Tabellen anfordert, der Name der betreffenden
Tabelle nicht angezeigt.
Die WITH GRANT OPTION
-Klausel gibt dem
Benutzer die Möglichkeit, anderen Benutzern beliebige
Berechtigungen zu gewähren, die der Benutzer selbst auf einer
bestimmten Berechtigungsebene hat. Sie sollten bei der Vergabe
der Berechtigung GRANT OPTION
mit Umsicht
vorgehen, weil zwei Benutzer mit unterschiedlichen
Berechtigungen sich diese unter Umständen gegenseitig
gewähren können!
Sie können einem anderen Benutzer keine Berechtigung
gewähren, die Sie selbst nicht haben – mit GRANT
OPTION
können Sie nur solche Berechtigungen
vergeben, über die Sie selbst auch verfügen.
Beachten Sie, dass, wenn Sie einem Benutzer die Berechtigung
GRANT OPTION
für eine bestimmte
Berechtigungsebene gewähren, dieser Benutzer alle
Berechtigungen, die er für diese Ebene hat (oder in Zukunft
erhält), beliebig anderen Benutzern zuweisen kann.
Angenommen, Sie gewähren einem Benutzer die Berechtigung
INSERT
für eine Datenbank. Wenn Sie
nachfolgend die Berechtigung SELECT
für
die Datenbank gewähren und WITH GRANT
OPTION
angeben, dann kann dieser Benutzer anderen
Benutzern nicht nur die Berechtigung SELECT
gewähren, sondern auch die Berechtigung
INSERT
. Wenn Sie dann dem Benutzer die
Berechtigung UPDATE
für die Datenbank
gewähren, kann der Benutzer die Berechtigungen
INSERT
, SELECT
und
UPDATE
gewähren.
Einem nichtadministrativen Benutzer sollten Sie die
Berechtigung ALTER
weder global noch für
die Datenbank mysql
gewähren. Andernfalls
kann der Benutzer das Berechtigungssystem unterlaufen, indem
er Tabellen umbenennt!
Die Optionen MAX_QUERIES_PER_HOUR
,
count
MAX_UPDATES_PER_HOUR
und
count
MAX_CONNECTIONS_PER_HOUR
begrenzen die
Anzahl der Abfrage-, Update- und Anmeldevorgänge, die ein
Benutzer im Verlauf einer Stunde ausführen kann. Wenn
count
count
0
ist
(Standardeinstellung), dann heißt das, dass für den Benutzer
keine Beschränkung gilt.
Die Option MAX_USER_CONNECTIONS
schränkt die
maximale Anzahl gleichzeitiger Verbindungen ein, die das Konto
herstellen kann. Wenn count
count
0
ist (Standardeinstellung), dann bestimmt
die Systemvariable max_user_connections
die
Anzahl gleichzeitiger Verbindungen für das Konto.
Hinweis: Um für einen vorhandenen Benutzer eine solche Option
zur Ressourcenbeschränkung anzugeben, ohne vorhandene
Berechtigungen einzuschränken, verwenden Sie GRANT
USAGE ON *.* ... WITH MAX_...
.
Siehe auch Abschnitt 5.9.4, „Begrenzen von Benutzer-Ressourcen“.
MySQL kann zusätzlich zur normalen, auf Benutzernamen und
Passwörtern basierenden Authentifizierung Attribute von
X509-Zertifikaten überprüfen. Um SSL-spezifische Optionen
für ein MySQL-Konto anzugeben, verwenden Sie die
REQUIRE
-Klausel der
GRANT
-Anweisung. (Hintergrundinformationen
zur Verwendung von SSL mit MySQL finden Sie in
Abschnitt 5.9.7, „Verwendung sicherer Verbindungen“.)
Es gibt mehrere verschiedene Gründe zur Beschränkung der Verbindungstypen für ein gegebenes Konto:
Wenn für das Konto keine SSL- oder X509-Anforderungen vorhanden sind, sind unverschlüsselte Verbindungen zulässig, sofern Benutzername und Passwort gültig sind. Allerdings können nach Maßgabe des Clients auch verschlüsselte Verbindungen benutzt werden, sofern der Client über die entsprechenden Zertifikats- und Schlüsseldateien verfügt.
Die Option REQUIRE SSL
weist den Server
an, nur SSL-verschlüsselte Verbindungen für das Konto
zuzulassen. Beachten Sie, dass diese Option weggelassen
werden kann, wenn Zugriffssteuerungs-Datensätze vorhanden
sind, die Nicht-SSL-Verbindungen zulassen.
GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE SSL;
REQUIRE X509
bedeutet, dass der Client
ein gültiges Zertifikat vorweisen muss, dass aber das
Zertifikat selbst, der Aussteller und der Zweck keine
Rolle spielen. Erforderlich ist einzig und allein, dass
die Signatur bei einem Zertifikat geprüft werden können
muss.
GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE X509;
REQUIRE ISSUER
'
schränkt
Verbindungsversuche dahingehend ein, dass der Client ein
gültiges X509-Zertifikat vorweisen muss, welches von der
Zertifizierungsstelle
issuer
''
ausgestellt wurde. Wenn der Client ein Zertifikat
vorweist, das zwar gültig ist, aber von einem anderen
Anbieter stammt, dann weist der Server die Verbindung ab.
Die Verwendung von X509-Zertifikaten impliziert immer auch
eine Verschlüsselung, d. h., die Option
issuer
'SSL
wird in diesem Fall nicht
benötigt.
GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE ISSUER '/C=FI/ST=Some-State/L=Helsinki/ O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com';
Beachten Sie, dass die
'
-Werte
als einzelner String eingegeben werden sollten.
issuer
'
REQUIRE SUBJECT
'
schränkt
Verbindungsversuche dahingehend ein, dass der Client ein
gültiges X509-Zertifikat vorweisen muss, bei dem als
Zweck subject
'subject
angegeben ist.
Wenn der Client ein Zertifikat vorweist, das zwar gültig
ist, aber einen anderen Zweck angibt, dann weist der
Server die Verbindung ab.
GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/ O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com';
Beachten Sie, dass die
'
-Werte
als einzelner String eingegeben werden sollten.
subject
'
REQUIRE CIPHER
'
ist
erforderlich, um sicherzustellen, dass Chiffren und
Schlüssellängen ausreichender Stärke verwendet werden.
SSL selbst kann schwach sein, wenn alte Algorithmen kurze
Schlüssel zur Verschlüsselung einsetzen. Mit dieser
Option können Sie die Verwendung einer bestimmten
Chiffriermethode vorsehen, damit die Verbindung zulässig
ist.
cipher
'
GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA';
Die Optionen SUBJECT
,
ISSUER
und CIPHER
können in der REQUIRE
-Klausel wie folgt
kombiniert werden:
GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost' IDENTIFIED BY 'goodsecret' REQUIRE SUBJECT '/C=EE/ST=Some-State/L=Tallinn/ O=MySQL demo client certificate/ CN=Tonu Samuel/Email=tonu@example.com' AND ISSUER '/C=FI/ST=Some-State/L=Helsinki/ O=MySQL Finland AB/CN=Tonu Samuel/Email=tonu@example.com' AND CIPHER 'EDH-RSA-DES-CBC3-SHA';
Das Schlüsselwort AND
zwischen den
REQUIRE
-Optionen ist optional.
Die Reihenfolge der Optionen ist unerheblich, allerdings darf keine Option zweimal angegeben werden.
Wenn mysqld startet, werden alle Berechtigungen in den Speicher eingelesen. Detaillierte Informationen finden Sie in Abschnitt 5.8.7, „Wann Berechtigungsänderungen wirksam werden“.
Beachten Sie, dass, wenn Sie Tabellen-, Spalten- oder Routineberechtigungen auch für nur einen einzigen Benutzer verwenden, der Server die Tabellen-, Spalten- und Routineberechtigungen für alle Benutzer prüft. Dies kann MySQL ein wenig verlangsamen. Analog muss der Server, wenn Sie die Anzahl von Abfragen, Updates oder Verbindungen für Benutzer beschränken wollen, auch diese Werte überwachen.
Die wesentlichsten Unterschiede zwischen dem SQL-Standard und
den MySQL-Versionen von GRANT
sind die
folgenden:
In MySQL werden Berechtigungen mit einer Kombination aus Host- und Benutzernamen (und nicht nur mit einem Benutzernamen) verknüpft.
Der SQL-Standard bietet keine Berechtigungen auf globaler oder Datenbankebene und unterstützt auch nicht alle von MySQL unterstützten Berechtigungstypen.
MySQL unterstützt die Berechtigungen
TRIGGER
und UNDER
des SQL-Standards nicht.
Berechtigungen nach SQL-Standard sind hierarchisch
strukturiert. Wenn Sie einen Benutzer entfernen, werden
alle Berechtigungen widerrufen, die dieser Benutzer hatte.
Dies gilt auch für MySQL, wenn Sie DROP
USER
verwenden. Siehe auch
Abschnitt 13.5.1.2, „DROP USER
“.
Wenn Sie in Standard-SQL eine Tabelle löschen, werden
alle Berechtigungen für die Tabelle widerrufen. Wenn Sie
in Standard-SQL eine Berechtigung widerrufen, werden alle
Berechtigungen, die basierend auf dieser Berechtigung
gewährt wurden, ebenfalls widerrufen. In MySQL können
Berechtigungen nur mit expliziten
REVOKE
-Anweisungen oder durch
Manipulation der in den MySQL-Grant-Tabellen gespeicherten
Werte gelöscht werden.
In MySQL können INSERT
-Berechtigungen
auch für nur einige der Spalten in einer Tabelle gewährt
werden. In diesem Fall können Sie
INSERT
-Anweisungen für die Tabelle
trotzdem ausführen, sofern Sie diejenigen Spalten
weglassen, für die Sie keine
INSERT
-Berechtigung haben. Die
übergangenen Spalten können auf ihre impliziten
Vorgabewerte gesetzt werden, sofern der strikte SQL-Modus
nicht aktiviert ist. Im strikten Modus wird die Anweisung
abgewiesen, wenn eine der übergangenen Spalten keinen
Vorgabewert hat. (Der SQL-Standard sieht vor, dass Sie die
INSERT
-Berechtigung für alle Spalten
benötigen.) Abschnitt 5.2.5, „Der SQL-Modus des Servers“, beschreibt
den strikten Modus. Abschnitt 11.1.4, „Vorgabewerte von Datentypen“,
erläutert implizite Vorgabewerte.
RENAME USERold_user
TOnew_user
[,old_user
TOnew_user
] ...
Die RENAME USER
-Anweisung benennt
MySQL-Konten um. Um sie zu verwenden, benötigen Sie die
globale Berechtigung CREATE USER
oder die
Berechtigung UPDATE
für die Datenbank
mysql
. Ein Fehler tritt auf, wenn ein Konto
mit dem alten oder neuen Namen bereits existiert. Jedes Konto
wird im selben Format wie bei der
GRANT
-Anweisung benannt (z. B.
'jeffrey'@'localhost'
). Die Benutzer- und
Hostbestandteile des Kontonamens entsprechen den Werten der
Spalten User
und Host
des kontenspezifischen Datensatzes in der Tabelle
user
.
REVOKEpriv_type
[(column_list
)] [,priv_type
[(column_list
)]] ... ON [object_type
] {tbl_name
| * | *.* |db_name
.*} FROMuser
[,user
] ... REVOKE ALL PRIVILEGES, GRANT OPTION FROMuser
[,user
] ...
Die REVOKE
-Anweisung erlaubt
Systemadministratoren das Widerrufen von Berechtigungen für
MySQL-Konten. Um REVOKE
verwenden zu
können, benötigen Sie die Berechtigung GRANT
OPTION
sowie alle Berechtigungen, die Sie
widerrufen.
Informationen zu den Ebenen, auf denen Berechtigungen
vorhanden sind, den zulässigen Werten für
priv_type
und der Syntax zur Angabe
von Benutzern und Passwörtern finden Sie in
Abschnitt 13.5.1.3, „GRANT
und REVOKE
“.
Wenn in den Grant-Tabellen Berechtigungsdatensätze vorhanden
sind, die Datenbank- oder Tabellennamen mit gemischter
Groß-/Kleinschreibung enthalten, und die Systemvariable
lower_case_table_names
auf einen
Nicht-Null-Wert gesetzt ist, dann können diese Berechtigungen
nicht mit REVOKE
widerrufen werden. Es ist
dann erforderlich, die Grant-Tabellen direkt zu manipulieren.
(GRANT
erstellt solche Datensätze zwar
nicht, wenn lower_case_table_names
eingestellt ist, aber unter Umständen wurden derartige
Datensätze bereits vor Einstellen der Variablen erstellt.)
Um alle Berechtigungen zu widerrufen, verwenden Sie die folgende Syntax. Hiermit löschen Sie alle globalen Berechtigungen sowie alle Berechtigungen auf Datenbank-, Tabellen- und Spaltenebene für den oder die aufgeführten Benutzer:
REVOKE ALL PRIVILEGES, GRANT OPTION FROMuser
[,user
] ...
Um diese REVOKE
-Syntax zu verwenden,
benötigen Sie die globale Berechtigung CREATE
USER
oder die Berechtigung UPDATE
für die Datenbank mysql
.
SET PASSWORD = PASSWORD('some password
') SET PASSWORD FORuser
= PASSWORD('some password
')
Die Anweisung SET PASSWORD
weist einem
vorhandenen MySQL-Benutzerkonto ein Passwort zu.
Die erste Syntax stellt das Passwort für den aktuellen Benutzer ein. Ein Client, der über ein nichtanonymes Konto eine Verbindung mit dem Server hergestellt hat, kann das Passwort für dieses Konto ändern.
Die zweite Syntax stellt das Passwort für ein bestimmtes
Konto auf dem aktuellen Serverhost ein. Nur Clients mit der
Berechtigung UPDATE
für die Datenbank
mysql
können dies tun. Der Wert
user
sollte im Format
angegeben werden, wobei user_name
@host_name
user_name
und host_name
exakt so aufgeführt
werden müssen, wie sie in den Spalten User
bzw. Host
des entsprechenden Eintrags in
der Tabelle mysql.user
notiert sind. Wenn
Sie beispielsweise einen Eintrag mit den Werten
'bob'
und '%.loc.gov'
in
den Spalten User
bzw.
Host
haben, dann würden Sie die Anweisung
wie folgt schreiben:
SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass
');
Dies entspricht den folgenden Anweisungen:
UPDATE mysql.user SET Password=PASSWORD('newpass
')
WHERE User='bob' AND Host='%.loc.gov';
FLUSH PRIVILEGES;
Hinweis: Wenn Sie mit einem
Clientprogramm vor Version 4.1 eine Verbindung zu einem Server
unter MySQL 4.1 oder höher herstellen, verwenden Sie die
obigen Anweisungen SET PASSWORD
oder
UPDATE
erst, wenn Sie
Abschnitt 5.8.9, „Kennwort-Hashing ab MySQL 4.1“, gelesen haben. Das
Passwortformat wurde in MySQL 4.1 geändert, und unter
bestimmten Bedingungen ist es möglich, dass Sie, wenn Sie Ihr
Passwort ändern, nachfolgend keine Serververbindung mehr
herstellen können.
Sie können anzeigen, unter welchem Konto der Server Sie
authentifiziert hat, indem Sie SELECT
CURRENT_USER()
ausführen.
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_name
[,tbl_name
] ...
ANALYZE TABLE
analysiert und speichert die
Schlüsselverteilung für eine Tabelle. Während der Analyse
ist die Tabelle mit einer Lesesperre versehen. Diese Anweisung
funktioniert nur bei MyISAM
-,
BDB
- und
InnoDB
-Tabellen. Bei
MyISAM
-Tabellen ist sie äquivalent zur
Verwendung von myisamchk -a.
MySQL verwendet die gespeicherte Schlüsselverteilung, um die Reihenfolge zu ermitteln, in der die Tabellen verknüpft werden sollen, wenn Sie einen Join mit etwas anderem als einer Konstante durchführen.
ANALYZE TABLE
gibt eine Ergebnismenge mit
den folgenden Spalten zurück:
Spalte | Wert |
Table | der Tabellenname |
Op | ist immer analyze |
Msg_type | status , error ,
info oder
warning |
Msg_text | die Nachricht |
Sie können die gespeicherte Schlüsselverteilung mit der
SHOW INDEX
-Anweisung vergleichen. Siehe
auch Abschnitt 13.5.4.12, „SHOW INDEX
“.
Wenn die Tabelle seit der letzten ANALYZE
TABLE
-Anweisung nicht geändert wurde, wird die
Tabelle nicht erneut analysiert.
ANALYZE TABLE
-Anweisungen werden in das
Binärlog geschrieben, sofern das optionale Schlüsselwort
NO_WRITE_TO_BINLOG
(oder sein Alias
LOCAL
) nicht verwendet wird. Dies wird
gemacht, damit ANALYZE TABLE
-Anweisungen,
die auf einem MySQL Server verwendet werden, der als
Replikationsmaster agiert, standardmäßig auf den
Replikationsslave repliziert werden.
BACKUP TABLEtbl_name
[,tbl_name
] ... TO '/path/to/backup/directory
'
Hinweis: Diese Anweisung ist veraltet. Wir arbeiten derzeit an einem besseren Ersatz, der auch die Online-Sicherung unterstützt. In der Zwischenzeit kann stattdessen das Skript mysqlhotcopy verwendet werden.
BACKUP TABLE
kopiert die minimale Anzahl an
Tabellendateien, die zur Wiederherstellung der Tabelle
benötigt werden, in das Sicherungsverzeichnis, nachdem ggf.
gepufferte Änderungen auf Festplatte geschrieben wurden. Die
Anweisung funktioniert nur bei
MyISAM
-Tabellen. Sie kopiert die
Definitionsdatei (.frm
) und die
Datendatei (.MYD
). Die
.MYI
-Indexdatei kann aus diesen beiden
Dateien neu erstellt werden. Das Verzeichnis sollte als
vollständiger Pfadname angegeben werden. Um die Tabelle
wiederherzustellen, verwenden Sie RESTORE
TABLE
.
Während des Backups wird für jede Tabelle für den Verlauf
des Sicherungsvorgangs eine Lesesperre gehalten (d. h. immer
für eine Tabelle gleichzeitig). Wenn Sie mehrere Tabellen als
Momentaufnahme sichern wollen (und dabei vermeiden wollen,
dass diese während der Sicherung geändert werden), setzen
Sie zunächst eine LOCK TABLES
-Anweisung
ab, um eine Lesesperre für alle betreffenden Tabellen zu
erwirken.
BACKUP TABLE
gibt eine Ergebnismenge mit
den folgenden Spalten zurück:
Spalte | Wert |
Table | der Tabellenname |
Op | ist immer backup |
Msg_type | status , error ,
info oder
warning |
Msg_text | die Nachricht |
CHECK TABLEtbl_name
[,tbl_name
] ... [option
] ...option
= {QUICK | FAST | MEDIUM | EXTENDED | CHANGED}
CHECK TABLE
prüft eine oder mehrere
Tabellen auf Fehler. CHECK TABLE
funktioniert bei MyISAM
- und
InnoDB
-Tabellen. Bei
MyISAM
-Tabellen werden auch die
Schlüsselstatistiken aktualisiert.
CHECK TABLE
kann auch Views auf Probleme
prüfen, z. B. in der View-Definition referenzierte Tabellen,
die nicht mehr vorhanden sind.
CHECK TABLE
gibt eine Ergebnismenge mit den
folgenden Spalten zurück:
Spalte | Wert |
Table | der Tabellenname |
Op | ist immer check |
Msg_type | status , error ,
info oder
warning |
Msg_text | die Nachricht |
Beachten Sie, dass die Anweisung unter Umständen viele
Datensätze für die überprüfte Tabelle ausgeben kann. Der
letzte Datensatz hat den Msg_type
-Wert
status
; Msg_text
sollte
normalerweise den Wert OK
haben. Wenn Sie
nicht den Wert OK
oder aber die Meldung
Table is already up to date
erhalten,
sollten Sie eine Reparatur der Tabelle durchführen. Siehe
auch Abschnitt 5.10.4, „Benutzung von myisamchk
für Tabellenwartung und Absturzreparatur“. Table is
already up to date
bedeutet, dass die
Speicher-Engine für die Tabelle angegeben hat, dass es keine
Notwendigkeit zur Überprüfung gibt.
Die verschiedenen Prüfoptionen, die angegeben werden können,
sind in der folgenden Tabelle aufgeführt. Die Optionen dienen
nur der Überprüfung von MyISAM
-Tabellen;
bei InnoDB
-Tabellen und Views werden sie
ignoriert.
Typ | Bedeutung |
QUICK | überprüft Datensätze nicht auf falsche Verknüpfungen. |
FAST | Überprüft nur Tabellen, die nicht ordnungsgemäß geschlossen wurden. |
CHANGED | überprüft nur solche Tabellen, die seit der letzten Überprüfung geändert oder aber nicht korrekt geschlossen wurden. |
MEDIUM | prüft Datensätze, um sicherzustellen, dass gelöschte Verknüpfungen gültig sind. Hierbei wird auch eine Schlüsselprüfsumme für die Datensätze berechnet, die dann mit einer berechneten Prüfsumme für die Schlüssel verglichen wird. |
EXTENDED | führt eine vollständige Schlüsselsuche für alle Schlüssel in jedem Datensatz durch. Hierdurch wird sichergestellt, dass die Tabelle hundertprozentig konsistent ist, der Vorgang dauert aber sehr lange. |
Wenn keine der Optionen QUICK
,
MEDIUM
oder EXTENDED
angegeben wird, wird standardmäßig MEDIUM
als Prüftyp für dynamische
MyISAM
-Tabellen verwendet. Dies hat
dieselben Auswirkungen wie die Ausführung von
myisamchk --medium-check
tbl_name
für die
Tabelle. Auch bei statischen
MyISAM
-Tabellen ist
MEDIUM
der Standardtyp, sofern nicht
CHANGED
oder FAST
angegeben wurde. (In diesen Fällen ist
QUICK
der Vorgabewert.) Der Datensatzscan
wird bei CHANGED
und
FAST
übersprungen, weil die Datensätze
sehr selten beschädigt sind.
Sie können Prüfoptionen auch kombinieren. Im folgenden Beispiel etwa erfolgt eine schnelle Prüfung der Tabelle, um zu ermitteln, ob sie korrekt geschlossen wurde:
CHECK TABLE test_table FAST QUICK;
Hinweis: In manchen Fällen
verändert CHECK TABLE
die Tabelle. Dies
geschieht, wenn die Tabelle als „beschädigt“
oder „nicht korrekt geschlossen“ gekennzeichnet
wurde, aber CHECK TABLE
keine Probleme in
der Tabelle findet. In diesem Fall kennzeichnet CHECK
TABLE
die Tabelle als fehlerfrei.
Wenn eine Tabelle beschädigt ist, liegt das Problem wahrscheinlich bei den Indizes und nicht im Datenteil vor. Alle bislang genannten Prüftypen führen eine umfassende Indexprüfung durch und sollten aufgrund dessen die meisten Fehler finden.
Wenn Sie eine Tabelle, bei der Sie davon ausgehen, dass sie in
Ordnung ist, nur sicherheitshalber überprüfen wollen, dann
sollten Sie entweder keine Prüfoption oder die Option
QUICK
angeben. Letzteres sollten Sie tun,
wenn Sie sehr in Eile sind und das sehr geringe Risiko in Kauf
nehmen wollen, dass QUICK
einen Fehler in
der Datendatei nicht findet. (In den meisten Fällen sollte
MySQL bei normaler Verwendung alle ggf. in der Datendatei
vorhandenen Fehler finden. Geschieht dies, so wird die Tabelle
als „beschädigt“ gekennzeichnet und kann erst
wieder verwendet werden, nachdem sie repariert wurde.)
FAST
und CHANGED
sollen
in erster Linie aus Skripten (die etwa mit
cron ausgeführt werden) heraus verwendet
werden, wenn Sie Ihre Tabellen von Zeit zu Zeit überprüfen
wollen. In den meisten Fällen ist FAST
CHANGED
vorzuziehen. (Der einzige Fall, wo
dies nicht zutrifft, liegt vor, wenn Sie annehmen, einen Bug
im MyISAM
-Code gefunden zu haben.)
EXTENDED
sollte erst verwendet werden, wenn
Sie bereits eine normale Überprüfung durchgeführt haben,
aber immer noch merkwürdige Fehler zu einer Tabelle erhalten,
sobald MySQL versucht, einen Datensatz zu aktualisieren oder
einen Datensatz nach seinem Schlüssel zu finden. Die
Wahrscheinlichkeit, dass so etwas nach einer normalen
Überprüfung passiert, ist sehr gering.
Einige Probleme, die von CHECK TABLE
gemeldet werden, können nicht automatisch behoben werden:
Found row where the auto_increment column has the
value 0
.
Das bedeutet, dass Sie einen Datensatz in der Tabelle
haben, bei dem die
AUTO_INCREMENT
-Indexspalte den Wert 0
enthält. (Ein Datensatz, bei dem die
AUTO_INCREMENT
-Spalte 0 ist, kann
tatsächlich erzeugt werden, indem die Spalte mit
UPDATE
explizit auf 0 gesetzt wird.)
Dies ist an sich kein Fehler, kann aber Probleme
verursachen, wenn Sie beschließen, die Tabelle zu
speichern und sie dann wiederherzustellen, oder eine
ALTER TABLE
-Anweisung an die Tabelle
absetzen. In diesem Fall ändert die
AUTO_INCREMENT
-Spalte ihren Wert
entsprechend den Regeln für
AUTO_INCREMENT
-Spalten, was Probleme
wie beispielsweise Schlüsseldubletten verursachen kann.
Um die Warnung zu beseitigen, führen Sie einfach eine
UPDATE
-Anweisung aus, um die Spalte auf
einen anderen Wert als 0 zu setzen.
CHECKSUM TABLEtbl_name
[,tbl_name
] ... [ QUICK | EXTENDED ]
CHECKSUM TABLE
meldet eine
Tabellenprüfsumme.
Bei QUICK
wird – sofern möglich – die
mitlaufende Prüfsumme gemeldet, andernfalls
NULL
. Dies ist sehr schnell. Eine
mitlaufende Prüfsumme wird durch Angabe der Tabellenoption
CHECKSUM = 1
bei Erstellung der Tabelle
aktiviert. Zurzeit wird dies nur bei
MyISAM
-Tabellen unterstützt. Siehe auch
Abschnitt 13.1.5, „CREATE TABLE
“.
Bei EXTENDED
wird die gesamte Tabelle
Datensatz für Datensatz gelesen und die Prüfsumme berechnet.
Dies kann bei großen Tabellen sehr lange dauern.
Wenn weder QUICK
noch
EXTENDED
angegeben sind, gibt MySQL eine
mitlaufende Prüfsumme zurück, wenn die Speicher-Engine der
Tabelle dies unterstützt; andernfalls wird die Tabelle
gescannt.
Bei einer nichtexistenten Tabelle gibt CHECKSUM
TABLE
NULL
zurück und erzeugt
eine Warnung.
OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_name
[,tbl_name
] ...
OPTIMIZE TABLE
sollte verwendet werden,
wenn Sie einen umfangreichen Teil einer Tabelle gelöscht oder
viele Änderungen an einer Tabelle mit Datensätzen variabler
Länge (also Tabellen mit VARCHAR
-,
VARBINARY
-, BLOB
- oder
TEXT
-Spalten) vorgenommen haben. Gelöschte
Datensätze werden zu einer verknüpften Liste hinzugefügt.
Nachfolgende INSERT
-Operationen verwenden
die alten Datensatzpositionen neu. Sie können mit
OPTIMIZE TABLE
nichtverwendeten Speicher in
der Tabelle freigeben und die Datendatei defragmentieren.
In den meisten Konfigurationen müssen Sie OPTIMIZE
TABLE
gar nicht ausführen. Auch wenn Sie viele
Änderungen an Datensätzen variabler Länge vorgenommen
haben, ist die Wahrscheinlichkeit, dass Sie dies häufiger als
einmal in der Woche oder im Monat tun müssen, sehr gering –
und selbst dies nur bei bestimmten Tabellen.
OPTIMIZE TABLE
funktioniert nur bei
MyISAM
-, BDB
- und
InnoDB
-Tabellen.
Bei MyISAM
-Tabellen funktioniert
OPTIMIZE TABLE
wie folgt:
Wenn die Tabelle gelöschte oder geteilte Datensätze aufweist, wird die Tabelle repariert.
Wenn die Indexseiten nicht sortiert sind, werden sie sortiert.
Wenn die Tabellenstatistiken nicht aktuell sind (und eine Reparatur durch Sortierung des Indexes nicht erfolgreich war), werden sie aktualisiert.
Bei BDB
wird OPTIMIZE
TABLE
zurzeit auf ANALYZE TABLE
umgesetzt. Siehe auch Abschnitt 13.5.2.1, „ANALYZE TABLE
“.
Bei InnoDB
wird OPTIMIZE
TABLE
auf ALTER TABLE
umgesetzt,
wodurch die Tabelle neu erstellt wird, um Indexstatistiken zu
aktualisieren und ungenutzten Speicher im Cluster-Index
freizugeben.
Sie können OPTIMIZE TABLE
auch bei anderen
Speicher-Engines zum Laufen bringen, indem Sie
mysqld mit den Optionen
--skip-new
oder --safe-mode
starten. In diesem Fall wird OPTIMIZE TABLE
einfach auf ALTER TABLE
umgesetzt.
OPTIMIZE TABLE
gibt eine Ergebnismenge mit
den folgenden Spalten zurück:
Spalte | Wert |
Table | der Tabellenname |
Op | ist immer optimize |
Msg_type | status , error ,
info oder
warning |
Msg_text | die Nachricht |
Beachten Sie, dass MySQL die Tabelle während der Laufzeit von
OPTIMIZE TABLE
sperrt.
OPTIMIZE TABLE
-Anweisungen werden in das
Binärlog geschrieben, sofern das optionale Schlüsselwort
NO_WRITE_TO_BINLOG
(oder sein Alias
LOCAL
) nicht verwendet wird. Dies wird
gemacht, damit OPTIMIZE TABLE
-Anweisungen,
die auf einem MySQL Server verwendet werden, der als
Replikationsmaster agiert, standardmäßig auf den
Replikationsslave repliziert werden.
REPAIR [LOCAL | NO_WRITE_TO_BINLOG] TABLEtbl_name
[,tbl_name
] ... [QUICK] [EXTENDED] [USE_FRM]
REPAIR TABLE
repariert eine unter
Umständen beschädigte Tabelle. Standardmäßig hat dies
dieselbe Wirkung wie myisamchk --recover
tbl_name
. REPAIR
TABLE
funktioniert bei MyISAM
-
und ARCHIVE
-Tabellen. Siehe auch
Abschnitt 14.1, „Die MyISAM
-Speicher-Engine“, und
Abschnitt 14.8, „Die ARCHIVE
-Speicher-Engine“.
Im Normalfall werden Sie diese Anweisung niemals ausführen.
Im Katastrophenfall kann REPAIR TABLE
Ihnen
aber sehr wahrscheinlich alle Daten aus einer
MyISAM
-Tabelle wiederherstellen. Treten bei
Ihren Tabellen häufig Beschädigungen auf, dann sollten Sie
versuchen, den Grund dafür zu ermitteln, um REPAIR
TABLE
nicht mehr fortlaufend einsetzen zu müssen.
Siehe auch Abschnitt A.4.2, „Was zu tun ist, wenn MySQL andauernd abstürzt“, und
Abschnitt 14.1.4, „MyISAM-Tabellenprobleme“.
Warnung: Wenn sich der Server
während eines REPAIR TABLE
-Vorgangs
aufhängt, ist es unabdingbar, unmittelbar nach dem Neustart
eine neue REPAIR TABLE
-Anweisung für die
Tabelle abzusetzen, bevor Sie weitere Operationen an ihr
vornehmen. (Es bietet sich ohnehin immer an, zuallererst ein
Backup zu erstellen.) Im schlimmsten Fall haben Sie unter
Umständen eine neue saubere Indexdatei ohne Informationen zur
Datendatei – und könnten im nächsten Schritt
möglicherweise Ihre Datendatei überschreiben! Dies ist ein
unwahrscheinliches, aber durchaus mögliches Szenario.
REPAIR TABLE
gibt eine Ergebnismenge mit
den folgenden Spalten zurück:
Spalte | Wert |
Table | der Tabellenname |
Op | ist immer repair |
Msg_type | status , error ,
info oder
warning |
Msg_text | die Nachricht |
Die Anweisung REPAIR TABLE
kann unter
Umständen viele Datensätze für die reparierte Tabelle
ausgeben. Der letzte Datensatz hat den
Msg_type
-Wert status
;
Msg_test
sollte normalerweise den Wert
OK
haben. Wenn Sie einen anderen Status als
OK
erhalten, sollten Sie die Tabelle mit
myisamchk --safe-recover zu reparieren
versuchen. (REPAIR TABLE
implementiert noch
nicht alle Optionen von myisamchk. Wir
beabsichtigen aber, die Anweisung in Zukunft flexibler zu
gestalten.) Mit myisamchk --safe-recover
können Sie auch Optionen verwenden, die REPAIR
TABLE
nicht unterstützt (z. B.
--max-record-length
).
Wenn QUICK
angegeben wird, versucht
REPAIR TABLE
, nur den Indexbaum zu
reparieren. Dieser Reparaturtyp ähnelt dem von
myisamchk --recover --quick.
Wenn Sie EXTENDED
verwenden, erstellt MySQL
den Index Datensatz für Datensatz, statt einen Index
gleichzeitig beim Sortieren zu erzeugen. Dieser Reparaturtyp
ähnelt dem von myisamchk --safe-recover.
Es gibt auch einen Modus USE_FRM
für
REPAIR TABLE
. Diesen verwenden Sie, wenn
die .MYI
-Indexdatei fehlt oder ihr Header
beschädigt ist. In diesem Modus erstellt MySQL die
.MYI
-Datei auf der Basis der Daten aus
der .frm
-Datei neu. Diese Art der
Reparatur ist mit myisamchk nicht möglich.
Hinweis: Verwenden Sie diesen
Modus nur, wenn Sie die regulären
REPAIR
-Modi nicht einsetzen können. Der
.MYI
-Header enthält wichtige
Tabellenmetadaten (insbesondere etwa den
AUTO_INCREMENT
-Wert und Delete
link
), die bei REPAIR ... USE_FRM
verloren gehen. Verwenden Sie USE_FRM
nicht
für eine komprimierte Tabelle, weil diese Informationen auch
in der .MYI
-Datei gespeichert sind.
REPAIR TABLE
-Anweisungen werden in das
Binärlog geschrieben, sofern das optionale Schlüsselwort
NO_WRITE_TO_BINLOG
(oder sein Alias
LOCAL
) nicht verwendet wird. Dies wird
gemacht, damit REPAIR TABLE
-Anweisungen,
die auf einem MySQL Server verwendet werden, der als
Replikationsmaster agiert, standardmäßig auf den
Replikationsslave repliziert werden.
RESTORE TABLEtbl_name
[,tbl_name
] ... FROM '/path/to/backup/directory
'
RESTORE TABLE
stellt eine oder mehrere
Tabellen aus einer Sicherung, die mit BACKUP
TABLE
erstellt wurde, wieder her. Vorhandene
Tabellen werden nicht überschrieben: Wenn Sie versuchen, eine
vorhandene Tabelle durch Wiederherstellen zu überschreiben,
dann tritt ein Fehler auf. Wie BACKUP TABLE
funktioniert auch RESTORE TABLE
derzeit nur
für MyISAM
-Tabellen. Das Verzeichnis
sollte als vollständiger Pfadname angegeben werden.
Das Backup einer Tabelle besteht aus ihrer
.frm
-Formatdatei und der
.MYD
-Datendatei. Beim
Wiederherstellungsvorgang werden diese Dateien zunächst
wiederhergestellt; darauf basierend wird dann die
.MYI
-Indexdatei erstellt. Die
Wiederherstellung dauert länger als die Sicherung, weil die
Indizes neu erstellt werden müssen. Je mehr Indizes die
Tabelle hat, desto länger dauert der Vorgang.
RESTORE TABLE
gibt eine Ergebnismenge mit
den folgenden Spalten zurück:
Spalte | Wert |
Table | der Tabellenname |
Op | ist immer restore |
Msg_type | status , error ,
info oder
warning |
Msg_text | die Nachricht |
SETvariable_assignment
[,variable_assignment
] ...variable_assignment
:user_var_name
=expr
| [GLOBAL | SESSION]system_var_name
=expr
| [@@global. | @@session. | @@]system_var_name
=expr
Die Anweisung SET
weist verschiedenen Arten
von Variablen, die sich auf den Betrieb des Servers oder Ihres
Clients auswirken, Werte zu.
Dieser Abschnitt beschreibt die Verwendung von
SET
zur Zuweisung von Werten an System- oder
Benutzervariablen. Allgemeine Informationen zu diesen
Variablentypen finden Sie in
Abschnitt 5.2.2, „Server-Systemvariablen“, und
Abschnitt 9.3, „Benutzerdefinierte Variablen“. Eine Liste der
Systemvariablen, die dynamisch zur Laufzeit geändert werden
können, finden Sie in
Abschnitt 5.2.3.2, „Dynamische Systemvariablen“.
Hinweis: Ältere Versionen von MySQL
verwendeten SET OPTION
. Diese Funktionalität
ist jedoch veraltet – mittlerweile wird SET
nur noch ohne OPTION
benutzt.
Es gibt auch Varianten der SET
-Syntax, die in
anderen Kontexten verwendet werden:
SET PASSWORD
weist Kontenpasswörter zu.
Siehe auch Abschnitt 13.5.1.6, „SET PASSWORD
“.
SET TRANSACTION ISOLATION LEVEL
bestimmt
die Isolierungsstufe für die Transaktionsverarbeitung.
Siehe auch Abschnitt 13.4.6, „SET TRANSACTION
“.
SET
wird in gespeicherten Routinen
benutzt, um lokalen Routinenvariablen Werte zuzuweisen.
Siehe auch Abschnitt 19.2.7.2, „Variable SET
-Anweisung“.
Die folgende Erläuterung zeigt die verschiedenen
SET
-Syntaxen, die zur Einstellung von
Variablen benutzt werden können. In den Beispielen wird jeweils
der Zuweisungsoperator =
benutzt, der
Operator :=
ist aber ebenfalls zulässig.
Eine Benutzervariable wird als
@
geschrieben und kann wie folgt eingestellt werden:
var_name
SET @var_name
=expr
;
Systemvariablen werden in SET
-Anweisungen als
var_name
referenziert. Unter
Umständen kann ihnen auch ein Modifizierer vorangestellt sein:
Um explizit anzugeben, dass eine Variable eine globale
Variable ist, stellen Sie dem Namen
GLOBAL
oder @@global.
voran. Zum Einstellen globaler Variablen ist die
Berechtigung SUPER
erforderlich.
Um explizit anzugeben, dass eine Variable eine
Sitzungsvariable ist, stellen Sie dem Namen
SESSION
oder
@@session.
voran.
LOCAL
und @@local.
sind Synonyme von SESSION
bzw.
@@session.
.
Ist kein Modifizierer vorhanden, dann stellt
SET
die Sitzungsvariable ein.
Ein paar Beispiele:
SET sort_buffer_size=10000; SET @@local.sort_buffer_size=10000; SET GLOBAL sort_buffer_size=1000000, SESSION sort_buffer_size=1000000; SET @@sort_buffer_size=1000000; SET @@global.sort_buffer_size=1000000, @@local.sort_buffer_size=1000000;
Die Syntax
@@
für
Systemvariablen wird unterstützt, damit die MySQL-Syntax mit
einigen anderen Datenbanksystemen kompatibel ist.
var_name
Wenn Sie mehrere Systemvariablen in derselben Anweisung
einstellen, wird die zuletzt angegebene
GLOBAL
- oder
SESSION
-Option für Variablen verwendet,
deren Modus nicht näher spezifiziert ist.
Wenn Sie eine sitzungsspezifische Systemvariable einstellen, bleibt der Wert gültig, bis die aktuelle Sitzung endet oder Sie der Variablen einen anderen Wert zuweisen. Stellen Sie eine globale Systemvariable ein, dann wird der Wert gespeichert und bis zum nächsten Neustart des Servers für alle neuen Verbindungen verwendet. Wenn Sie den Wert einer globalen Systemvariablen permanent ändern wollen, sollten Sie diesen in eine Optionsdatei eintragen. Siehe auch Abschnitt 4.3.2, „my.cnf-Optionsdateien“.
Um eine falsche Verwendung zu verhindern, erzeugt MySQL einen
Fehler, wenn Sie SET GLOBAL
für eine
Variable verwenden, für die nur SET SESSION
zulässig ist, oder GLOBAL
(bzw.
@@global.
) beim Einstellen einer globalen
Variablen nicht angeben.
Um eine SESSION
-Variable auf den
GLOBAL
-Wert oder eine
GLOBAL
-Variable auf den in MySQL
einkompilierten Standardwert zu setzen, verwenden Sie das
Schlüsselwort DEFAULT
. So sind
beispielsweise die beiden folgenden Anweisungen dahingehend
identisch, dass sie den Sitzungswert von
max_join_size
auf den globalen Wert setzen:
SET max_join_size=DEFAULT; SET @@session.max_join_size=@@global.max_join_size;
Es lassen sich nicht alle Systemvariablen auf
DEFAULT
setzen. In solchen Fällen tritt bei
Verwendung von DEFAULT
ein Fehler auf.
Eine Liste der Systemvariablen und ihrer Werte zeigen Sie mit
der SHOW VARIABLES
-Anweisung an. (Siehe auch
Abschnitt 13.5.4.24, „SHOW VARIABLES
“.) Um einen bestimmten
Variablennamen oder eine Liste der Namen zu erhalten, die einem
Muster entsprechen, verwenden Sie eine
LIKE
-Klausel wie folgt:
SHOW VARIABLES LIKE 'max_join_size'; SHOW GLOBAL VARIABLES LIKE 'max_join_size';
Zum Anzeigen einer Variablenliste, deren Namen einem Muster
entsprechen, verwenden Sie das Jokerzeichen
‘%
’:
SHOW VARIABLES LIKE '%size%'; SHOW GLOBAL VARIABLES LIKE '%size%';
Jokerzeichen können an beliebiger Position im Vergleichsmuster stehen.
Sie können den Wert einer bestimmten Systemvariablen auch mit
SELECT
ermitteln, indem Sie die Syntax
@@[global.|session.]
benutzen:
var_name
SELECT @@global.max_join_size, @@session.max_join_size;
Wenn Sie eine Variable mit SELECT
@@
(ohne
Modifizierer) abrufen, gibt MySQL den
var_name
SESSION
-Wert, sofern dieser vorhanden ist,
und andernfalls den GLOBAL
-Wert zurück.
(Hier liegt ein Unterschied zu SET
@@
vor, wo immer der
Sitzungswert referenziert wird.)
var_name
=
value
Die folgende Liste beschreibt Variablen, die keine
Standardsyntax aufweisen oder nicht in der in
Abschnitt 5.2.2, „Server-Systemvariablen“, aufgeführten Liste
der Systemvariablen beschrieben sind. Zwar werden die hier
beschriebenen Variablen nicht von SHOW
VARIABLES
angezeigt, Sie können die Werte aber mit
SELECT
abrufen (Ausnahmen sind
CHARACTER SET
und SET
NAMES
). Zum Beispiel:
mysql> SELECT @@AUTOCOMMIT;
+--------------+
| @@AUTOCOMMIT |
+--------------+
| 1 |
+--------------+
Die Groß-/Kleinschreibung dieser Optionen ist irrelevant.
AUTOCOMMIT = {0 | 1}
Stellt den Autocommit-Modus ein. Mit der Einstellung 1
werden alle Änderungen direkt übernommen. Wenn Sie 0
wählen, müssen Sie eine Transaktion mit
COMMIT
übergeben oder sie mit
ROLLBACK
abbrechen. Standardmäßig
starten Clientverbindungen mit dem
AUTOCOMMIT
-Wert 1. Wenn Sie
AUTOCOMMIT
von 0 auf 1 umstellen, führt
MySQL automatisch eine COMMIT
-Anweisung
für alle offenen Transaktionen aus. Eine andere
Möglichkeit, eine Transaktion zu starten, besteht in der
Verwendung der Anweisungen START
TRANSACTION
oder BEGIN
. Siehe
auch Abschnitt 13.4.1, „BEGIN/COMMIT/ROLLBACK
“.
Beim Wert 1 werden alle Temporärtabellen auf der Festplatte
statt im Arbeitsspeicher abgelegt. Dies ist ein wenig
langsamer, aber der Fehler The table
tritt
nicht bei tbl_name
is fullSELECT
-Operationen auf, die
eine große Temporärtabelle erfordern. Der Standardwert bei
einer neuen Verbindung ist 0 (d. h., es werden
speicherresidente Temporärtabellen verwendet). Im
Normalfall sollten Sie diese Variable niemals umstellen
müssen, da speicherresidente Tabellen nach Bedarf
automatisch in festplattenbasierte Tabellen konvertiert
werden. (Hinweis: Diese
Variable hieß früher SQL_BIG_TABLES
.)
CHARACTER SET
{
charset_name
|
DEFAULT}
Hiermit werden alle Strings vom und an den Client den
Angaben entsprechend konvertiert. Sie können neue
Zuordnungen angeben, indem Sie die Datei
sql/convert.cc
in der
MySQL-Quelldistribution bearbeiten. SET CHARACTER
SET
stellt drei sitzungsspezifische
Systemvariablen ein: character_set_client
und character_set_results
werden auf den
angegebenen Zeichensatz gesetzt,
character_set_connection
auf den Wert von
character_set_database
. Siehe auch
Abschnitt 10.4, „Verbindungszeichensatz und -sortierfolge“.
Die Standardzuordnung kann mit dem Wert
DEFAULT
wiederhergestellt werden.
Beachten Sie, dass die Syntax sich bei SET
CHARACTER SET
von der zur Einstellung der meisten
anderen Optionen unterscheidet.
FOREIGN_KEY_CHECKS = {0 | 1}
Bei der Einstellung 1 (Vorgabe) werden
Fremdschlüssel-Constraints für
InnoDB
-Tabellen überprüft. Bei der
Einstellung 0 werden sie ignoriert. Die Deaktivierung der
Fremdschlüsselüberprüfung kann nützlich sein, um
InnoDB
-Tabellen in einer anderen als der
Reihenfolge neu zu laden, die von den
Parent/Child-Beziehungen erfordert wird. Siehe auch
Abschnitt 14.2.6.4, „Fremdschlüssel-Beschränkungen“.
IDENTITY =
value
Diese Variable ist synonym zur Variablen
LAST_INSERT_ID
. Sie ist aus Gründen der
Kompatibilität mit anderen Datenbanksystemen vorhanden. Sie
können ihren Wert mit SELECT @@IDENTITY
auslesen und mit SET IDENTITY
einstellen.
INSERT_ID =
value
Stellt den von der folgenden INSERT
- oder
ALTER TABLE
-Anweisung zu verwendenden
Wert ein, wenn ein AUTO_INCREMENT
-Wert
eingefügt wird. Wird in erster Linie beim Binärlog
benutzt.
LAST_INSERT_ID =
value
Stellt den von LAST_INSERT_ID()
zurückzugebenden Wert ein. Dieser wird im Binärlog
gespeichert, wenn Sie LAST_INSERT_ID()
in
einer Anweisung verwenden, die eine Tabelle aktualisiert.
Durch Einstellen dieser Variablen wird der von der
C-API-Funktion mysql_insert_id()
zurückgegebene Wert nicht geändert.
NAMES {'
charset_name
' |
DEFAULT}
SET NAMES
setzt die drei Systemvariablen
character_set_client
,
character_set_connection
und
character_set_results
auf den angegebenen
Zeichensatz. Das Einstellen von
character_set_connection
auf
charset_name
setzt
collation_connection
auf die
Standardsortierfolge für charset_name
.
Siehe auch Abschnitt 10.4, „Verbindungszeichensatz und -sortierfolge“.
Die Standardzuordnung kann mit dem Wert
DEFAULT
wiederhergestellt werden.
Beachten Sie, dass die Syntax sich bei SET
NAMES
von der zur Einstellung der meisten anderen
Optionen unterscheidet.
ONE_SHOT
Diese Option ist ein Modifizierer und keine Variable. Sie
kann verwendet werden, um die Wirkung von Variablen zu
beeinflussen, die den Zeichensatz, die Sortierfolge und die
Zeitzone einstellen. ONE_SHOT
wird in
erster Linie zu Replikationszwecken eingesetzt.
mysqlbinlog verwendet SET
ONE_SHOT
zur vorübergehenden Änderung der Werte
von Zeichensatz-, Sortierfolgen- und Zeitzonenvariablen, um
die ursprünglichen Werte für einen Rollforward zu
speichern.
Sie können ONE_SHOT
nur mit den
zulässigen Variablen verwenden, andernfalls erhalten Sie
einen Fehler wie den folgenden:
mysql> SET ONE_SHOT max_allowed_packet = 1;
ERROR 1382 (HY000): The 'SET ONE_SHOT' syntax is reserved for purposes
internal to the MySQL server
Wenn ONE_SHOT
mit zulässigen Variablen
benutzt wird, ändert es die Variablen nach Bedarf –
jedoch nur für die nächste Anweisung, die nicht
SET
ist. Nachfolgend setzt der Server
alle zeichensatz-, sortierfolgen- und zeitzonenspezifischen
Systemvariablen auf ihre vorherigen Werte. Beispiel:
mysql>SET ONE_SHOT character_set_connection = latin5;
mysql>SET ONE_SHOT collation_connection = latin5_turkish_ci;
mysql>SHOW VARIABLES LIKE '%_connection';
+--------------------------+-------------------+ | Variable_name | Value | +--------------------------+-------------------+ | character_set_connection | latin5 | | collation_connection | latin5_turkish_ci | +--------------------------+-------------------+ mysql>SHOW VARIABLES LIKE '%_connection';
+--------------------------+-------------------+ | Variable_name | Value | +--------------------------+-------------------+ | character_set_connection | latin1 | | collation_connection | latin1_swedish_ci | +--------------------------+-------------------+
SQL_AUTO_IS_NULL = {0 | 1}
Bei der Einstellung 1 (Vorgabe) ermitteln Sie den zuletzt
eingefügten Datensatz für eine Tabelle, die eine
AUTO_INCREMENT
-Spalte umfasst, mithilfe
des folgenden Konstrukts:
WHERE auto_increment_column
IS NULL
Dieses Verhalten wird von einigen ODBC-Programmen wie etwa Access verwendet.
SQL_BIG_SELECTS = {0 | 1}
Bei der Einstellung 0 bricht MySQL
SELECT
-Anweisungen ab, deren Ausführung
voraussichtlich sehr lange dauern wird (d. h., Anweisungen,
bei denen der Optimierer eine Anzahl von untersuchten
Datensätzen annimmt, deren Wert
max_join_size
überschreitet. Dies ist
praktisch, wenn eine nicht empfehlenswerte
WHERE
-Anweisung abgesetzt wurde. Der
Standardwert für eine neue Verbindung ist 1, d. h., alle
SELECT
-Anweisungen sind zulässig.
Wenn Sie die Systemvariable max_join_size
auf einen anderen Wert als DEFAULT
setzen, wird SQL_BIG_SELECTS
auf 0
gesetzt.
SQL_BUFFER_RESULT = {0 | 1}
SQL_BUFFER_RESULT
bewirkt, dass
Ergebnisse aus SELECT
-Anweisungen in
Temporärtabellen abgelegt werden. Auf diese Weise kann
MySQL die Tabellensperren schnell wieder aufheben. Die
Option ist zudem in Fällen hilfreich, in denen die
Übermittlung der Ergebnisse an den Client sehr lange
dauert.
SQL_LOG_BIN = {0 | 1}
Bei der Einstellung 0 erfolgt für den Client keine
Aufzeichnung in das Binärlog. Der Client benötigt die
Berechtigung SUPER
, um diese Option
einzustellen.
SQL_LOG_OFF = {0 | 1}
Bei der Einstellung 1 erfolgt für den Client keine
Aufzeichnung in das Log für allgemeine Abfragen. Der Client
benötigt die Berechtigung SUPER
, um
diese Option einzustellen.
SQL_LOG_UPDATE = {0 | 1}
Diese Variable ist veraltet und wird auf
SQL_LOG_BIN
umgesetzt.
SQL_NOTES = {0 | 1}
Bei der Einstellung 1 (Standard) werden Warnungen auf
Note
-Ebene aufgezeichnet. Wird hingegen 0
gewählt, dann werden Note
-Warnungen
unterdrückt. mysqldump enthält eine
Ausgabe, die diese Variable auf 0 setzt, sodass ein Neuladen
der Dumpdatei keine Warnungen für Ereignisse erzeugt, die
die Integrität des Neuladevorgangs nicht beeinträchtigen.
SQL_QUOTE_SHOW_CREATE = {0 | 1}
Bei der Einstellung 1 setzt der Server Bezeichner für die
Anweisungen SHOW CREATE TABLE
und
SHOW CREATE DATABASE
in
Anführungszeichen. Bei 0 werden keine Anführungszeichen
gesetzt. Die Option ist standardmäßig aktiviert, damit die
Replikation auch bei Bezeichnern funktioniert, die
Anführungszeichen erfordern. Siehe auch
Abschnitt 13.5.4.6, „SHOW CREATE TABLE
“, und
Abschnitt 13.5.4.4, „SHOW CREATE DATABASE
“.
SQL_SAFE_UPDATES = {0 | 1}
Bei der Einstellung 1 bricht MySQL
UPDATE
- und
DELETE
-Anweisungen ab, die keinen
Schlüssel in der WHERE
-Klausel oder
einer LIMIT
-Klausel verwenden. Auf diese
Weise lassen sich UPDATE
- oder
DELETE
-Anweisungen abfangen, bei denen
Schlüssel nicht korrekt eingesetzt werden und die unter
Umständen eine große Zahl von Datensätzen ändern oder
löschen würden.
SQL_SELECT_LIMIT =
{
value
| DEFAULT}
Die maximale Anzahl von Datensätzen, die von
SELECT
-Anweisungen zurückgegeben werden
können. Der Standardwert bei einer neuen Verbindung lautet
„unbegrenzt“. Wenn Sie den Grenzwert geändert
haben, kann der Standardwert mit dem Wert
DEFAULT
für
SQL_SELECT_LIMIT
wiederhergestellt
werden.
Wenn eine SELECT
-Anweisung eine
LIMIT
-Klausel aufweist, hat diese
LIMIT
-Klausel Vorrang vor dem Wert von
SQL_SELECT_LIMIT
.
SQL_SELECT_LIMIT
gilt nicht für
SELECT
-Anweisungen, die in gespeicherten
Routinen ausgeführt werden. Ebenso wenig gelten sie für
SELECT
-Anweisungen, die keine
Ergebnismenge erzeugen, die an den Client zurückgegeben
wird. Hierzu gehören SELECT
-Anweisungen
in Unterabfragen, CREATE TABLE ... SELECT
und INSERT INTO ... SELECT
.
SQL_WARNINGS = {0 | 1}
Diese Variable steuert, ob
INSERT
-Anweisungen für einen Datensatz
einen Informations-String erzeugen, wenn Warnungen
auftreten. Die Standardeinstellung ist 0. Setzen Sie den
Wert auf 1, um einen Informations-String zu generieren.
TIMESTAMP =
{
timestamp_value
|
DEFAULT}
Stellt die Zeit für diesen Client ein. Auf deren Basis wird
der ursprüngliche Zeitstempel ermittelt, wenn Sie
Datensätze mit dem Binärlog wiederherstellen.
timestamp_value
sollte ein
Unix-Epochenzeitstempel und kein MySQL-Zeitstempel sein.
UNIQUE_CHECKS = {0 | 1}
Bei der Einstellung 1 (Standard) werden
Eindeutigkeitsprüfungen für Sekundärindizes in
InnoDB
-Tabellen durchgeführt. Wenn der
Wert 0 eingestellt wurde, werden keine
Eindeutigkeitsprüfungen für Indexeinträge durchgeführt,
die in den InnoDB
-Einfügepuffer
eingefügt wurden. Wenn Sie ganz sicher wissen, dass Ihre
Daten keine Verstöße gegen das Eindeutigkeitsgebot
enthalten, können Sie hier 0 wählen, um den Import großer
Tabellen in InnoDB
zu beschleunigen.
SHOW CHARACTER SET
SHOW COLLATION
SHOW COLUMNS
SHOW CREATE DATABASE
SHOW CREATE PROCEDURE
und SHOW CREATE
FUNCTION
SHOW CREATE TABLE
SHOW DATABASES
SHOW ENGINE
SHOW ENGINES
SHOW ERRORS
SHOW GRANTS
SHOW INDEX
SHOW INNODB STATUS
SHOW LOGS
SHOW OPEN TABLES
SHOW PLUGIN
SHOW PRIVILEGES
SHOW PROCEDURE STATUS
und SHOW FUNCTION
STATUS
SHOW PROCESSLIST
SHOW STATUS
SHOW TABLE STATUS
SHOW TABLES
SHOW TRIGGERS
SHOW VARIABLES
SHOW WARNINGS
Es gibt viele Formen von SHOW
, die
Informationen zu Datenbanken, Tabellen oder Spalten sowie
Statusangaben zum Server vermitteln. In diesem Abschnitt werden
die folgenden SHOW
-Anweisungen beschrieben:
SHOW [FULL] COLUMNS FROMtbl_name
[FROMdb_name
] [LIKE 'pattern
'] SHOW CREATE DATABASEdb_name
SHOW CREATE FUNCTIONfuncname
SHOW CREATE PROCEDUREprocname
SHOW CREATE TABLEtbl_name
SHOW DATABASES [LIKE 'pattern
'] SHOW ENGINEengine_name
{LOGS | STATUS } SHOW [STORAGE] ENGINES SHOW ERRORS [LIMIT [offset
,]row_count
] SHOW FUNCTION STATUS [LIKE 'pattern
'] SHOW GRANTS FORuser
SHOW INDEX FROMtbl_name
[FROMdb_name
] SHOW INNODB STATUS SHOW PROCEDURE STATUS [LIKE 'pattern
'] SHOW [BDB] LOGS SHOW PLUGIN SHOW PRIVILEGES SHOW [FULL] PROCESSLIST SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern
'] SHOW TABLE STATUS [FROMdb_name
] [LIKE 'pattern
'] SHOW [OPEN] TABLES [FROMdb_name
] [LIKE 'pattern
'] SHOW TRIGGERS SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern
'] SHOW WARNINGS [LIMIT [offset
,]row_count
]
Es gibt zusätzliche Formen der
SHOW
-Anweisung, die Informationen zu
Replikationsmaster- und -slave-Servern vermitteln (diese werden
in Abschnitt 13.6, „SQL-Befehle in Bezug auf Replikation“, beschrieben):
SHOW BINLOG EVENTS SHOW MASTER LOGS SHOW MASTER STATUS SHOW SLAVE HOSTS SHOW SLAVE STATUS
Wenn die Syntax für eine gegebene
SHOW
-Anweisung einen LIKE
'
-Teil enthält,
ist pattern
''
ein
String, der die SQL-Jokerzeichen
‘pattern
'%
’ und
‘_
’ enthalten kann. Dieses Muster
ist praktisch, um die Ausgabe der Anweisung auf passende Werte
zu beschränken.
Mehrere SHOW
-Anweisungen akzeptieren zudem
eine WHERE
-Klausel, die mehr Flexibilität
bei der Angabe der anzuzeigenden Datensätze bietet. Siehe auch
Abschnitt 22.22, „Erweiterungen der SHOW
-Anweisungen“.
SHOW CHARACTER SET [LIKE 'pattern
']
Die Anweisung SHOW CHARACTER SET
zeigt alle
verfügbaren Zeichensätze an. Sie nimmt eine optionale
LIKE
-Klausel entgegen, die angibt, auf
welche Zeichensatznamen zu prüfen ist. Zum Beispiel:
mysql> SHOW CHARACTER SET LIKE 'latin%';
+---------+-----------------------------+-------------------+--------+
| Charset | Description | Default collation | Maxlen |
+---------+-----------------------------+-------------------+--------+
| latin1 | cp1252 West European | latin1_swedish_ci | 1 |
| latin2 | ISO 8859-2 Central European | latin2_general_ci | 1 |
| latin5 | ISO 8859-9 Turkish | latin5_turkish_ci | 1 |
| latin7 | ISO 8859-13 Baltic | latin7_general_ci | 1 |
+---------+-----------------------------+-------------------+--------+
Die Spalte Maxlen
zeigt die maximale Anzahl
von Bytes an, die zur Speicherung eines Zeichens erforderlich
sind.
SHOW COLLATION [LIKE 'pattern
']
Die Ausgabe von SHOW COLLATION
enthält
alle verfügbaren Zeichensätze. Sie nimmt eine optionale
LIKE
-Klausel entgegen, bei der
pattern
angibt, auf welche
Sortierfolgennamen zu prüfen ist. Zum Beispiel:
mysql> SHOW COLLATION LIKE 'latin1%';
+-------------------+---------+----+---------+----------+---------+
| Collation | Charset | Id | Default | Compiled | Sortlen |
+-------------------+---------+----+---------+----------+---------+
| latin1_german1_ci | latin1 | 5 | | | 0 |
| latin1_swedish_ci | latin1 | 8 | Yes | Yes | 0 |
| latin1_danish_ci | latin1 | 15 | | | 0 |
| latin1_german2_ci | latin1 | 31 | | Yes | 2 |
| latin1_bin | latin1 | 47 | | Yes | 0 |
| latin1_general_ci | latin1 | 48 | | | 0 |
| latin1_general_cs | latin1 | 49 | | | 0 |
| latin1_spanish_ci | latin1 | 94 | | | 0 |
+-------------------+---------+----+---------+----------+---------+
Die Spalte Default
gibt ab, ob eine
Sortierfolge standardmäßig für den Zeichensatz verwendet
wird. Compiled
zeigt an, ob der Zeichensatz
in den Server einkompiliert ist. Sortlen
schließlich bezieht sich auf die Menge des Speichers, die zum
Sortieren der im Zeichensatz ausgedrückten Strings
erforderlich ist.
SHOW [FULL] COLUMNS FROMtbl_name
[FROMdb_name
] [LIKE 'pattern
']
SHOW COLUMNS
vermittelt Informationen zu
Spalten in einer Tabelle. Die Anweisung funktioniert auch bei
Views.
Das Schlüsselwort FULL
bewirkt, dass die
Ausgabe ihre Berechtigungen sowie alle spaltenspezifischen
Kommentare für jede Spalte enthält.
Sie können db_name.tbl_name
als
Alternative zur Syntax
verwenden. Die
beiden folgenden Anweisungen sind mithin äquivalent:
tbl_name
FROM
db_name
mysql>SHOW COLUMNS FROM mytable FROM mydb;
mysql>SHOW COLUMNS FROM mydb.mytable;
SHOW FIELDS
ist ein Synonym für
SHOW COLUMNS
. Sie können die Spalten einer
Tabelle auch mit dem Befehl mysqlshow
db_name
tbl_name
auflisten.
Die Anweisung DESCRIBE
ermittelt ähnliche
Informationen wie SHOW COLUMNS
. Siehe auch
Abschnitt 13.3.1, „DESCRIBE
(Informationen über Spalten abrufen)“.
SHOW CREATE {DATABASE | SCHEMA} db_name
Zeigt die CREATE DATABASE
-Anweisung an, mit
der die übergebene Datenbank erstellt wurde. SHOW
CREATE SCHEMA
ist ein Synonym zu SHOW
CREATE DATABASE
.
mysql>SHOW CREATE DATABASE test\G
*************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */ mysql>SHOW CREATE SCHEMA test\G
*************************** 1. row *************************** Database: test Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */
SHOW CREATE DATABASE
setzt Tabellen- und
Spaltennamen entsprechend dem Wert von
SQL_QUOTE_SHOW_CREATE
in
Anführungszeichen. Siehe auch Abschnitt 13.5.3, „SET
“.
SHOW CREATE {PROCEDURE | FUNCTION} sp_name
Diese Anweisung ist eine MySQL-Erweiterung. Analog zu
SHOW CREATE TABLE
gibt sie den exakten
String zurück, mit dem die genannte Routine neu erstellt
werden kann.
mysql> SHOW CREATE FUNCTION test.hello\G
*************************** 1. row ***************************
Function: hello
sql_mode:
Create Function: CREATE FUNCTION `test`.`hello`(s CHAR(20)) RETURNS CHAR(50)
RETURN CONCAT('Hello, ',s,'!')
SHOW CREATE TABLE tbl_name
Zeigt die CREATE TABLE
-Anweisung an, mit
der die übergebene Tabelle erstellt wurde. Diese Anweisung
funktioniert auch bei Views.
mysql> SHOW CREATE TABLE t\G
*************************** 1. row ***************************
Table: t
Create Table: CREATE TABLE t (
id INT(11) default NULL auto_increment,
s char(60) default NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM
SHOW CREATE TABLE
setzt Tabellen- und
Spaltennamen entsprechend dem Wert von
SQL_QUOTE_SHOW_CREATE
in
Anführungszeichen. Siehe auch Abschnitt 13.5.3, „SET
“.
SHOW {DATABASES | SCHEMAS} [LIKE 'pattern
']
SHOW DATABASES
listet die Datenbanken auf
dem MySQL Server-Host auf. Sofern Sie nicht über die
Berechtigung SHOW DATABASES
verfügen,
werden Ihnen nur diejenigen Datenbanken angezeigt, für die
Sie Berechtigungen haben. Sie können diese Liste auch mit
mysqlshow anzeigen.
Wurde der Server mit der Option
--skip-show-database
gestartet, dann können
Sie diese Anweisung ohne die Berechtigung SHOW
DATABASES
überhaupt nicht verwenden.
SHOW SCHEMAS
kann ebenfalls verwendet
werden.
SHOW ENGINE engine_name
{LOGS | STATUS }
SHOW ENGINE
zeigt Log- und
Statusinformationen zu Speicher-Engines an. Die folgenden
Anweisungen werden derzeit unterstützt:
SHOW ENGINE BDB LOGS SHOW ENGINE INNODB STATUS
SHOW ENGINE BDB LOGS
zeigt
Statusinformationen zu vorhandenen
BDB
-Logdateien an. Zurückgegeben werden
die folgenden Felder:
File
Der vollständige Pfad zur Logdatei.
Type
Der Logdateityp (BDB
bei Berkeley
DB-Logdateien).
Status
Der Status der Logdatei (FREE
, wenn die
Datei entfernt werden kann, oder IN
USE
, wenn die Datei vom Transaktionssubsystem
benötigt wird).
SHOW ENGINE INNODB STATUS
zeigt umfassende
Informationen zum Zustand der
InnoDB
-Speicher-Engine an.
Ältere (und mittlerweile nicht mehr verwendete) Synonyme für
diese Anweisungen sind SHOW [BDB] LOGS
und
SHOW INNODB STATUS
.
SHOW [STORAGE] ENGINES
SHOW ENGINES
zeigt Statusinformationen zu
den Speicher-Engines des Servers an. Dies ist besonders
nützlich, um zu überprüfen, ob eine Speicher-Engine
unterstützt wird, oder um festzustellen, welche Engine
standardmäßig benutzt wird. SHOW TABLE
TYPES
ist ein veraltetes Synonym.
mysql> SHOW ENGINES\G
*************************** 1. row ***************************
Engine: MEMORY
Support: YES
Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
XA: NO
Savepoints: NO
*************************** 2. row ***************************
Engine: MyISAM
Support: DEFAULT
Comment: Default engine as of MySQL 3.23 with great performance
Transactions: NO
XA: NO
Savepoints: NO
*************************** 3. row ***************************
Engine: InnoDB
Support: YES
Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
XA: YES
Savepoints: YES
*************************** 4. row ***************************
Engine: BerkeleyDB
Support: YES
Comment: Supports transactions and page-level locking
Transactions: YES
XA: NO
Savepoints: NO
*************************** 5. row ***************************
Engine: EXAMPLE
Support: YES
Comment: Example storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 6. row ***************************
Engine: ARCHIVE
Support: YES
Comment: Archive storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 7. row ***************************
Engine: CSV
Support: YES
Comment: CSV storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 8. row ***************************
Engine: BLACKHOLE
Support: YES
Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
XA: NO
Savepoints: NO
*************************** 9. row ***************************
Engine: FEDERATED
Support: YES
Comment: Federated MySQL storage engine
Transactions: NO
XA: NO
Savepoints: NO
*************************** 10. row ***************************
Engine: MRG_MYISAM
Support: YES
Comment: Collection of identical MyISAM tables
Transactions: NO
XA: NO
Savepoints: NO
Der Wert Support
gibt an, ob die
betreffende Speicher-Engine unterstützt wird und welches die
standardmäßig verwendete Engine ist. Wird der Server
beispielsweise mit der Option
--default-table-type=InnoDB
gestartet, dann
hat der Wert Support
für den Datensatz
InnoDB
den Wert DEFAULT
.
Siehe auch Kapitel 14, Speicher-Engines und Tabellentypen.
Die Spalten Transactions
,
XA
und Savepoints
wurden
in MySQL 5.1.2 hinzugefügt. Sie geben jeweils an, ob die
Speicher-Engine Transaktionen, XA-Transaktionen und/oder
Speicherpunkte unterstützt.
SHOW ERRORS [LIMIT [offset
,]row_count
] SHOW COUNT(*) ERRORS
Diese Anweisung ähnelt SHOW WARNINGS
; der
Unterschied besteht darin, dass statt Fehlern, Warnungen und
Hinweisen lediglich Fehler angezeigt werden.
Die LIMIT
-Klausel hat dieselbe Syntax wie
bei der SELECT
-Anweisung. Siehe auch
Abschnitt 13.2.7, „SELECT
“.
Die SHOW COUNT(*) ERRORS
-Anweisung zeigt
die Anzahl der Fehler an. Sie können diese Anzahl auch der
Variablen error_count
entnehmen:
SHOW COUNT(*) ERRORS; SELECT @@error_count;
Weitere Informationen finden Sie unter
Abschnitt 13.5.4.25, „SHOW WARNINGS
“.
SHOW GRANTS FOR user
Diese Anweisung listet die
GRANT
-Anweisung(en) auf, die abgesetzt
werden muss bzw. müssen, um die Berechtigungen zu kopieren,
die einem MySQL-Benutzerkonto zugewiesen sind. Das Konto wird
im selben Format wie bei der
GRANT
-Anweisung angegeben (z. B.
'jeffrey'@'localhost'
). Die Benutzer- und
Hostbestandteile des Kontonamens entsprechen den Werten der
Spalten User
und Host
des kontenspezifischen Datensatzes in der Tabelle
user
.
mysql> SHOW GRANTS FOR 'root'@'localhost';
+---------------------------------------------------------------------+
| Grants for root@localhost |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+
Um die Berechtigungen des Kontos aufzulisten, über das Sie mit dem Server verbunden sind, können Sie eine der folgenden Anweisungen verwenden:
SHOW GRANTS; SHOW GRANTS FOR CURRENT_USER; SHOW GRANTS FOR CURRENT_USER();
SHOW GRANTS
zeigt nur die Berechtigungen
an, die dem genannten Konto explizit zugewiesen sind. Das
Konto kann also über weitere Berechtigungen verfügen, die
nicht aufgelistet sind. Ist beispielsweise ein anonymes Konto
vorhanden, dann kann das genannte Konto dessen Berechtigungen
unter Umständen nutzen; dies wird aber von SHOW
GRANTS
nicht angezeigt.
SHOW INDEX FROMtbl_name
[FROMdb_name
]
SHOW INDEX
gibt Informationen zum
Tabellenindex zurück. Das Format erinnert an das des Aufrufs
SQLStatistics
in ODBC.
SHOW INDEX
gibt die folgenden Felder
zurück:
Table
Der Name der Tabelle.
Non_unique
0, wenn der Index keine Dubletten enthalten darf, andernfalls 1.
Key_name
Der Name des Indexes.
Seq_in_index
Die Sequenznummer der Spalte im Index, beginnend bei 1.
Column_name
Der Spaltenname.
Gibt an, wie die Spalte im Index sortiert ist. In MySQL
können die Werte ‘A
’
(aufsteigend) oder NULL
(nicht
sortiert) auftreten.
Schätzung der Anzahl eindeutiger Werte im Index.
Aktualisiert wird der Wert durch Ausführung von
ANALYZE TABLE
oder myisamchk
-a. Cardinality
wird
basierend auf Statistiken gezählt, die als Integers
gespeichert werden, d. h., der Wert ist auch bei kleinen
Tabellen unter Umständen nicht exakt. Je höher die
Kardinalität, desto größer ist die Chance, dass MySQL
den Index bei der Durchführung von Joins verwendet.
Sub_part
Die Anzahl der indizierten Zeichen, wenn die Spalte nur
teilweise indiziert ist, oder NULL
,
wenn die gesamte Spalte indiziert ist.
Packed
Gibt an, wie der Schlüssel gepackt ist.
NULL
zeigt an, dass der Schlüssel
nicht gepackt ist.
Null
Enthält YES
, wenn die Spalte
NULL
sein kann. Andernfalls enthält
die Spalte NO
.
Index_type
Der verwendete Indextyp (BTREE
,
FULLTEXT
, HASH
,
RTREE
).
Comment
Verschiedene Anmerkungen.
Sie können
db_name
.tbl_name
als Alternative zur Syntax
verwenden. Die
folgenden beiden Anweisungen sind äquivalent:
tbl_name
FROM
db_name
SHOW INDEX FROM mytable FROM mydb; SHOW INDEX FROM mydb.mytable;
SHOW KEYS
ist ein Synonym für
SHOW INDEX
. Sie können die Indizes einer
Tabelle auch mit dem Befehl mysqlshow -k
db_name
tbl_name
auflisten.
SHOW INNODB STATUS
In MySQL 5.1 ist dies ein veraltetes Synonym für
SHOW ENGINE INNODB STATUS
. Siehe auch
Abschnitt 13.5.4.8, „SHOW ENGINE
“.
SHOW [BDB] LOGS
In MySQL 5.1 ist dies ein veraltetes Synonym für
SHOW ENGINE BDB LOGS
. Siehe auch
Abschnitt 13.5.4.8, „SHOW ENGINE
“.
SHOW OPEN TABLES [FROMdb_name
] [LIKE 'pattern
']
SHOW OPEN TABLES
listet die
nichttemporären Tabellen auf, die derzeit im Tabellen-Cache
geöffnet sind. Siehe auch Abschnitt 7.4.8, „Nachteile der Erzeugung großer Mengen von Tabellen in derselben
Datenbank“.
SHOW OPEN TABLES
gibt die folgenden Felder
zurück:
Database
Die Datenbank, die die Tabelle enthält.
Table
Der Tabellenname.
In_use
Häufigkeit, mit der die Tabelle zurzeit von Abfragen verwendet wird. Wenn der Wert null ist, dann ist die Tabelle geöffnet, wird aber derzeit nicht verwendet.
Name_locked
Gibt an, ob der Tabellenname gesperrt ist. Die Namenssperrung wird bei Operationen wie dem Löschen oder Umbenennen von Tabellen verwendet.
SHOW PLUGIN
SHOW PLUGIN
zeigt Informationen zu
bekannten Plug-Ins an.
mysql> SHOW PLUGIN;
+------------+--------+----------------+---------+
| Name | Status | Type | Library |
+------------+--------+----------------+---------+
| MEMORY | ACTIVE | STORAGE ENGINE | NULL |
| MyISAM | ACTIVE | STORAGE ENGINE | NULL |
| InnoDB | ACTIVE | STORAGE ENGINE | NULL |
| ARCHIVE | ACTIVE | STORAGE ENGINE | NULL |
| CSV | ACTIVE | STORAGE ENGINE | NULL |
| BLACKHOLE | ACTIVE | STORAGE ENGINE | NULL |
| FEDERATED | ACTIVE | STORAGE ENGINE | NULL |
| MRG_MYISAM | ACTIVE | STORAGE ENGINE | NULL |
+------------+--------+----------------+---------+
SHOW PLUGIN
wurde in MySQL 5.1.5
hinzugefügt.
SHOW PRIVILEGES
SHOW PRIVILEGES
zeigt eine Liste mit
Systemberechtigungen an, die der MySQL Server unterstützt.
Wie diese Liste genau aussieht, hängt von der Version Ihres
Servers ab.
mysql> SHOW PRIVILEGES\G
*************************** 1. row ***************************
Privilege: Alter
Context: Tables
Comment: To alter the table
*************************** 2. row ***************************
Privilege: Alter routine
Context: Functions,Procedures
Comment: To alter or drop stored functions/procedures
*************************** 3. row ***************************
Privilege: Create
Context: Databases,Tables,Indexes
Comment: To create new databases and tables
*************************** 4. row ***************************
Privilege: Create routine
Context: Functions,Procedures
Comment: To use CREATE FUNCTION/PROCEDURE
*************************** 5. row ***************************
Privilege: Create temporary tables
Context: Databases
Comment: To use CREATE TEMPORARY TABLE
...
SHOW {PROCEDURE | FUNCTION} STATUS [LIKE 'pattern
']
Diese Anweisung ist eine MySQL-Erweiterung. Sie gibt Eigenschaften von Routinen zurück, z. B. Datenbank, Name, Typ und Ersteller sowie Erstellungs- und Änderungsdatum. Wird kein Muster angegeben, dann werden abhängig von der verwendeten Anweisung Informationen zu allen gespeicherten Prozeduren oder allen gespeicherten Funktionen aufgelistet.
mysql> SHOW FUNCTION STATUS LIKE 'hello'\G
*************************** 1. row ***************************
Db: test
Name: hello
Type: FUNCTION
Definer: testuser@localhost
Modified: 2004-08-03 15:29:37
Created: 2004-08-03 15:29:37
Security_type: DEFINER
Comment:
Sie können Informationen zu gespeicherten Routinen auch der
Tabelle ROUTINES
in
INFORMATION_SCHEMA
entnehmen. Siehe auch
Abschnitt 22.14, „Die Tabelle INFORMATION_SCHEMA ROUTINES
“.
SHOW [FULL] PROCESSLIST
SHOW PROCESSLIST
zeigt Ihnen, welche
Threads gerade ausgeführt werden. Sie können diese
Information auch mit mysqladmin processlist
anzeigen. Wenn Sie die Berechtigung SUPER
haben, werden alle Threads angezeigt. Andernfalls werden nur
Ihre eigenen Threads (d. h. Threads, die mit dem
MySQL-Benutzerkonto verknüpft sind, das Sie verwenden)
angezeigt. Siehe auch Abschnitt 13.5.5.3, „KILL
“. Wenn Sie das
Schlüsselwort FULL
nicht angeben, werden
nur die ersten hundert Zeichen jeder Anweisung im Feld
Info
angezeigt.
Diese Anweisung ist recht praktisch, wenn Sie die
Fehlermeldung „Too many connections“ erhalten und
herausfinden wollen, was gerade passiert. MySQL reserviert
eine zusätzliche Verbindung für Konten, die die Berechtigung
SUPER
haben, damit gewährleistet ist, dass
Administratoren jederzeit Verbindungen herstellen können, um
das System zu überprüfen. (Dies setzt natürlich voraus,
dass Sie diese Berechtigung nicht allen Benutzern gewähren.)
Die Ausgabe von SHOW PROCESSLIST
kann etwa
so aussehen:
mysql> SHOW FULL PROCESSLIST\G *************************** 1. row *************************** Id: 1 User: system user Host: db: NULL Command: Connect Time: 1030455 State: Waiting for master to send event Info: NULL *************************** 2. row *************************** Id: 2 User: system user Host: db: NULL Command: Connect Time: 1004 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL *************************** 3. row *************************** Id: 3112 User: replikator Host: artemis:2204 db: NULL Command: Binlog Dump Time: 2144 State: Has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 4. row *************************** Id: 3113 User: replikator Host: iconnect2:45781 db: NULL Command: Binlog Dump Time: 2086 State: Has sent all binlog to slave; waiting for binlog to be updated Info: NULL *************************** 5. row *************************** Id: 3123 User: stefan Host: localhost db: apollon Command: Query Time: 0 State: NULL Info: SHOW FULL PROCESSLIST 5 rows in set (0.00 sec)
Die Spalten haben die nachfolgend beschriebenen Bedeutungen:
Id
Der Verbindungsbezeichner.
User
Der MySQL-Benutzer, der die Anweisung abgesetzt hat. Die
Anzeige system user
bezeichnet einen
clientlosen Thread, den der Server erzeugt hat, um Tasks
intern zu verwalten. Es kann sich dabei um den I/O- oder
den SQL-Thread, der auf dem Replikationsserver verwendet
wird, oder einen Handler für verzögerte Datensätze
handeln. Für den system user
ist in
der Spalte Host
kein Host angegeben.
Host
Der Hostname des Clients, der die Anweisung absetzt
(außer bei system user
, wo kein Host
angegeben wird).
SHOW PROCESSLIST
meldet den Hostnamen
für TCP/IP-Verbindungen im Format
,
damit Sie schneller feststellen können, welcher Client
was tut.
host_name
:client_port
db
Die Standarddatenbank, sofern eine solche ausgewählt
wurde; andernfalls NULL
.
Command
Der Wert dieser Spalte entspricht den
COM_
-Befehlen
des Client/Server-Protokolls. Siehe auch
Abschnitt 5.2.4, „Server-Statusvariablen“.
xxx
Der Wert Command
kann einen der
folgenden Werte haben: Binlog Dump
,
Change user
, Close
stmt
, Connect
,
Connect Out
, Create
DB
, Debug
, Delayed
insert
, Drop DB
,
Error
, Execute
,
Fetch
, Field List
,
Init DB
, Kill
,
Long Data
, Ping
,
Prepare
,
Processlist
, Query
,
Quit
, Refresh
,
Register Slave
, Reset
stmt
, Set option
,
Shutdown
, Sleep
,
Statistics
, Table
Dump
, Time
Time
Die Zeit (in Sekunden), die seit dem Start der Anweisung oder des Befehls bis jetzt vergangen ist.
State
Eine Aktion, ein Ereignis oder ein Zustand. Folgende Werte
sind möglich: After create
,
Analyzing
, Changing
master
, Checking master
version
, Checking table
,
Connecting to master
, Copying
to group table
, Copying to tmp
table
, Creating delayed
handler
, Creating index
,
Creating sort index
, Creating
table from master dump
, Creating tmp
table
, Execution of
init_command
, FULLTEXT
initialization
, Finished reading one
binlog; switching to next binlog
,
Flushing tables
,
Killed
, Killing
slave
, Locked
,
Making temp file
, Opening
master dump table
, Opening
table
, Opening tables
,
Processing request
, Purging
old relay logs
, Queueing master event
to the relay log
, Reading event from
the relay log
, Reading from
net
, Reading master dump table
data
, Rebuilding the index on master
dump table
, Reconnecting after a failed
binlog dump request
, Reconnecting after
a failed master event read
, Registering
slave on master
, Removing
duplicates
, Reopen tables
,
Repair by sorting
, Repair
done
, Repair with keycache
,
Requesting binlog dump
,
Rolling back
, Saving
state
, Searching rows for
update
, Sending binlog event to
slave
, Sending data
,
Sorting for group
, Sorting for
order
, Sorting index
,
Sorting result
, System
lock
, Table lock
,
Thread initialized
,
Updating
, User lock
,
Waiting for INSERT
, Waiting
for master to send event
, Waiting for
master update
, Waiting for slave mutex
on exit
, Waiting for table
,
Waiting for tables
, Waiting
for the next event in relay log
,
Waiting on cond
, Waiting to
finalize termination
, Waiting to
reconnect after a failed binlog dump request
,
Waiting to reconnect after a failed master event
read
, Writing to net
,
allocating local table
,
cleaning up
, closing
tables
, converting HEAP to
MyISAM
, copy to tmp table
,
creating table
, deleting from
main table
, deleting from reference
tables
,
discard_or_import_tablespace
,
end
, freeing items
,
got handler lock
, got old
table
, info
,
init
, insert
,
logging slow query
,
login
, preparing
,
purging old relay logs
, query
end
, removing tmp table
,
rename
, rename result
table
, reschedule
,
setup
, starting
slave
, statistics
,
storing row into queue
,
update
, updating
,
updating main table
, updating
reference tables
, upgrading
lock
, waiting for delay_list
,
waiting for handler insert
,
waiting for handler lock
,
waiting for handler open
Die gängigsten State
-Werte werden im
Folgenden beschrieben. Die Mehrzahl der anderen
State
-Werte sind in erster Linie
praktisch, um Bugs im Server zu finden. Weitere
Informationen zu Prozesszuständen bei Replikationsservern
finden Sie in
Abschnitt 6.4, „Replikation: Implementationsdetails“.
Für die SHOW PROCESSLIST
-Anweisung ist
der State
-Wert NULL
.
Info
Die Anweisung, die der Thread ausführt, oder
NULL
, sofern er keine Anweisung
ausführt.
Einige State
-Werte finden Sie in der
Ausgabe von SHOW PROCESSLIST
recht häufig:
Checking table
Der Thread führt eine Tabellenprüfung durch.
Closing tables
Der Thread synchronisiert die geänderten Tabellendaten auf die Festplatte und schließt die verwendeten Tabellen. Dies sollte ein sehr schneller Vorgang sein. Andernfalls sollten Sie überprüfen, ob Ihre Festplatte nicht voll ist oder stark frequentiert wird.
Connect Out
Ein Replikationsslave stellt eine Verbindung zum Master her.
Copying to tmp table
Der Server kopiert Daten in eine Temporärtabelle im Speicher.
Copying to tmp table on disk
Der Server kopiert Daten in eine Temporärtabelle auf die
Festplatte. Die temporäre Ergebnismenge war größer als
tmp_table_size
, und der Thread stellt
die Temporärtabelle deswegen vom speicherresidenten in
das festplattenbasierte Format um, um Speicher zu sparen.
Creating tmp table
Der Thread erstellt eine Temporärtabelle, die einen Teil des Abfrageergebnisses aufnehmen soll.
deleting from main table
Der Server führt den ersten Teil eines Löschvorgangs über mehrere Tabellen aus. Der Löschvorgang erfolgt nur in der ersten Tabelle und speichert Felder und Offsets, die zum Löschen aus anderen (Referenz-)Tabellen benutzt werden.
deleting from reference tables
Der Server führt den zweiten Teil eines Löschvorgangs über mehrere Tabellen aus und löscht die entsprechenden Datensätze aus anderen Tabellen.
Flushing tables
Der Thread führt FLUSH TABLES
aus und
wartet, bis alle Threads ihre Tabellen geschlossen haben.
FULLTEXT initialization
Der Server bereitet die Ausführung einer natursprachlichen Volltextsuche vor.
Killed
Jemand hat eine KILL
-Anweisung an den
Thread abgesetzt. Der Thread wird abgebrochen, wenn beim
nächsten Mal das Terminierungs-Flag gesetzt wird. Dieses
Flag wird in jeder größeren Schleife in MySQL gesetzt.
Trotzdem kann es unter Umständen einen Moment dauern, bis
der Thread terminiert ist. Ist der Thread durch einen
anderen Thread gesperrt, dann erfolgt die Terminierung
erst, wenn der andere Thread die Sperre aufgehoben hat.
Locked
Die Abfrage wird durch eine andere Abfrage gesperrt.
Sending data
Der Thread verarbeitet Datensätze für eine
SELECT
-Anweisung und sendet zudem Daten
an den Client.
Sorting for group
Der Thread führt eine Sortierung infolge einer
GROUP BY
-Klausel durch.
Sorting for order
Der Thread führt eine Sortierung infolge einer
ORDER BY
-Klausel durch.
Opening tables
Der Thread versucht, eine Tabelle zu öffnen. Dies sollte
ein sehr schneller Vorgang sein, sofern das Öffnen nicht
durch irgendeinen Umstand verhindert wird. So kann
beispielsweise eine ALTER TABLE
- oder
eine LOCK TABLE
-Anweisung das Öffnen
einer Tabelle bis zum Abschluss der Anweisung unterbinden.
Reading from net
Der Server liest ein Paket aus dem Netzwerk.
Removing duplicates
Die Abfrage verwendete SELECT DISTINCT
so, dass MySQL die DISTINCT
-Operation
nicht zu einem frühen Zeitpunkt wegoptimieren konnte. Aus
diesem Grund erfordert MySQL eine zusätzliche Phase, um
alle duplizierten Datensätze zu entfernen, bevor das
Ergebnis an den Client gesendet wird.
Reopen table
Der Thread hat eine Sperre für die Tabelle erwirkt, danach aber festgestellt, dass die zugrunde liegende Tabellenstruktur sich geändert hat. Der Thread hat die Sperre dann aufgehoben und die Tabelle geschlossen und versucht nun, sie wieder zu öffnen.
Repair by sorting
Der Reparaturcode verwendet einen Sortiervorgang zur Erstellung der Indizes.
Repair with keycache
Der Reparaturcode erstellt einen Schlüssel nach dem
anderen über den Schlüssel-Cache. Dies ist wesentlich
langsamer als Repair by sorting
.
Searching rows for update
Der Thread durchläuft die erste Phase zur Suche nach
passenden Datensätzen, bevor er sie aktualisiert. Dies
muss getan werden, wenn UPDATE
den
Index ändert, der für die Suche nach den betreffenden
Datensätzen verwendet wird.
Sleeping
Der Thread wartet darauf, dass der Client eine neue Anweisung an ihn sendet.
statistics
Der Server berechnet Statistiken zur Entwicklung eines Abfrageausführungsplans.
Der Thread wartet darauf, eine externe Systemsperre für
die Tabelle zu erhalten. Wenn Sie nicht mehrere
mysqld-Server verwenden, die auf die
gleichen Tabellen zugreifen, können Sie Systemsperren mit
der Option --skip-external-locking
deaktivieren.
Upgrading lock
Der Handler INSERT DELAYED
versucht,
eine Sperre für die Tabelle zu erwirken, um Datensätze
einzufügen.
Updating
Der Thread sucht nach zu aktualisierenden Datensätzen und aktualisiert diese dann.
updating main table
Der Server führt den ersten Teil eines Änderungsvorgangs über mehrere Tabellen aus. Er führt Änderungen nur in der ersten Tabelle aus und speichert Felder und Offsets, die zur Aktualisierung anderer (Referenz-)Tabellen benutzt werden.
updating reference tables
Der Server führt den zweiten Teil eines Änderungsvorgangs über mehrere Tabellen aus und aktualisiert die entsprechenden Datensätze in den anderen Tabellen.
User Lock
Der Thread wartet auf ein GET_LOCK()
.
Waiting for tables
Der Thread hat eine Mitteilung erhalten, dass die einer Tabelle zugrunde liegende Struktur sich geändert hat und er die Tabelle neu öffnen muss, um die neue Struktur zu erhalten. Um die Tabelle allerdings neu öffnen zu können, muss er warten, bis alle anderen Threads die fragliche Tabelle geschlossen haben.
Diese Benachrichtigung erfolgt, wenn ein anderer Thread
FLUSH TABLES
oder eine der folgenden
Anweisungen für die betreffende Tabelle verwendet hat:
FLUSH TABLES
,
tbl_name
ALTER TABLE
, RENAME
TABLE
, REPAIR TABLE
,
ANALYZE TABLE
oder OPTIMIZE
TABLE
.
waiting for handler insert
Der INSERT DELAYED
-Handler hat alle
anhängigen Einfügeoperationen verarbeitet und wartet auf
neue.
Writing to net
Der Server schreibt ein Paket in das Netzwerk.
Die meisten Zustände entsprechen sehr schnellen Operationen. Wenn ein Thread für mehrere Sekunden in einem dieser Zustände verbleibt, dann weist dies auf ein Problem hin, das untersucht werden muss.
SHOW [GLOBAL | SESSION] STATUS [LIKE 'pattern
']
SHOW STATUS
zeigt Serverstatusinformationen
an. Diese Informationen können auch mit dem Befehl
mysqladmin extended-status ermittelt
werden.
Nachfolgend ist auszugsweise eine Ausgabe aufgelistet. Die Liste der Variablen und ihrer Werte kann auf Ihrem Server anders aussehen. Die Bedeutung der Variablen ist in Abschnitt 5.2.4, „Server-Statusvariablen“, beschrieben.
mysql> SHOW STATUS;
+--------------------------+------------+
| Variable_name | Value |
+--------------------------+------------+
| Aborted_clients | 0 |
| Aborted_connects | 0 |
| Bytes_received | 155372598 |
| Bytes_sent | 1176560426 |
| Connections | 30023 |
| Created_tmp_disk_tables | 0 |
| Created_tmp_tables | 8340 |
| Created_tmp_files | 60 |
...
| Open_tables | 1 |
| Open_files | 2 |
| Open_streams | 0 |
| Opened_tables | 44600 |
| Questions | 2026873 |
...
| Table_locks_immediate | 1920382 |
| Table_locks_waited | 0 |
| Threads_cached | 0 |
| Threads_created | 30022 |
| Threads_connected | 1 |
| Threads_running | 1 |
| Uptime | 80380 |
+--------------------------+------------+
Mit einer LIKE
-Klausel zeigt die Anweisung
nur die Variablen an, die dem Muster entsprechen:
mysql> SHOW STATUS LIKE 'Key%';
+--------------------+----------+
| Variable_name | Value |
+--------------------+----------+
| Key_blocks_used | 14955 |
| Key_read_requests | 96854827 |
| Key_reads | 162040 |
| Key_write_requests | 7589728 |
| Key_writes | 3813196 |
+--------------------+----------+
Wenn die Option GLOBAL
angegeben wird,
erhalten Sie die Statuswerte für alle Verbindungen zu MySQL.
Bei SESSION
erhalten Sie hingegen die
Statuswerte der aktuellen Verbindung. Geben Sie überhaupt
keine Option an, dann wird SESSION
als
Vorgabe verwendet. LOCAL
ist ein Synonym
für SESSION
.
Einige Statusvariablen haben nur einen globalen Wert. Bei
diesen erhalten Sie denselben Wert sowohl für
GLOBAL
als auch für
SESSION
.
SHOW TABLE STATUS [FROMdb_name
] [LIKE 'pattern
']
SHOW TABLE STATUS
funktioniert wie
SHOW TABLE
, vermittelt aber zahlreiche
Informationen zu den einzelnen Tabellen. Sie können diese
Liste auch mit mysqlshow --status
db_name
anzeigen.
Diese Anweisung erlaubt auch die Anzeige von Informationen zu Views.
SHOW TABLE STATUS
gibt die folgenden Felder
zurück:
Name
Den Namen der Tabelle.
Engine
Die Speicher-Engine der Tabelle. Siehe auch
Kapitel 14, Speicher-Engines und Tabellentypen. Vor MySQL 4.1.2 hieß
dieser Wert Type
.
Version
Die Versionsnummer der .frm
-Datei der
Tabelle.
Row_format
Das Format für die Datensatzspeicherung
(Fixed
, Dynamic
,
Compressed
,
Redundant
, Compact
).
Das Format von InnoDB
-Tabellen wird als
Redundant
oder
Compact
gemeldet.
Rows
Anzahl der Datensätze. Einige Speicher-Engines wie etwa
MyISAM
speichern die exakte Anzahl.
Bei anderen Engines wie InnoDB
hingegen
ist dies ein Schätzwert, der vom tatsächlichen Wert um
bis zu 40 oder 50 Prozent abweichen kann. In solchen
Fällen sollten Sie mit SELECT COUNT(*)
eine exakte Anzahl ermitteln.
Der Rows
-Wert ist
NULL
bei Tabellen in der Datenbank
INFORMATION_SCHEMA
.
Avg_row_length
Durchschnittliche Länge eines Datensatzes.
Data_length
Die Länge der Datendatei.
Max_data_length
Die maximale Länge der Datendatei. Dies ist die Gesamtzahl der Bytes, die in der Tabelle gespeichert werden können. Sie wird auf der Basis der verwendeten Zeigergröße berechnet.
Index_length
Die Länge der Indexdatei.
Data_free
Anzahl der reservierten, aber nicht verwendeten Bytes.
Auto_increment
Der nächste AUTO_INCREMENT
-Wert.
Create_time
Zeitpunkt der Tabellenerstellung.
Update_time
Zeitpunkt der letzten Aktualisierung der Datendatei.
Check_time
Zeitpunkt der letzten Tabellenüberprüfung. Nicht alle
Speicher-Engines aktualisieren diese Zeitangabe (in
solchen Fällen ist der Wert stets
NULL
).
Collation
Zeichensatz und Sortierung der Tabelle.
Checksum
Wert der mitlaufenden Prüfsumme (sofern vorhanden).
Create_options
Zusätzliche Optionen, die bei CREATE
TABLE
angegeben wurden.
Comment
Bei der Erstellung der Tabelle angegebener Kommentar (oder Angaben dazu, warum MySQL nicht auf die Tabellendaten zugreifen konnte).
Im Tabellenkommentar meldet InnoDB
den
freien Speicher des Tablespaces, zu dem die Tabelle gehört.
Bei einer Tabelle, die sich in einem gemeinsamen Tablespace
befindet, ist dies der freie Speicher des gemeinsamen
Tablespaces. Verwenden Sie mehrere Tablespaces und hat die
Tabelle einen eigenen Tablespace, dann bezieht sich die Angabe
des freien Speichers nur auf diese Tabelle.
Bei MEMORY
-Tabellen geben die Werte
Data_length
,
Max_data_length
und
Index_length
näherungsweise die
tatsächliche Menge des reservierten Speichers an. Der
Reservierungsalgorithmus reserviert in großem Umfang
Speicher, um die Anzahl der Reservierungsoperationen zu
verringern.
Bei NDB Cluster
-Tabellen zeigt die Ausgabe
dieser Anweisung annähernde Werte für die Spalten
Avg_row_length
und
Data_length
. Ausgenommen sind lediglich
BLOB
-Spalten, die nicht berücksichtigt
werden. Außerdem wird die Anzahl der Repliken in der
Comment
-Spalte (als
number_of_replicas
) angegeben.
Bei Views sind alle von SHOW TABLE STATUS
angezeigten Felder NULL
; lediglich
Name
zeigt den Namen des Views an, und
Comment
enthält view
.
SHOW [FULL] TABLES [FROMdb_name
] [LIKE 'pattern
']
SHOW TABLES
listet alle nichttemporären
Tabellen in einer gegebenen Datenbank auf. Sie können diese
Liste auch mit mysqlshow
db_name
anzeigen.
Die Anweisung listet außerdem alle Views in der Datenbank
auf. Der Modifizierer FULL
wird dahingehend
unterstützt, dass SHOW FULL TABLES
eine
zweite Ausgabespalte anzeigt. Werte der zweiten Spalte sind
BASE TABLE
bei einer Tabelle und
VIEW
bei einem View.
Hinweis: Wenn Sie keine
Berechtigungen für eine Tabelle haben, dann erscheint diese
nicht in der Ausgabe von SHOW TABLES
oder
mysqlshow db_name.
SHOW TRIGGERS [FROMdb_name
] [LIKEexpr
]
SHOW TRIGGERS
listet die derzeit auf dem
MySQL Server definierten Trigger auf. Diese Anweisung
erfordert die Berechtigung SUPER
.
Für den Trigger ins_sum
, wie er in
Abschnitt 20.3, „Verwendung von Triggern“, definiert ist, sieht die
Ausgabe der Anweisung wie folgt aus:
mysql> SHOW TRIGGERS LIKE 'acc%'\G
*************************** 1. row ***************************
Trigger: ins_sum
Event: INSERT
Table: account
Statement: SET @sum = @sum + NEW.amount
Timing: BEFORE
Created: NULL
sql_mode:
Definer: myname@localhost
Hinweis: Wenn Sie eine
LIKE
-Klausel mit SHOW
TRIGGERS
verwenden, wird der zu prüfende Ausdruck
expr
mit dem Namen der Tabelle
verglichen, für die der Trigger deklariert wurde, und nicht
mit dem Namen des Triggers:
mysql> SHOW TRIGGERS LIKE 'ins%';
Empty set (0.01 sec)
Es folgt eine kurze Erläuterung der Spalten in der Ausgabe der Anweisung:
Trigger
Der Name des Triggers.
Event
Das Ereignis, welches die Trigger-Aktivierung ausgelöst
hat: 'INSERT'
,
'UPDATE'
oder
'DELETE'
.
Table
Die Tabelle, für die der Trigger definiert ist.
Statement
Die bei Aktivierung des Triggers auszuführende Anweisung.
Diese entspricht dem Text in der Spalte
ACTION_STATEMENT
von
INFORMATION_SCHEMA.TRIGGERS
.
Timing
Einer der beiden Werte 'BEFORE'
oder
'AFTER'
.
Created
Der Wert dieser Spalte ist zurzeit immer
NULL
.
sql_mode
Der bei der Ausführung des Triggers gültige SQL-Modus.
Definer
Das Konto, welches den Trigger erstellt hat.
Siehe auch Abschnitt 22.16, „Die Tabelle INFORMATION_SCHEMA TRIGGERS
“.
SHOW [GLOBAL | SESSION] VARIABLES [LIKE 'pattern
']
SHOW VARIABLES
zeigt den Wert einiger
MySQL-Systemvariablen. Diese Informationen können auch mit
dem Befehl mysqladmin variables ermittelt
werden.
Mit der Option GLOBAL
erhalten Sie die
Werte, die für neue Verbindungen mit MySQL verwendet werden.
Mit SESSION
erhalten Sie hingegen die für
die aktuelle Verbindung gültigen Werte. Geben Sie überhaupt
keine Option an, dann wird SESSION
als
Vorgabe verwendet. LOCAL
ist ein Synonym
für SESSION
.
Sind die Standardwerte ungeeignet, dann können Sie die
meisten dieser Variablen beim Start von
mysqld mit Befehlsoptionen oder zur
Laufzeit mit der SET
-Anweisung einstellen.
Siehe auch Abschnitt 5.2.1, „Befehlsoptionen für mysqld“, und
Abschnitt 13.5.3, „SET
“.
Nachfolgend ist auszugsweise eine Ausgabe aufgelistet. Die Liste der Variablen und ihrer Werte kann auf Ihrem Server anders aussehen. Abschnitt 5.2.2, „Server-Systemvariablen“, beschreibt die Bedeutung der einzelnen Variablen. Informationen zu ihrer Optimierung finden Sie in Abschnitt 7.5.2, „Serverparameter feineinstellen“.
mysql> SHOW VARIABLES;
+---------------------------------+---------------------------+
| Variable_name | Value |
+---------------------------------+---------------------------+
| auto_increment_increment | 1 |
| auto_increment_offset | 1 |
| automatic_sp_privileges | ON |
| back_log | 50 |
| basedir | /home/jon/bin/mysql-5.1/ |
| binlog_cache_size | 32768 |
| bulk_insert_buffer_size | 8388608 |
| character_set_client | latin1 |
| character_set_connection | latin1 |
...
| max_user_connections | 0 |
| max_write_lock_count | 4294967295 |
| multi_range_count | 256 |
| myisam_data_pointer_size | 6 |
| myisam_max_sort_file_size | 2147483647 |
| myisam_recover_options | OFF |
| myisam_repair_threads | 1 |
| myisam_sort_buffer_size | 8388608 |
| ndb_autoincrement_prefetch_sz | 32 |
| ndb_cache_check_time | 0 |
| ndb_force_send | ON |
...
| time_zone | SYSTEM |
| timed_mutexes | OFF |
| tmp_table_size | 33554432 |
| tmpdir | |
| transaction_alloc_block_size | 8192 |
| transaction_prealloc_size | 4096 |
| tx_isolation | REPEATABLE-READ |
| updatable_views_with_limit | YES |
| version | 5.1.6-alpha-log |
| version_comment | Source distribution |
| version_compile_machine | i686 |
| version_compile_os | suse-linux |
| wait_timeout | 28800 |
+---------------------------------+---------------------------+
Mit einer LIKE
-Klausel zeigt die Anweisung
nur die Variablen an, die dem Muster entsprechen:
mysql> SHOW VARIABLES LIKE 'have%';
+-----------------------+----------+
| Variable_name | Value |
+-----------------------+----------+
| have_archive | YES |
| have_bdb | NO |
| have_blackhole_engine | YES |
| have_compress | YES |
| have_crypt | YES |
| have_csv | YES |
| have_example_engine | NO |
| have_federated_engine | NO |
| have_geometry | YES |
| have_innodb | YES |
| have_isam | NO |
| have_ndbcluster | DISABLED |
| have_openssl | NO |
| have_partitioning | YES |
| have_query_cache | YES |
| have_raid | NO |
| have_rtree_keys | YES |
| have_symlink | YES |
+-----------------------+----------+
SHOW WARNINGS [LIMIT [offset
,]row_count
] SHOW COUNT(*) WARNINGS
SHOW WARNINGS
zeigt die Fehler-, Warnungs-
und Hinweismeldungen, die durch die zuletzt abgesetzte
Anweisung ausgegeben wurden. Hat diese Anweisung keine
Meldungen erzeugt, so ist die Ausgabe leer. Die verwandte
Anweisung SHOW ERRORS
zeigt nur die Fehler
an. Siehe auch Abschnitt 13.5.4.10, „SHOW ERRORS
“.
Die Liste der Meldungen wird bei jeder neuen Anweisung, die eine Tabelle verwendet, zurückgesetzt.
Die SHOW COUNT(*) WARNINGS
-Anweisung zeigt
die Gesamtanzahl der Fehler, Warnungen und Hinweise an. Sie
können diese Anzahl auch der Variablen
warning_count
entnehmen:
SHOW COUNT(*) WARNINGS; SELECT @@warning_count;
Der Wert von warning_count
kann größer
sein als die Anzahl der von SHOW WARNINGS
angezeigten Meldungen. Dies liegt dann daran, dass die
Systemvariable max_error_count
so niedrig
angesetzt ist, dass nicht alle Meldungen gespeichert werden.
Ein weiter unten in diesem Anschnitt gezeigtes Beispiel
veranschaulicht, wie dies geschehen kann.
Die LIMIT
-Klausel hat dieselbe Syntax wie
bei der SELECT
-Anweisung. Siehe auch
Abschnitt 13.2.7, „SELECT
“.
Der MySQL Server sendet die Gesamtanzahl der Fehler, Warnungen
und Hinweise zurück, die aufgrund der letzten Anweisung
erzeugt wurden. Wenn Sie die C-API verwenden, lässt sich
dieser Wert durch einen Aufruf von
mysql_warning_count()
ermitteln. Siehe auch
Abschnitt 24.2.3.69, „mysql_warning_count()
“.
Warnungen werden für Anweisungen wie LOAD DATA
INFILE
und DML-Anweisungen wie
INSERT
, UPDATE
,
CREATE TABLE
und ALTER
TABLE
erzeugt.
Die folgende DROP TABLE
-Anweisung erzeugt
einen Hinweis:
mysql>DROP TABLE IF EXISTS no_such_table;
mysql>SHOW WARNINGS;
+-------+------+-------------------------------+ | Level | Code | Message | +-------+------+-------------------------------+ | Note | 1051 | Unknown table 'no_such_table' | +-------+------+-------------------------------+
Es folgt ein einfaches Beispiel, das eine Syntaxwarnung für
CREATE TABLE
und Konvertierungswarnungen
für INSERT
enthält:
mysql>CREATE TABLE t1 (a TINYINT NOT NULL, b CHAR(4)) TYPE=MyISAM;
Query OK, 0 rows affected, 1 warning (0.00 sec) mysql>SHOW WARNINGS\G
*************************** 1. row *************************** Level: Warning Code: 1287 Message: 'TYPE=storage_engine' is deprecated, use 'ENGINE=storage_engine' instead 1 row in set (0.00 sec) mysql>INSERT INTO t1 VALUES(10,'mysql'),(NULL,'test'),
->(300,'Open Source');
Query OK, 3 rows affected, 4 warnings (0.01 sec) Records: 3 Duplicates: 0 Warnings: 4 mysql>SHOW WARNINGS\G
*************************** 1. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 1 *************************** 2. row *************************** Level: Warning Code: 1263 Message: Data truncated, NULL supplied to NOT NULL column 'a' at row 2 *************************** 3. row *************************** Level: Warning Code: 1264 Message: Data truncated, out of range for column 'a' at row 3 *************************** 4. row *************************** Level: Warning Code: 1265 Message: Data truncated for column 'b' at row 3 4 rows in set (0.00 sec)
Die maximale Anzahl zu speichernder Fehler-, Warn- und
Hinweismeldungen wird von der Systemvariablen
max_error_count
gesteuert. Der Standardwert
ist 64. Um die Anzahl der Meldungen, die Sie speichern wollen,
zu ändern, modifizieren Sie den Wert von
max_error_count
. Im folgenden Beispiel
erzeugt die ALTER TABLE
-Anweisung drei
Warnmeldungen, von denen aber nur eine gespeichert wird, weil
max_error_count
zuvor auf 1 gesetzt worden
war:
mysql>SHOW VARIABLES LIKE 'max_error_count';
+-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | max_error_count | 64 | +-----------------+-------+ 1 row in set (0.00 sec) mysql>SET max_error_count=1;
Query OK, 0 rows affected (0.00 sec) mysql>ALTER TABLE t1 MODIFY b CHAR;
Query OK, 3 rows affected, 3 warnings (0.00 sec) Records: 3 Duplicates: 0 Warnings: 3 mysql>SELECT @@warning_count;
+-----------------+ | @@warning_count | +-----------------+ | 3 | +-----------------+ 1 row in set (0.01 sec) mysql>SHOW WARNINGS;
+---------+------+----------------------------------------+ | Level | Code | Message | +---------+------+----------------------------------------+ | Warning | 1263 | Data truncated for column 'b' at row 1 | +---------+------+----------------------------------------+ 1 row in set (0.00 sec)
Um Warnungen zu deaktivieren, setzen Sie
max_error_count
auf 0. In diesem Fall zeigt
warning_count
zwar noch an, wie viele
Warnungen aufgetreten sind, aber keine dieser Meldungen wird
gespeichert.
Sie können die Sitzungsvariable SQL_NOTES
auf 0 setzen, damit Warnungen auf der
Note
-Ebene nicht aufgezeichnet werden.
CACHE INDEXtbl_index_list
[,tbl_index_list
] ... INkey_cache_name
tbl_index_list
:tbl_name
[[INDEX|KEY] (index_name
[,index_name
] ...)]
Die Anweisung CACHE INDEX
weist
Tabellenindizes einem bestimmten Schlüssel-Cache zu. Sie wird
nur bei MyISAM
-Tabellen eingesetzt.
Die folgende Anweisung weist Indizes der Tabellen
t1
, t2
und
t3
dem Schlüssel-Cache namens
hot_cache
zu:
mysql> CACHE INDEX t1, t2, t3 IN hot_cache;
+---------+--------------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+--------------------+----------+----------+
| test.t1 | assign_to_keycache | status | OK |
| test.t2 | assign_to_keycache | status | OK |
| test.t3 | assign_to_keycache | status | OK |
+---------+--------------------+----------+----------+
Die Syntax von CACHE INDEX
gestattet Ihnen,
anzugeben, dass nur bestimmte Indizes aus einer Tabelle dem
Cache zuzuweisen sind. Die aktuelle Implementierung weist alle
Indizes der Tabelle dem Cache zu, weswegen es keinen Grund
gibt, einen anderen Parameter als den Tabellennamen zu
übergeben.
Der in der CACHE INDEX
-Anweisung
referenzierte Schlüssel-Cache kann erstellt werden, indem
seine Größe mit einer Anweisung zur Parametereinstellung
oder in den Parametereinstellungen des Servers angegeben wird.
Zum Beispiel:
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
Parameter eines Schlüssel-Caches lassen sich als Mitglieder einer strukturierten Systemvariablen einstellen. Siehe auch Abschnitt 5.2.3.1, „Strukturierte Systemvariablen“.
Ein Schlüssel-Cache muss bereits vorhanden sein, bevor Sie ihm Indizes zuweisen:
mysql> CACHE INDEX t1 IN non_existent_cache;
ERROR 1284 (HY000): Unknown key cache 'non_existent_cache'
Standardmäßig werden Tabellenindizes dem (vorgabeseitigen) Hauptschlüssel-Cache zugewiesen, der beim Serverstart erstellt wird. Wird ein Schlüssel-Cache zerstört, dann werden alle ihm zugewiesenen Indizes wieder dem Standardschlüssel-Cache zugewiesen.
Die Indexzuweisung wirkt sich global auf den Server aus: Wenn ein Client einem gegebenen Cache einen Index zuweist, wird der Cache für alle Abfragen verwendet, die diesen Index einbeziehen – unabhängig davon, welcher Client die Abfragen absetzt.
FLUSH [LOCAL | NO_WRITE_TO_BINLOG]flush_option
[,flush_option
] ...
Die FLUSH
-Anweisung leert verschiedene
interne Caches, die von MySQL verwendet werden, bzw. lädt
diese neu. Für die Ausführung von FLUSH
benötigen Sie die Berechtigung RELOAD
.
Die Anweisung RESET
ähnelt
FLUSH
. Siehe auch Abschnitt 13.5.5.5, „RESET
“.
flush_option
kann die folgenden
Werte annehmen:
HOSTS
Leert die Cache-Tabellen auf dem Host. Sie sollten die
Hosttabellen leeren, wenn einer Ihrer Hosts die IP-Nummer
wechselt oder Sie die Fehlermeldung Host
'
erhalten. Wenn aufeinander folgend mehr
als host_name
' is
blockedmax_connect_errors
Fehler für
einen gegebenen Host auftreten, während dieser eine
Verbindung mit dem MySQL Server herstellt, dann geht MySQL
davon aus, dass etwas nicht stimmt, und sperrt weitere
Verbindungsanfragen dieses Hosts. Das Synchronisieren der
Hosttabellen gestattet dem Host einen neuen Versuch der
Verbindungsherstellung. Siehe auch
Abschnitt A.2.5, „Host '...' is blocked
-Fehler“.
Sie können mysqld mit
--max_connect_errors=999999999
starten,
um diese Fehlermeldung zu verhindern.
DES_KEY_FILE
Lädt die DES-Schlüssel aus der mit der Option
--des-key-file
beim Serverstart
angegebenen Datei neu.
LOGS
Schließt alle Logdateien und öffnet sie neu. Wenn das
binäre Loggen aktiviert ist, wird die Sequenznummer der
Binärlogdatei relativ zur vorherigen Datei um den Wert 1
erhöht. Unter Unix ist dies das Gleiche wie das Senden
eines SIGHUP
-Signals an den
mysqld-Server. (Ausnahme sind einige
Versionen von Mac OS X 10.3, wo mysqld
SIGHUP
und SIGQUIT
ignoriert.)
Wenn der Server mit der Option
--log-error
gestartet wurde, bewirkt
FLUSH LOGS
, dass das Fehlerlog mit dem
Suffix -old
umbenannt wird und
mysqld eine neue leere Logdatei
erstellt. Wenn die Option --log-error
nicht angegeben wird, erfolgt keine Umbenennung.
PRIVILEGES
Lädt die Berechtigungen aus der Gesamtstruktur in der
mysql
-Datenbank neu.
QUERY CACHE
Defragmentiert den Abfrage-Cache, um seinen Speicher
besser zu nutzen. FLUSH QUERY CACHE
entfernt anders als RESET QUERY CACHE
keine Abfragen aus dem Cache.
STATUS
Setzt die meisten Statusvariablen auf null. Dies ist etwas, das Sie nur beim Debuggen einer Abfrage tun sollten. Siehe auch Abschnitt 1.8, „Wie man Bugs oder Probleme meldet“.
{TABLE | TABLES}
[
tbl_name
[,
tbl_name
] ...]
Wenn keine Tabellen benannt sind, werden alle Tabellen
geschlossen. Das Schließen aller gerade verwendeten
Tabellen wird ebenfalls erzwungen. Ferner wird der
Schlüssel-Cache synchronisiert. Werden ein oder mehrere
Tabellennamen angegeben, dann werden nur die angegebenen
Tabellen synchronisiert. FLUSH TABLES
entfernt ebenso wie RESET QUERY CACHE
zudem alle Abfrageergebnisse aus dem Abfrage-Cache.
TABLES WITH READ LOCK
Schließt alle offenen Tabellen und versieht alle Tabellen
für alle Datenbanken mit einer Lesesperre, bis Sie
UNLOCK TABLES
ausführen. Dies ist eine
recht praktische Möglichkeit der Datensicherung, wenn Sie
ein Dateisystem wie Veritas einsetzen, das rechtzeitig
Schnappschüsse erstellt.
USER_RESOURCES
Setzt alle Benutzerbeschränkungen auf Stundenbasis auf
null. Hierdurch können Clients, bei denen der Grenzwert
für Verbindungen, Abfragen oder Änderungen pro Stunde
erreicht wurde, ihre Aktivitäten direkt wiederaufnehmen.
FLUSH USER_RESOURCES
wirkt sich
allerdings nicht auf die Begrenzung gleichzeitiger
Verbindungen aus. Siehe auch Abschnitt 13.5.1.3, „GRANT
und REVOKE
“.
FLUSH
-Anweisungen werden in das Binärlog
geschrieben, sofern das optionale Schlüsselwort
NO_WRITE_TO_BINLOG
(oder sein Alias
LOCAL
) nicht verwendet wird. Dies wird
gemacht, damit FLUSH
-Anweisungen, die auf
einem MySQL Server verwendet werden, der als
Replikationsmaster agiert, standardmäßig auf den
Replikationsslave repliziert werden.
Hinweis: FLUSH
LOGS
, FLUSH MASTER
,
FLUSH SLAVE
und FLUSH TABLES WITH
READ LOCK
werden keinesfalls geloggt, weil dies bei
der Replikation auf einen Slave Probleme verursachen würde.
Sie können auf einige dieser Anweisungen auch mit dem
Hilfsprogramm mysqladmin zugreifen, indem
Sie die Befehle flush-hosts
,
flush-logs
,
flush-privileges
,
flush-status
oder
flush-tables
verwenden.
Hinweis: Es ist in MySQL
5.1 nicht möglich,
FLUSH
-Anweisungen in gespeicherten
Funktionen oder Triggern abzusetzen. Allerdings können Sie
FLUSH
in gespeicherten Prozeduren benutzen,
solange diese nicht aus gespeicherten Funktionen heraus oder
von Triggern aufgerufen werden. Siehe auch
Abschnitt I.1, „Beschränkungen bei gespeicherten Routinen und Triggern“.
Informationen dazu, wie die RESET
-Anweisung
bei der Replikation verwendet wird, finden Sie in
Abschnitt 13.5.5.5, „RESET
“.
KILL [CONNECTION | QUERY] thread_id
Jede Verbindung mit mysqld wird in einem
separaten Thread ausgeführt. Mit der Anweisung SHOW
PROCESSLIST
können Sie die gerade ausgeführten
Threads auflisten. Die Terminierung eines Threads ist mit der
Anweisung KILL
möglich.
thread_id
KILL
unterstützt die optionalen
Modifizierer CONNECTION
oder
QUERY
:
KILL CONNECTION
entspricht
KILL
ohne Modifizierer: Es terminiert
die Verbindung zur angegebenen Kennung
thread_id
.
KILL QUERY
terminiert die über die
Verbindung aktuell ausgeführte Anweisung, lässt die
Verbindung selbst aber bestehen.
Wenn Sie die Berechtigung PROCESS
haben,
werden alle Threads angezeigt. Wenn Sie die Berechtigung
SUPER
haben, können Sie alle Threads und
Anweisungen terminieren. Andernfalls werden nur Ihre eigenen
Threads und Anweisungen angezeigt und zur Terminierung
freigegeben.
Zur Überprüfung und Terminierung von Threads können Sie auch die Befehle mysqladmin processlist und mysqladmin kill verwenden.
Hinweis: Sie können
KILL
nicht mit der Embedded MySQL
Server-Bibliothek verwenden, da der eingebettete Server nur in
den Threads der Hostanwendung ausgeführt wird – er selbst
erstellt also keine Verbindungs-Threads.
Wenn Sie KILL
verwenden, wird ein
Thread-spezifisches Terminierungs-Flag für den Thread
gesetzt. In den meisten Fällen kann es etwas dauern, bis die
Terminierung des Threads abgeschlossen ist, weil das Flag nur
in bestimmten Abständen überprüft wird:
Bei SELECT
-, ORDER
BY
- und GROUP BY
-Schleifen
wird das Flag nach dem Lesen eines Datensatzblocks
überprüft. Ist das Terminierungs-Flag gesetzt, dann wird
die Anweisung abgebrochen.
Bei ALTER TABLE
wird das
Terminierungs-Flag vor jedem Lesen eines Datensatzblocks
aus der Ursprungstabelle geprüft. Wurde das Flag gesetzt,
dann wird die Anweisung abgebrochen und die
Temporärtabelle gelöscht.
Bei UPDATE
- oder
DELETE
-Operationen wird das Flag nach
jedem gelesenen Block und nach jedem geänderten oder
gelöschten Datensatz überprüft. Ist das
Terminierungs-Flag gesetzt, dann wird die Anweisung
abgebrochen. Beachten Sie, dass, wenn Sie keine
Transaktionen verwenden, bereits erfolgte Änderungen
nicht rückgängig gemacht werden.
GET_LOCK()
führt einen Abbruch aus und
gibt NULL
zurück.
Ein INSERT DELAYED
-Thread
synchronisiert schnell alle Datensätze in seinem Speicher
(d. h., er schreibt sie) und wird dann terminiert.
Wenn der Thread sich im Tabellensperr-Handler befindet
(Zustand Locked
), dann wird die
Tabellensperre umgehend aufgehoben.
Wartet der Thread bei einem Schreibaufruf auf freien Festplattenspeicher, dann wird die Schreiboperation mit der Fehlermeldung „Disk Full“ abgebrochen.
Warnung: Die Terminierung
einer REPAIR TABLE
- oder
OPTIMIZE TABLE
-Operation führt bei
einer MyISAM
-Tabelle zu
Beschädigungen, die die Tabelle unbrauchbar machen. Lese-
oder Schreiboperationen in eine solche Tabelle schlagen
fehl, bis Sie sie – ohne Unterbrechung – wieder
optimieren oder reparieren.
LOAD INDEX INTO CACHEtbl_index_list
[,tbl_index_list
] ...tbl_index_list
:tbl_name
[[INDEX|KEY] (index_name
[,index_name
] ...)] [IGNORE LEAVES]
Die Anweisung LOAD INDEX INTO CACHE
lädt
einen Tabellenindex vorab in den Schlüssel-Cache, dem er
durch eine explizite CACHE INDEX
-Anweisung
zugewiesen wurde, oder aber in den vorgabeseitigen
Schlüssel-Cache. LOAD INDEX INTO CACHE
wird nur bei MyISAM
-Tabellen verwendet.
Der Modifizierer IGNORE LEAVES
bewirkt,
dass nur Blöcke für Indexknoten, die nicht Endknoten
(Blätter) sind, geladen werden.
Die folgende Anweisung lädt Knoten (Indexblöcke) mit Indizes
der Tabellen t1
und t2
:
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES;
+---------+--------------+----------+----------+
| Table | Op | Msg_type | Msg_text |
+---------+--------------+----------+----------+
| test.t1 | preload_keys | status | OK |
| test.t2 | preload_keys | status | OK |
+---------+--------------+----------+----------+
Die Anweisung lädt alle Indexblöcke aus
t1
. Bei t2
werden nur
Blöcke für Nichtendknoten geladen.
Die Syntax von LOAD INDEX INTO CACHE
gestattet Ihnen, anzugeben, dass nur bestimmte Indizes aus
einer Tabelle geladen werden sollen. Die aktuelle
Implementierung lädt alle Indizes der Tabelle in den Cache,
weswegen es keinen Grund gibt, einen anderen Parameter als den
Tabellennamen zu übergeben.
RESETreset_option
[,reset_option
] ...
Die RESET
-Anweisung wird benutzt, um den
Status verschiedener Serveroperationen zu löschen. Sie
benötigen die Berechtigung RELOAD
, um
RESET
ausführen zu können.
RESET
agiert als stärkere Version der
FLUSH
-Anweisung. Siehe auch
Abschnitt 13.5.5.2, „FLUSH
“.
reset_option
kann die folgenden
Werte annehmen:
MASTER
Löscht alle in der Indexdatei aufgeführten Binärlogs,
leert den Binärlogindex und setzt ihn zurück und
erstellt eine neue Binärlogdatei. (Ist als FLUSH
MASTER
in MySQL-Versionen vor 3.23.26 bekannt.)
Siehe auch Abschnitt 13.6.1, „SQL-Anweisungen für die Steuerung von Master-Servern“.
QUERY CACHE
Entfernt alle Abfrageergebnisse aus dem Abfrage-Cache.
SLAVE
Löscht auf dem Slave die Angabe zur Replikationsposition
in den Binärlogs des Masters (d. h., der Slave
„vergisst“ die Position). Setzt außerdem das
Relay-Log zurück, indem alle vorhandenen Relay-Logdateien
gelöscht werden und eine neue Logdatei begonnen wird.
(Ist als FLUSH SLAVE
in MySQL-Versionen
vor 3.23.26 bekannt.) Siehe auch
Abschnitt 13.6.2, „SQL-Anweisungen für die Steuerung von Slave-Servern“.
Dieser Abschnitt beschreibt SQL-Anweisungen, die im Zusammenhang mit der Replikation von Bedeutung sind. Eine Gruppe von Anweisungen wird zur Steuerung der Master-Server verwendet, die andere zur Steuerung der Slave-Server.
Die Replikation kann über die SQL-Schnittstelle gesteuert werden. Dieser Bereich beschreibt die Anweisungen zur Verwaltung der Replikationsmaster-Server. Abschnitt 13.6.2, „SQL-Anweisungen für die Steuerung von Slave-Servern“, beschreibt Anweisungen zur Verwaltung der Slave-Server.
PURGE {MASTER | BINARY} LOGS TO 'log_name
' PURGE {MASTER | BINARY} LOGS BEFORE 'date
'
Löscht alle Binärlogs, die im Logindex vor dem angegebenen Log oder Datum aufgelistet sind. Die Logs werden auch von der Liste entfernt, die in der Logindexdatei aufgezeichnet ist, d. h., das übergebene Log wird zum ersten Log auf der Liste.
Beispiel:
PURGE MASTER LOGS TO 'mysql-bin.010'; PURGE MASTER LOGS BEFORE '2003-04-02 22:46:26';
Das Argument date
der Variante
BEFORE
kann im Format 'YYYY-MM-DD
hh:mm:ss'
angegeben werden.
MASTER
und BINARY
sind
Synonyme.
Diese Anweisung kann auch bei laufender Slave-Replikation sicher ausgeführt werden. Sie müssen die Replikation also nicht anhalten. Wenn ein aktiver Slave gerade eines der Logs ausliest, das Sie löschen wollen, dann hat die Anweisung keine Auswirkungen, sondern schlägt mit einem Fehler fehl. Wenn allerdings ein Slave schläft und Sie eines der Logs löschen, die dieser Slave noch lesen muss, dann wird er nach dem Erwachen nicht mehr zur Replikation in der Lage sein.
Um Logs sicher zu löschen, gehen Sie wie folgt vor:
Sie setzen auf allen Slave-Servern SHOW SLAVE
STATUS
ab, um zu prüfen, welches Log gerade
gelesen wird.
Sie zeigen mit SHOW MASTER LOGS
eine
Liste der Logdateien auf dem Master-Server an.
Ermitteln Sie das zeitlich früheste Log unter allen Slaves. Dies ist das Ziellog. Wenn alle Slaves aktuell sind, muss es das letzte Log auf der Liste sein.
Erstellen Sie eine Kopie aller Logs, die Sie zu löschen beabsichtigen. (Dieser Schritt ist optional, aber stets empfehlenswert.)
Löschen Sie alle Logs bis zum Ziellog (aber nicht das Ziellog selbst).
RESET MASTER
Löscht alle in der Indexdatei aufgeführten Binärlogs, leert den Binärlogindex und setzt ihn zurück und erstellt eine neue Binärlogdatei.
SET SQL_LOG_BIN = {0|1}
Aktiviert oder deaktiviert das binäre Loggen für die
aktuelle Verbindung (SQL_LOG_BIN
ist eine
Sitzungsvariable), sofern der Client die Berechtigung
SUPER
hat. Die Anweisung wird mit einem
Fehler abgewiesen, wenn der Client die Berechtigung nicht hat.
SHOW BINLOG EVENTS [IN 'log_name
'] [FROMpos
] [LIMIT [offset
,]row_count
]
Zeigt die Ereignisse im Binärlog an. Wenn Sie
'
nicht
angeben, wird das erste Binärlog angezeigt.
log_name
'
Die LIMIT
-Klausel hat dieselbe Syntax wie
bei der SELECT
-Anweisung. Siehe auch
Abschnitt 13.2.7, „SELECT
“.
Hinweis: Das Absetzen einer
SHOW BINLOG EVENTS
-Anweisung ohne
LIMIT
-Klausel kann einen sehr zeit- und
ressourcenaufwändigen Prozess starten, weil der Server den
vollständigen Inhalt des Binärlogs an den Client zurückgibt
(dieses Log enthält alle datenändernden Anweisungen, die vom
Server ausgeführt wurden). Als Alternative zu SHOW
BINLOG EVENTS
können Sie das Hilfsprogramm
mysqlbinlog verwenden. Sie können damit
das Binärlog in eine Textdatei speichern und später
untersuchen. Siehe auch Abschnitt 8.8, „mysqlbinlog — Hilfsprogramm für die Verarbeitung binärer Logdateien“.
SHOW MASTER LOGS SHOW BINARY LOGS
Listet die Binärlogdateien auf dem Server auf. Diese
Anweisung wird im Zuge eines Vorgangs benutzt, der in
Abschnitt 13.6.1.1, „PURGE MASTER LOGS
“, beschrieben ist. Dort
wird gezeigt, wie man ermittelt, welche Logdateien gelöscht
werden können.
mysql> SHOW BINARY LOGS;
+---------------+-----------+
| Log_name | File_size |
+---------------+-----------+
| binlog.000015 | 724935 |
| binlog.000016 | 733481 |
+---------------+-----------+
SHOW BINARY LOGS
ist äquivalent mit
SHOW MASTER LOGS
.
SHOW MASTER STATUS
Vermittelt Statusinformationen zu den Binärlogdateien des Masters. Beispiel:
mysql > SHOW MASTER STATUS;
+---------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73 | test | manual,mysql |
+---------------+----------+--------------+------------------+
Die Replikation kann über die SQL-Schnittstelle gesteuert werden. Dieser Abschnitt beschreibt die Anweisungen zur Verwaltung der Replikationsslave-Server. Abschnitt 13.6.1, „SQL-Anweisungen für die Steuerung von Master-Servern“, beschreibt Anweisungen zur Verwaltung der Master-Server.
CHANGE MASTER TOmaster_def
[,master_def
] ...master_def
: MASTER_HOST = 'host_name
' | MASTER_USER = 'user_name
' | MASTER_PASSWORD = 'password
' | MASTER_PORT =port_num
| MASTER_CONNECT_RETRY =count
| MASTER_LOG_FILE = 'master_log_name
' | MASTER_LOG_POS =master_log_pos
| RELAY_LOG_FILE = 'relay_log_name
' | RELAY_LOG_POS =relay_log_pos
| MASTER_SSL = {0|1} | MASTER_SSL_CA = 'ca_file_name
' | MASTER_SSL_CAPATH = 'ca_directory_name
' | MASTER_SSL_CERT = 'cert_file_name
' | MASTER_SSL_KEY = 'key_file_name
' | MASTER_SSL_CIPHER = 'cipher_list
'
CHANGE MASTER TO
ändert die Parameter, die
der Slave-Server zur Verbindungsherstellung und Kommunikation
mit dem Master-Server verwendet. Die Anweisung aktualisiert
auch den Inhalt der Dateien master.info
und relay-log.info
.
MASTER_USER
,
MASTER_PASSWORD
,
MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
,
MASTER_SSL_KEY
und
MASTER_SSL_CIPHER
vermitteln dem Slave
Informationen dazu, wie er Verbindungen mit dem Master
herstellen kann.
Die SSL-Optionen (MASTER_SSL
,
MASTER_SSL_CA
,
MASTER_SSL_CAPATH
,
MASTER_SSL_CERT
,
MASTER_SSL_KEY
und
MASTER_SSL_CIPHER
) können auch auf Slaves
geändert werden, die ohne SSL-Unterstützung kompiliert
wurden. Sie werden in der Datei
master.info
gespeichert, aber ignoriert,
bis Sie einen Server verwenden, auf dem die SSL-Unterstützung
aktiviert ist.
Wenn Sie einen der Parameter nicht angeben, dann behält er in der Regel seinen alten Wert (Ausnahmen entnehmen Sie der nachfolgenden Erläuterung). Wenn sich beispielsweise das Passwort, mit dem die Verbindung zu Ihrem MySQL-Master hergestellt wird, geändert hat, müssen Sie nur die folgenden Anweisungen absetzen, um dem Slave das neue Passwort mitzuteilen:
STOP SLAVE; -- if replication was running CHANGE MASTER TO MASTER_PASSWORD='new3cret'; START SLAVE; -- if you want to restart replication
Es ist nicht notwendig, Parameter anzugeben, die sich nicht ändern (Host, Port, Benutzer usw.).
MASTER_HOST
und
MASTER_PORT
sind der Hostname (oder die
IP-Adresse) des Master-Hosts bzw. sein TCP/IP-Port. Beachten
Sie, dass, wenn MASTER_HOST
gleich
localhost
ist, die Portnummer – wie unter
MySQL bei anderen Gelegenheiten auch – unter Umständen
ignoriert werden kann (dies ist etwa der Fall, wenn
Unix-Socketdateien benutzt werden).
Geben Sie MASTER_HOST
oder
MASTER_PORT
an, dann setzt der Slave
voraus, dass der Master-Server sich vom vorherigen
unterscheidet (und zwar auch dann, wenn Sie einen Host- oder
Portwert angeben, der mit dem aktuellen Wert identisch ist).
In diesem Fall werden die alten Namens- und Positionswerte der
Binärlogdatei auf dem Master-Server als nun ungültig
betrachtet, d. h., wenn Sie
MASTER_LOG_FILE
und
MASTER_LOG_POS
in der Anweisung nicht
angeben, werden stillschweigend
MASTER_LOG_FILE=''
und
MASTER_LOG_POS=4
angehängt.
MASTER_LOG_FILE
und
MASTER_LOG_POS
sind die Koordinaten, bei
denen der Slave-I/O-Thread mit dem Lesen vom Master beginnen
soll, wenn der Thread beim nächsten Mal startet. Wenn Sie
einen dieser Werte angeben, dürfen Sie
RELAY_LOG_FILE
oder
RELAY_LOG_POS
nicht angeben. Wenn weder
MASTER_LOG_FILE
noch
MASTER_LOG_POS
angegeben werden, verwendet
der Slave die letzten Koordinaten des
Slave-SQL-Threads, bevor CHANGE
MASTER
abgesetzt wurde. Hierdurch ist
gewährleistet, dass es bei der Replikation auch dann nicht zu
Unstetigkeiten kommt, wenn der Slave-SQL-Thread sehr spät mit
dem Slave-I/O-Thread verglichen wurde – etwa dann, wenn Sie
beispielsweise nur das zu verwendende Passwort ändern wollen.
CHANGE MASTER
löscht alle
Relay-Logdateien und beginnt eine neue
Relay-Logdatei, sofern Sie nicht
RELAY_LOG_FILE
oder
RELAY_LOG_POS
angeben. In diesem Fall
werden die Relay-Logs behalten, und die globale Variable
relay_log_purge
wird stillschweigend auf 0
gesetzt.
CHANGE MASTER
ist praktisch, wenn es darum
geht, einen Slave zu konfigurieren, und Sie hierfür die
Momentaufnahme des Masters benötigen und Logdatei und Offset
entsprechend aufgezeichnet haben. Nachdem Sie die
Momentaufnahme in den Slave geladen haben, können Sie
CHANGE MASTER TO
MASTER_LOG_FILE='
auf dem Slave ausführen.
log_name_on_master
',
MASTER_LOG_POS=log_offset_on_master
Das folgende Beispiel ändert die Koordinaten des Masters und dessen Binärlogdatei. Dies tut man, wenn man den Slave so konfiguriert, dass er den Master repliziert:
CHANGE MASTER TO MASTER_HOST='master2.mycompany.com', MASTER_USER='replication', MASTER_PASSWORD='bigs3cret', MASTER_PORT=3306, MASTER_LOG_FILE='master2-bin.001', MASTER_LOG_POS=4, MASTER_CONNECT_RETRY=10;
Das nächste Beispiel zeigt eine Operation, die weniger
häufig benötigt wird. Sie wird verwendet, wenn auf dem Slave
Relay-Logs vorhanden sind, die Sie aus irgendeinem Grund
erneut ausführen wollen. Zu diesem Zweck muss der Master
nicht erreichbar sein. Sie müssen lediglich CHANGE
MASTER TO
benutzen und den SQL-Thread mit
START SLAVE SQL_THREAD
starten:
CHANGE MASTER TO RELAY_LOG_FILE='slave-relay-bin.006', RELAY_LOG_POS=4025;
Sie können die zweite Operation sogar in einer
Nicht-Replikations-Konfiguration mit einem eigenständigen
Nicht-Slave-Server benutzen, um nach einem Absturz eine
Wiederherstellung durchzuführen. Angenommen, Ihr Server ist
abgestürzt, und Sie haben eine Sicherung wiederhergestellt.
Nun wollen Sie die eigenen Binärlogs des Servers – nicht
die Relay-Logs, sondern die regulären Binärlogs – namens
(beispielsweise) myhost-bin.*
wieder auf
den Server aufspielen. Zunächst erstellen Sie ein Backup
dieser Binärlogs an einer sicheren Position für den Fall,
dass Sie der nachfolgenden Anleitung nicht exakt folgen und
der Server deswegen die Binärlogs unbeabsichtigt löscht.
Verwenden Sie SET GLOBAL relay_log_purge=0
,
um die Sicherheit zu erhöhen. Danach starten Sie den Server
ohne die Option --log-bin
. Stattdessen geben
Sie die Optionen --replicate-same-server-id
,
--relay-log=myhost-bin
(damit der Server
glaubt, dass es sich bei diesen regulären Logs um Relay-Logs
handelt) und --skip-slave-start
an. Nach dem
Serverstart setzen Sie die folgenden Anweisungen ab:
CHANGE MASTER TO RELAY_LOG_FILE='myhost-bin.153', RELAY_LOG_POS=410, MASTER_HOST='some_dummy_string'; START SLAVE SQL_THREAD;
Der Server liest nun seine eigenen Binärlogs und führt diese
aus. Auf diese Weise erfolgt eine Wiederherstellung der Daten.
Nach deren Abschluss führen Sie STOP SLAVE
aus, fahren den Server herunter, löschen die Dateien
master.info
und
relay-log.info
und starten den Server mit
den ursprünglichen Optionen neu.
Die Angabe der Option MASTER_HOST
(auch mit
einem Pseudowert) ist erforderlich, damit der Server annimmt,
er sei ein Slave.
LOAD DATA FROM MASTER
Diese Anweisung erstellt eine Momentaufnahme des Masters und
kopiert diese auf den Slave. Sie aktualisiert die Werte von
MASTER_LOG_FILE
und
MASTER_LOG_POS
, sodass der Slave die
Replikation an der korrekten Position startet.
Ausschlussregeln für Tabellen und Datenbanken, die mit den
Optionen --replicate-*-do-*
und
--replicate-*-ignore-*
angegeben werden,
werden beachtet. --replicate-rewrite-db
wird
hingegen nicht berücksichtigt, weil ein
Benutzer mit dieser Option eine nichteindeutige Zuordnung wie
--replicate-rewrite-db="db1->db3"
oder
--replicate-rewrite-db="db2->db3"
vornehmen könnte, was den Slave beim Laden der Tabellen vom
Master verwirren würde.
Die Verwendung dieser Anweisung hängt von den folgenden Bedingungen ab:
Sie funktioniert nur bei
MyISAM
-Tabellen. Der Versuch, eine
Tabelle anderen Typs zu laden, führt zu folgendem Fehler:
ERROR 1189 (08S01): Net error reading from master
Sie erwirkt während der Aufzeichnung der Momentaufnahme eine globale Lesesperre auf dem Master, wodurch während des Ladevorgangs Updates auf dem Master unterbunden werden.
Wenn Sie große Tabellen laden, müssen Sie die Werte von
net_read_timeout
und
net_write_timeout
unter Umständen sowohl
auf dem Master- als auch auf den Slave-Servern erhöhen. Siehe
auch Abschnitt 5.2.2, „Server-Systemvariablen“.
Beachten Sie, dass LOAD DATA FROM MASTER
keine Tabellen aus der
mysql
-Datenbank kopiert. Dies erleichtert
die Einrichtung verschiedener Benutzer und Berechtigungen auf
dem Master und dem Slave.
Um LOAD DATA FROM MASTER
verwenden zu
können, benötigt das Replikationskonto, welches zur
Verbindung mit dem Master-Server verwendet wird, die
Berechtigungen RELOAD
und
SUPER
auf dem Master und die Berechtigung
SELECT
für alle Master-Tabellen, die Sie
laden wollen. Alle Master-Tabellen, für die der Benutzer die
Berechtigung SELECT
nicht hat, werden von
LOAD DATA FROM MASTER
ignoriert. Dies liegt
daran, dass der Master sie vor dem Benutzer verbirgt:
LOAD DATA FROM MASTER
ruft SHOW
DATABASES
auf, um die zu ladenden Master-Datenbanken
in Erfahrung zu bringen; SHOW DATABASES
aber gibt nur Datenbanken zurück, für die der Benutzer
Berechtigungen hat. Siehe auch
Abschnitt 13.5.4.7, „SHOW DATABASES
“. Auf der Slave-Seite
benötigt der Benutzer, der LOAD DATA FROM
MASTER
absetzt, Berechtigungen zum Löschen und
Erstellen der Datenbanken und Tabellen, die kopiert werden.
LOAD TABLE tbl_name
FROM MASTER
Überträgt eine Kopie der Tabelle vom Master auf den Slave.
Diese Anweisung wurde in erster Linie zum Debuggen von
LOAD DATA FROM MASTER
-Operationen
implementiert. Um LOAD TABLE
verwenden zu
können, benötigt das Konto, welches zur Verbindung mit dem
Master-Server verwendet wird, die Berechtigungen
RELOAD
und SUPER
auf dem
Master und die Berechtigung SELECT
für die
zu ladende Master-Tabelle. Auf der Slave-Seite benötigt der
Benutzer, der LOAD TABLE FROM MASTER
absetzt, Berechtigungen zum Löschen und Erstellen der
Tabelle.
Die Bedingungen für LOAD DATA FROM MASTER
gelten auch hier. So funktioniert LOAD TABLE FROM
MASTER
beispielsweise nur bei
MyISAM
-Tabellen. Auch die Hinweise zu
Zeitüberschreitungen für LOAD DATA FROM
MASTER
sind anzuwenden.
SELECT MASTER_POS_WAIT('master_log_file
',master_log_pos
)
Dies ist eigentlich eine Funktion und keine Anweisung. Mit ihr kann gewährleistet werden, dass der Slave Ereignisse bis zu einer gegebenen Position im Binärlog des Masters gelesen und ausgeführt hat. Eine vollständige Beschreibung finden Sie in Abschnitt 12.10.4, „Verschiedene Funktionen“.
RESET SLAVE
RESET SLAVE
löscht auf dem Slave die
Angabe zur Replikationsposition in den Binärlogs des Masters
(d. h., der Slave „vergisst“ die Position).
Diese Anweisung ist zur Verwendung für einen sauberen Start
vorgesehen: Sie löscht die Dateien
master.info
und
relay-log.info
und alle Relay-Logs und
beginnt ein neues Relay-Log.
Hinweis: Alle Relay-Logs
werden gelöscht – auch dann, wenn sie nicht vollständig
vom Slave-SQL-Thread ausgeführt wurden. (Dieser Umstand ist
wahrscheinlich auf einem Replikationsslave gegeben, wenn Sie
eine STOP SLAVE
-Anweisung abgesetzt haben
oder der Slave stark belastet ist.)
Verbindungsdaten, die in der Datei
master.info
gespeichert sind, werden
direkt unter Berücksichtigung von Werten zurückgesetzt, die
ggf. mit den entsprechenden Startoptionen angegeben werden. Zu
diesen Daten gehören Werte wie Master-Host, Master-Port,
Master-Benutzer und Master-Passwort. Wenn der Slave-SQL-Thread
gerade mit der Replikation von Temporärtabellen beschäftigt
war, als er angehalten wurde, und RESET
SLAVE
abgesetzt wird, dann werden diese replizierten
Temporärtabellen auf dem Slave gelöscht.
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = N
Diese Anweisung überspringt die nächsten
N
Ereignisse auf dem Master. Dies
ist nützlich, wenn Replikationen wiederhergestellt werden
sollen, die durch eine Anweisung angehalten wurden.
Die Anweisung ist nur gültig, wenn der Slave-Thread nicht ausgeführt wird. Andernfalls erzeugt er einen Fehler.
SHOW SLAVE STATUS
Diese Anweisung vermittelt Statusinformationen zu wesentlichen
Parametern der Slave-Threads. Wenn Sie diese Anweisung mit dem
mysql-Client absetzen, können Sie
\G
statt des Semikolons als
Abschlusszeichen für die Anweisung verwenden, um eine
vertikale Ausgabe zu erhalten, die besser zu lesen ist:
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: localhost
Master_User: root
Master_Port: 3306
Connect_Retry: 3
Master_Log_File: gbichot-bin.005
Read_Master_Log_Pos: 79
Relay_Log_File: gbichot-relay-bin.005
Relay_Log_Pos: 548
Relay_Master_Log_File: gbichot-bin.005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 79
Relay_Log_Space: 552
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 8
SHOW SLAVE STATUS
gibt die folgenden Felder
zurück:
Slave_IO_State
Eine Kopie des State
-Felds in der
Ausgabe von SHOW PROCESSLIST
für den
Slave-I/O-Thread. Sie zeigt an, was der Thread gerade tut:
Verbindungsherstellung zum Master, Warten auf vom Master
kommende Ereignisse, Wiederverbindung mit dem Master usw.
Mögliche Zustände sind in
Abschnitt 6.4, „Replikation: Implementationsdetails“,
beschrieben. Bei älteren MySQL-Versionen ist eine
Überprüfung dieses Felds notwendig, denn diese erlaubten
eine fortlaufende Ausführung des Threads auch für den
Fall, dass eine Verbindungsherstellung mit dem Master
nicht möglich war. Wird er ausgeführt, so liegt kein
Problem vor; andernfalls finden Sie den Fehler im Feld
Last_Error
(siehe unten).
Master_Host
Der aktuelle Master-Host.
Master_User
Der aktuelle Benutzer, der mit dem Master verbunden ist.
Master_Port
Der aktuelle Master-Port.
Connect_Retry
Der aktuelle Wert der Option
--master-connect-retry
.
Master_Log_File
Der Name der Master-Binärlogdatei, aus der der I/O-Thread derzeit liest.
Read_Master_Log_Pos
Die Position, bis zu der der I/O-Thread im aktuellen Master-Binärlog gelesen hat.
Relay_Log_File
Der Name der Relay-Logdatei, deren Angaben der SQL-Thread derzeit liest und ausführt.
Relay_Log_Pos
Die Position, bis zu der der SQL-Thread Angaben in der aktuellen Relay-Logdatei gelesen und ausgeführt hat.
Relay_Master_Log_File
Der Name der Master-Binärlogdatei, die das aktuelle Ereignis enthält, welches gerade vom SQL-Thread ausgeführt wird.
Slave_IO_Running
Gibt an, ob der I/O-Thread gestartet wurde und erfolgreich
eine Verbindung mit dem Master herstellen konnte. Bei
älteren MySQL-Versionen (vor 4.1.14 und 5.0.12) hat
Slave_IO_Running
den Wert
YES
, wenn der I/O-Thread gestartet
wurde (und zwar auch dann, wenn noch keine Verbindung zum
Master hergestellt wurde).
Slave_SQL_Running
Gibt an, ob der SQL-Thread gestartet wurde.
Replicate_Do_DB
,
Replicate_Ignore_DB
Liste der Datenbanken, die ggf. mit den Optionen
--replicate-do-db
und
--replicate-ignore-db
angegeben wurden.
Replicate_Do_Table
,
Replicate_Ignore_Table
,
Replicate_Wild_Do_Table
,
Replicate_Wild_Ignore_Table
Liste der Tabellen, die ggf. mit den Optionen
--replicate-do-table
,
--replicate-ignore-table
,
--replicate-wild-do-table
und
--replicate-wild-ignore_table
angegeben
wurden.
Last_Errno
,
Last_Error
Nummer und Meldung des Fehlers, der von der zuletzt
ausgeführten Abfrage zurückgegeben wurde. Die
Fehlernummer 0 und der Leer-String als Meldung haben die
Bedeutung „kein Fehler“. Wenn der Wert
Last_Error
nicht leer ist, erscheint er
auch als Meldung im Fehlerlog des Slaves. Zum Beispiel:
Last_Errno: 1051 Last_Error: error 'Unknown table 'z'' on query 'drop table z'
Die Meldung zeigt an, dass die Tabelle
z
auf dem Master vorhanden war und dort
gelöscht wurde, dass sie aber auf dem Slave nicht
existierte, weswegen die Anweisung DROP
TABLE
dort fehlschlug. (Dies kann beispielsweise
passieren, wenn Sie vergessen, die Tabelle beim Einrichten
der Replikation auf den Slave zu kopieren.)
Skip_Counter
Der zuletzt verwendete Wert von
SQL_SLAVE_SKIP_COUNTER
.
Exec_Master_Log_Pos
Die Position des letzten vom SQL-Thread ausgeführten
Ereignisses aus dem Binärlog des Masters
(Relay_Master_Log_File
).
(Relay_Master_Log_File
,
Exec_Master_Log_Pos
) im Binärlog des
Masters entspricht (Relay_Log_File
,
Relay_Log_Pos
) im Relay-Log.
Relay_Log_Space
Die Gesamtgröße aller vorhandenen Relay-Logs.
Until_Condition
,
Until_Log_File
,
Until_Log_Pos
Der in der UNTIL
-Klausel der
START SLAVE
-Anweisung angegebene Wert.
Until_Condition
kann folgende Werte
haben:
None
, sofern keine
UNTIL
-Klausel angegeben wurde.
Master
, wenn der Slave bis zu einer
angegebenen Position in den Binärlogs des Masters
liest.
Relay
, wenn der Slave bis zu einer
angegebenen Position in seinen Binärlogs liest.
Until_Log_File
und
Until_Log_Pos
geben den Namen der
Logdatei und die Position an. Diese Werte definieren den
Punkt, an dem die Ausführung des SQL-Threads endet.
Master_SSL_Allowed
,
Master_SSL_CA_File
,
Master_SSL_CA_Path
,
Master_SSL_Cert
,
Master_SSL_Cipher
,
Master_SSL_Key
Diese Felder geben (sofern vorhanden) die SSL-Parameter an, die vom Slave zur Verbindung mit dem Master verwendet werden.
Master_SSL_Allowed
kann folgende Werte
haben:
Yes
, wenn eine SSL-Verbindung zum
Master zulässig ist.
No
, wenn keine SSL-Verbindung zum
Master zulässig ist.
Ignored
, wenn eine SSL-Verbindung
zwar zulässig ist, aber am Slave-Server die
SSL-Unterstützung nicht aktiviert ist.
Die Werte der übrigen SSL-spezifischen Felder entsprechen
den Werten der Optionen --master-ca
,
--master-capath
,
--master-cert
,
--master-cipher
und
--master-key
.
Seconds_Behind_Master
Dieses Feld gibt an, wie „verspätet“ der Slave ist:
Wenn der Slave-SQL-Thread aktiv läuft (d. h. Änderungen verarbeitet), dann gibt dieses Feld die Anzahl der Sekunden an, die seit dem Zeitstempel des Ereignisses vergangen sind, das von diesem Thread zuletzt auf dem Master ausgeführt wurde.
Wenn der SQL-Thread den Slave-I/O-Thread eingeholt hat und untätig auf weitere Ereignisse vom I/O-Thread wartet, ist das Feld null.
Im Endeffekt misst das Feld also den zeitlichen Unterschied zwischen dem Slave-SQL-Thread und dem Slave-I/O-Thread.
Ist die Netzwerkverbindung zwischen Master und Slave sehr
schnell, dann liegt der Slave-I/O-Thread recht nah am
Master, d. h., das Feld erlaubt eine recht genaue
Schätzung des zeitlichen Verarbeitungsabstandes zwischen
Slave-SQL-Thread und dem Master. Ist das Netzwerk hingegen
langsam, dann ist der Wert nicht sehr
aussagekräftig: Der Slave-SQL-Thread kann recht häufig
zum langsam lesenden Slave-I/O-Thread aufschließen,
weswegen Seconds_Behind_Master
oft den
Wert 0 anzeigt – und zwar auch dann, wenn der I/O-Thread
im Vergleich zum Master relativ stark verspätet ist.
Anders gesagt, diese Spalte ist nur bei
schnellen Netzwerken aussagekräftig.
Diese Berechnung des zeitlichen Unterschieds funktioniert,
obwohl Master und Slave keine identisch laufenden Uhren
haben (der Unterschied wird ermittelt, wenn der
Slave-I/O-Thread startet; danach wird davon ausgegangen,
dass der Abstand konstant bleibt).
Seconds_Behind_Master
ist
NULL
(d. h. „unbekannt“),
wenn der Slave-SQL-Thread nicht ausgeführt wird oder wenn
der Slave-I/O-Thread nicht läuft oder nicht mit dem
Master verbunden ist. Schläft beispielsweise der
Slave-I/O-Thread für die mit der Option
--master-connect-retry
angegebene Anzahl
von Sekunden, bevor er eine Wiederverbindung versucht,
dann wird NULL
angezeigt, weil der
Slave nicht wissen kann, was der Master tut, und deswegen
auch nicht zuverlässig weiß, wie spät es ist.
Dieses Feld hat eine Einschränkung: Der Zeitstempel wird
bei der Replikation beibehalten, d. h., wenn ein Master
M1 seinerseits ein Slave von M0 ist, dann hat jedes
Ereignis im Binärlog von M1, das der Replikation eines
Ereignisses aus dem Binärlog von M0 entstammt, auch den
Zeitstempel dieses Ereignisses. Dies erlaubt MySQL die
erfolgreiche Replikation von TIMESTAMP
.
Der Nachteil für Seconds_Behind_Master
besteht allerdings darin, dass, wenn M1 auch direkte
Updates von Clients erhält, der Wert wahllos abweicht,
weil das letzte Ereignis auf M1 mal von M0 stammt, mal
aber auch der letzte Zeitstempel eines direkten Updates
ist.
START SLAVE [thread_type
[,thread_type
] ... ] START SLAVE [SQL_THREAD] UNTIL MASTER_LOG_FILE = 'log_name
', MASTER_LOG_POS =log_pos
START SLAVE [SQL_THREAD] UNTIL RELAY_LOG_FILE = 'log_name
', RELAY_LOG_POS =log_pos
thread_type
: IO_THREAD | SQL_THREAD
START SLAVE
startet beide Slave-Threads.
Der I/O-Thread liest Abfragen vom Master-Server und speichert
sie im Relay-Log. Der SQL-Thread liest das Relay-Log und
führt die Abfragen aus. START SLAVE
erfordert die Berechtigung SUPER
.
Wenn START SLAVE
die Slave-Threads
erfolgreich startet, wird kein Fehler zurückgegeben.
Allerdings kann es auch in diesem Fall vorkommen, dass die
Slave-Threads starten und kurz darauf wieder beendet werden
(etwa weil sie keine Verbindung zum Master herstellen oder die
Binärlogs nicht lesen konnten oder aus einem anderen Grund).
START SLAVE
warnt Sie davor nicht. Sie
müssen das Fehlerlog des Slaves auf Fehlermeldungen prüfen,
die von den Slave-Threads erzeugt wurden, oder sich mit
SHOW SLAVE STATUS
vergewissern, dass sie
einwandfrei ausgeführt werden.
Sie können die Optionen IO_THREAD
oder
SQL_THREAD
zur Anweisung hinzufügen, wenn
Sie angeben wollen, welcher der Threads gestartet werden soll.
Eine UNTIL
-Klausel kann hinzugefügt
werden, um anzugeben, dass der Slave starten und laufen soll,
bis der SQL-Thread einen gegebenen Punkt im Master-Binärlog
oder den Slave-Relay-Logs erreicht. Wenn der SQL-Thread diesen
Punkt erreicht, wird er beendet. Wird die Option
SQL_THREAD
in der Anweisung angegeben, dann
startet nur der SQL-Thread. Andernfalls werden beide
Slave-Threads gestartet. Läuft der SQL-Thread bereits, dann
wird die Klausel UNTIL
ignoriert, und eine
Warnung wird ausgegeben.
Für eine UNTIL
-Klausel müssen Sie sowohl
einen Logdateinamen als auch eine Position angeben. Vermischen
Sie die Optionen für Master- und Relay-Logs nicht.
Eine UNTIL
-Bedingung wird von einer
nachfolgenden STOP SLAVE
-Anweisung, einer
START SLAVE
-Anweisung ohne
UNTIL
-Klausel oder einem Serverneustart
zurückgesetzt.
Die UNTIL
-Klausel kann nützlich sein, um
die Replikation zu debuggen oder festzulegen, dass die
Replikation bis genau zu dem Punkt fortfahren soll, an dem ein
Slave eine Anweisung nicht mehr replizieren soll. Wurde
beispielsweise versehentlich eine DROP
TABLE
-Anweisung auf dem Master ausgeführt, dann
können Sie den Slave mit UNTIL
anweisen,
das Log nur bis unmittelbar vor diesem Punkt, aber nicht mehr
weiter auszuführen. Um herauszufinden, was das Ereignis ist,
verwenden Sie mysqlbinlog mit den
Master-Logs oder den Slave-Relay-Logs oder setzen eine
SHOW BINLOG EVENTS
-Anweisung ab.
Wenn Sie UNTIL
verwenden, damit der
Slave-Prozess die Abfragen in Abschnitten repliziert,
empfehlen wir den Start des Slaves mit der Option
--skip-slave-start
, damit der SQL-Thread
nicht ausgeführt wird, wenn der Slave-Server startet. Es ist
wahrscheinlich am besten, diese Option in einer Optionsdatei
statt auf der Befehlszeile zu benutzen, damit die Klausel bei
einem unerwarteten Serverneustart nicht vergessen wird.
Die SHOW SLAVE STATUS
-Anweisung enthält
Ausgabefelder, die die aktuellen Werte der
UNTIL
-Bedingung anzeigen.
In älteren Versionen von MySQL (vor 4.0.5) hieß diese
Anweisung SLAVE START
. Ihre Verwendung in
dieser Form ist zwar in MySQL 5.1 aus
Kompatibilitätsgründen noch akzeptabel, aber veraltet.
STOP SLAVE [thread_type
[,thread_type
] ... ]thread_type
: IO_THREAD | SQL_THREAD
Beendet die Slave-Threads. STOP SLAVE
erfordert die Berechtigung SUPER
.
Wie START SLAVE
kann diese Anweisung mit
den Optionen IO_THREAD
und
SQL_THREAD
verwendet werden, um den oder
die zu beendenden Threads anzugeben.
In älteren Versionen von MySQL (vor 4.0.5) hieß diese
Anweisung SLAVE STOP
. Ihre Verwendung in
dieser Form ist zwar in MySQL 5.1 aus
Kompatibilitätsgründen noch akzeptabel, aber veraltet.
MySQL 5.1 unterstützt serverseitige vorbereitete
Anweisungen. Diese Unterstützung nutzt das effiziente binäre
Client/Server-Protokoll, welches in MySQL 4.1 implementiert wurde.
Voraussetzung hierfür ist, dass Sie eine geeignete
Client-Programmierschnittstelle verwenden. Geeignete
Schnittstellen sind die C-API-Clientbibliothek von MySQL (für
C-Programme), MySQL Connector/J (für Java-Programme) und MySQL
Connector/NET. So bietet etwa die C-API eine Anzahl von
Funktionsaufrufen, die eine API für vorbereitete Anweisungen
darstellen. Siehe auch
Abschnitt 24.2.4, „C-API: Prepared Statements“. Andere
Sprachschnittstellen bieten Unterstützung für vorbereitete
Anweisungen, die das binäre Protokoll verwenden, indem Sie eine
Verbindung in die C-Clientbibliothek herstellen (z. B. die
mysqli
-Erweiterung
in PHP 5.0).
Es gibt auch eine alternative SQL-Schnittstelle für vorbereitete Anweisungen. Diese ist zwar nicht so effizient wie die Verwendung eines binären Protokolls über eine API für vorbereitete Anweisungen, sie erfordert aber auch keine Programmierung, weil sie direkt auf SQL-Ebene verfügbar ist:
Sie können sie verwenden, wenn Ihnen keine Programmierschnittstelle zur Verfügung steht.
Sie können sie aus jedem Programm heraus verwenden, das Ihnen die Übermittlung von SQL-Anweisungen an den Server zur dortigen Ausführung gestattet (dies gilt beispielsweise für das mysql-Clientprogramm).
Sie können es auch dann verwenden, wenn der Client eine alte Version der Clientbibliothek einsetzt. Die einzige Voraussetzung besteht darin, dass Sie eine Verbindung mit einem Server herstellen können müssen, der aktuell genug ist, um die SQL-Syntax für vorbereitete Anweisungen zu unterstützen.
Die SQL-Syntax für vorbereitete Anweisungen ist zur Verwendung in Fällen wie den folgenden vorgesehen:
Sie wollen die Funktion vorbereiteter Anweisungen in Ihrer Anwendung testen, bevor Sie sie einkodieren.
Eine Anwendung hat Probleme mit der Ausführung vorbereiteter Anweisungen, und Sie wollen dem Problem interaktiv auf den Grund gehen.
Sie wollen einen Testfall erstellen, der ein Problem im Zusammenhang mit vorbereiteten Anweisungen beschreibt. Dieser soll als Grundlage eines Fehlerberichts dienen.
Sie müssen vorbereitete Anweisungen verwenden, haben aber keinen Zugang zu einer Programmierschnittstelle, die diese unterstützt.
Die SQL-Syntax für vorbereitete Anweisungen basiert auf drei SQL-Anweisungen:
PREPARE
stmt_name
FROM
preparable_stmt
Die Anweisung PREPARE
bereitet eine
Anweisung vor und weist ihr den Namen
stmt_name
zu, unter dem sie später
referenziert werden kann. Die Groß-/Kleinschreibung wird bei
Anweisungsnamen nicht unterschieden.
preparable_stmt
ist entweder ein
String-Literal oder eine Benutzervariable, die den Text der
Anweisung enthält. Der Text muss eine einzelne SQL-Anweisung
(nicht mehrere Anweisungen) darstellen. In dieser Anweisung
können Fragezeichen (‘?
’) als
Parameterkennzeichen verwendet werden: Sie geben an, wo bei
der späteren Ausführung der Anweisung Datenwerte eingebunden
werden. Fragezeichen sollten auch dann nicht in
Anführungszeichen gesetzt werden, wenn Sie beabsichtigen, sie
an String-Werte anzubinden. Parameterkennzeichen dürfen nur
an Stellen verwendet werden, an denen Datenwerte eingefügt
werden sollen, nicht jedoch für SQL-Schlüsselwörter,
Bezeichner usw.
Wenn eine vorbereitete Anweisung des angegebenen Namens bereits vorhanden ist, wird diese Namenszuweisung implizit aufgehoben, bevor die neue Anweisung vorbereitet wird. Das bedeutet, dass, wenn die neue Anweisung einen Fehler enthält und nicht vorbereitet werden kann, ein Fehler zurückgegeben wird; in diesem Fall gibt es keine Anweisung des betreffenden Namens mehr.
Der Gültigkeitsbereich einer vorbereiteten Anweisung ist die Clientsitzung, innerhalb derer sie erstellt wird. Andere Clients sehen sie nicht.
EXECUTE
stmt_name
[USING
@var_name
[,
@var_name
] ...]
Nach der Vorbereitung einer Anweisung können Sie sie mit
einer EXECUTE
-Anweisung ausführen, die den
Namen der vorbereiteten Anweisung referenziert. Wenn die
vorbereitete Anweisung Parameterkennzeichen enthält, müssen
Sie eine USING
-Klausel angeben, die die
Benutzervariablen mit den Werten auflistet, welche für die
Parameter eingesetzt werden sollen. Parameterwerte können nur
über Benutzervariablen übergeben werden. Die
USING
-Klausel muss so viele Variablen
übergeben, wie Parameterkennzeichen in der Anweisung
vorhanden sind, und alle Variablennamen müssen korrekt sein.
Sie können eine vorbereitete Anweisung mehrfach ausführen und dabei unterschiedliche Variablen übergeben oder die Variablen vor jeder Ausführung auf andere Werte setzen.
{DEALLOCATE | DROP} PREPARE
stmt_name
Um eine vorbereitete Anweisung aufzuheben, verwenden Sie die
Anweisung DEALLOCATE PREPARE
. Wenn Sie eine
vorbereitete Anweisung auszuführen versuchen, nachdem Sie sie
aufgehoben haben, wird ein Fehler erzeugt.
Wenn Sie eine Clientsitzung beenden, ohne eine zuvor vorbereitete Anweisung aufzuheben, dann hebt der Server sie automatisch auf.
In vorbereiteten Anweisungen können die folgenden SQL-Anweisungen
verwendet werden: CREATE TABLE
,
DELETE
, DO
,
INSERT
, REPLACE
,
SELECT
, SET
,
UPDATE
und die meisten
SHOW
-Anweisungen. Andere Anweisungen werden
noch nicht unterstützt.
Die folgenden Beispiele zeigen zwei gleichwertige Arten der Vorbereitung einer Anweisung, die die Hypotenuse eines Dreiecks berechnet, bei dem zwei Seitenlängen gegeben sind.
Das erste Beispiel zeigt, wie man eine vorbereitete Anweisung unter Verwendung eines String-Literals erstellt, um den Text der Anweisung zu übergeben:
mysql>PREPARE stmt1 FROM 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql>SET @a = 3;
mysql>SET @b = 4;
mysql>EXECUTE stmt1 USING @a, @b;
+------------+ | hypotenuse | +------------+ | 5 | +------------+ mysql>DEALLOCATE PREPARE stmt1;
Das zweite Beispiel ist ähnlich, übergibt den Text der Anweisung aber als Benutzervariable:
mysql>SET @s = 'SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse';
mysql>PREPARE stmt2 FROM @s;
mysql>SET @a = 6;
mysql>SET @b = 8;
mysql>EXECUTE stmt2 USING @a, @b;
+------------+ | hypotenuse | +------------+ | 10 | +------------+ mysql>DEALLOCATE PREPARE stmt2;
Die SQL-Syntax für vorbereitete Anweisungen erlaubt keine
Verschachtelungen: Eine an PREPARE
übergebene
Anweisung darf selbst keine PREPARE
-,
EXECUTE
- oder DEALLOCATE
PREPARE
-Anweisung sein.
Die SQL-Syntax für vorbereitete Anweisungen unterscheidet sich
von der Verwendung von API-Aufrufen für vorbereitete Anweisungen.
So können Sie beispielsweise mit der C-API-Funktion
mysql_stmt_prepare()
keine
PREPARE
-, EXECUTE
- oder
DEALLOCATE PREPARE
-Anweisung vorbereiten.
Die SQL-Syntax für vorbereitete Anweisungen kann in gespeicherten Prozeduren, nicht aber in gespeicherten Funktionen oder Triggern verwendet werden.
Bei der Verwendung vorbereiteter Anweisungen können für die
Argumente der LIMIT
-Klausel Platzhalter
eingesetzt werden. Siehe auch Abschnitt 13.2.7, „SELECT
“.
Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.