Kapitel 7. MySQL-Sprachreferenz

Inhaltsverzeichnis

7.1. Sprachstruktur
7.1.1. Literale: Wie Zeichenketten und Zahlen geschrieben werden
7.1.2. Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen
7.1.3. Groß-/Kleinschreibung in Namen
7.1.4. Benutzer-Variablen
7.1.5. Kommentar-Syntax
7.1.6. Ist MySQL pingelig hinsichtlich reservierter Wörter?
7.2. Spaltentypen
7.2.1. Numerische Typen
7.2.2. Datums- und Zeit-Typen
7.2.3. Zeichenketten-Typen
7.2.4. Den richtigen Typ für eine Spalte auswählen
7.2.5. Spaltentypen anderer Datenbanken benutzen
7.2.6. Speicherbedarf von Spaltentypen
7.3. Funktionen für die Benutzung in SELECT- und WHERE-Klauseln
7.3.1. Nicht typenspezifische Operatoren und Funktionen
7.3.2. Zeichenketten-Funktionen
7.3.3. Numerische Funktionen
7.3.4. Datums- und Zeit-Funktionen
7.3.5. Weitere Funktionen
7.3.6. Funktionen zur Benutzung bei GROUP BY-Klauseln
7.4. Datenmanipulation: SELECT, INSERT, UPDATE, DELETE
7.4.1. SELECT-Syntax
7.4.2. INSERT-Syntax
7.4.3. HANDLER-Syntax
7.4.4. INSERT DELAYED-Syntax
7.4.5. UPDATE-Syntax
7.4.6. DELETE-Syntax
7.4.7. TRUNCATE-Syntax
7.4.8. REPLACE-Syntax
7.4.9. LOAD DATA INFILE-Syntax
7.5. Datendefinition: CREATE, DROP, ALTER
7.5.1. CREATE DATABASE-Syntax
7.5.2. DROP DATABASE-Syntax
7.5.3. CREATE TABLE-Syntax
7.5.4. ALTER TABLE-Syntax
7.5.5. RENAME TABLE-Syntax
7.5.6. DROP TABLE-Syntax
7.5.7. CREATE INDEX-Syntax
7.5.8. DROP INDEX-Syntax
7.6. Grundlegende Befehle des MySQL-Dienstprogramms für Benutzer
7.6.1. USE-Syntax
7.6.2. DESCRIBE-Syntax (Informationen über Spalten erhalten)
7.7. Transaktionale und Sperrbefehle von MySQL
7.7.1. BEGIN/COMMIT/ROLLBACK-Syntax
7.7.2. LOCK TABLES/UNLOCK TABLES-Syntax
7.7.3. SET TRANSACTION-Syntax
7.8. MySQL-Volltextsuche
7.8.1. Volltext-Einschränkungen
7.8.2. MySQL-Volltextsuche fein einstellen
7.8.3. Neue Features der Volltextsuche in MySQL 4.0
7.8.4. Volltextsuche TODO-Liste
7.9. MySQL-Anfragen-Cache
7.9.1. Wie der Anfragen-Cache funktioniert
7.9.2. Anfragen-Cache-Konfiguration
7.9.3. Anfragen-Cache-Optionen in SELECT
7.9.4. Anfragen-Cache-Status und -Wartung

MySQL hat eine sehr komplexe, aber intuitive und leicht zu erlernende SQL-Schnittstelle. Dieses Kapitel beschreibt die verschiedenen Befehle, Typen und Funktionen, die Sie kennen müssen, um MySQL effizient und effektiv zu benutzen. Dieses Kapitel dient auch als Referenz für die gesamte in MySQL beinhaltete Funktionalität. Um dieses Kapitel effektiv zu nutzen, sollten Sie unter den verschiedenen Stichworten nachschlagen.

7.1. Sprachstruktur

7.1.1. Literale: Wie Zeichenketten und Zahlen geschrieben werden

Dieser Abschnitt beschreibt die verschiedenen Arten, in MySQL Zeichenketten und Zahlen zu schreiben. Ebenfalls enthalten sind die verschiedenen Nuancen und Fallstricke, in denen man sich bei den grundlegenden Datentypen von MySQL verfangen kann.

7.1.1.1. Zeichenketten

Eine Zeichenkette ist eine Folge von Zeichen, die entweder von Apostrophs (einfachen Anführungszeichen, ‘'’) oder (doppelten) Anführungszeichen (‘"’) umgeben ist (nur einfache Anführungszeichen, wenn Sie MySQL im ANSI-Modus laufen lassen). Beispiele:

'eine Zeichenkette'
"eine weitere Zeichenkette"

Innerhalb einer Zeichenkette haben bestimmte Folgen eine spezielle Bedeutung. Jede dieser Folgen fängt mit einem Backslash (‘\’) an, bekannt als Fluchtzeichen (Escape-Zeichen). MySQL erkennt folgende Flucht-Folgen (Escape-Folgen):

  • \0

    Ein ASCII-0- (NUL) Zeichen.

  • \'

    Ein Apostroph- (‘'’) Zeichen.

  • \"

    Ein Anführungszeichen (‘"’).

  • \b

    Ein Rückschritt- (Backspace-) Zeichen.

  • \n

    Ein Neue-Zeile- (Newline-) Zeichen.

  • \r

    Ein Wagenrücklauf- (carriage return) Zeichen.

  • \t

    Ein Tabulator-Zeichen.

  • \z

    ASCII(26) (Steuerung-Z). Dieses Zeichen kann kodiert werden, um das Problem zu umgehen, dass ASCII(26) unter Windows für Dateiende (END-OF-FILE) steht. (ASCII(26) verursacht Probleme, wenn Sie mysql Datenbank < Dateiname benutzen.)

  • \\

    Ein Backslash- (‘\’) Zeichen.

  • \%

    Ein ‘%’-Zeichen. Dieses wird benutzt, um nach literalen Instanzen von ‘%’ in Zusammenhängen zu suchen, wo ‘%’ ansonsten als Platzhalterzeichen interpretiert werden würde. See Abschnitt 7.3.2.1, „Zeichenketten-Vergleichsfunktionen“.

  • \_

    Ein ‘_’-Zeichen. Dieses wird benutzt, um nach literalen Instanzen von ‘_’ in Zusammenhängen zu suchen, wo ‘_’ ansonsten als Platzhalterzeichen interpretiert werden würde. See Abschnitt 7.3.2.1, „Zeichenketten-Vergleichsfunktionen“.

Beachten Sie, dass bei der Benutzung von ‘\%’ oder ‘\_’ in einigen Zeichenketten-Zusammenhängen diese die Zeichenketten ‘\%’ und ‘\_’ und nicht ‘%’ und ‘_’ zurückgeben.

Es gibt verschiedene Möglichkeiten, Anführungszeichen innerhalb einer Zeichenkette zu schreiben:

  • Ein ‘'’ innerhalb einer Zeichenkette, die mit ‘'’ begrenzt wird, kann als ‘''’ geschrieben werden.

  • Ein ‘"’ innerhalb einer Zeichenkette, die ‘"’ begrenzt wird, kann als ‘""’ geschrieben werden.

  • Sie können dem Anführungszeichen ein Fluchtzeichen (Escape-Zeichen) (‘\’) voranstellen.

  • Ein ‘'’ innerhalb einer Zeichenkette, die mit ‘"’ begrenzt wird, braucht keine spezielle Behandlung und muss nicht verdoppelt oder escapet werden. In gleicher Weise benötigt ‘"’ innerhalb einer Zeichenkette, die mit ‘'’ begrenzt wird, keine spezielle Behandlung.

Die unten stehenden SELECT-Statements zeigen, wie Quoten und Escapen funktionieren:

mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "Das\nsind\nvier\nZeilen";
+--------------------+
| Das
sind
vier
Zeilen |
+--------------------+

Wenn Sie Binärdaten in eine BLOB-Spalte einfügen, müssen folgende Zeichen durch Flucht-Folgen repräsentiert werden:

  • NUL

    ASCII 0. Dieses geben Sie als ‘\0’ ein (ein Backslash und ein ASCII-‘0’-Zeichen).

  • \

    ASCII 92, Backslash. Das geben Sie als ‘\\’ ein.

  • '

    ASCII 39, Apostroph. Das geben Sie als ‘\'’ ein.

  • "

    ASCII 34, Anführungszeichen. Das geben Sie als ‘\"’ ein.

Wenn Sie C-Code schreiben, können Sie die C-API-Funktion mysql_escape_string() für Fluchtzeichen (Escape-Zeichen) für das INSERT-Statement benutzen. See Abschnitt 9.4.2, „C-API-Funktionsüberblick“. In Perl können Sie die quote-Methode des DBI-Pakets benutzen, um Sonderzeichen in die korrekten Flucht-Folgen umzuwandeln. See Abschnitt 9.2.2, „Die DBI-Schnittstelle“.

Sie sollten auf jede Zeichenkette, die eins der oben erwähnten Sonderzeichen enthalten könnte, eine der Flucht-Funktionen anwenden!

7.1.1.2. Zahlen

Ganzzahlen werden als Folge von Ziffern repräsentiert. Fließkommazahlen benutzen ‘.’ als Dezimalseparator. Jedem Zahlentyp kann ‘-’ vorangestellt werden, um einen negativen Wert anzuzeigen.

Beispiele gültiger Ganzzahlen:

1221
0
-32

Beispiele gültiger Fließkommazahlen:

294.42
-32032.6809e+10
148.00

Eine Ganzzahl kann in einem Fließkomma-Zusammenhang benutzt werden, sie wird dann als die äquivalente Fließkommazahl interpretiert.

7.1.1.3. Hexadezimale Werte

MySQL unterstützt hexadezimale Werte. In Zahlen-Zusammenhängen funktionieren diese wie eine Ganzzahl (64-Bit-Genauigkeit). Im Zeichenketten-Zusammenhang funktionieren sie wie eine binäre Zeichenkette, wobei jedes Paar hexadezimaler Ziffern in ein Zeichen umgewandelt wird:

mysql> SELECT x'FF'
       -> 255
mysql> SELECT 0xa+0;
       -> 10
mysql> select 0x5061756c;
       -> Paul

Die x'hexadezimale_zeichenkette'-Syntax (neu in Version 4.0) basiert auf ANSI-SQL. Die 0x-Syntax basiert auf ODBC. Hexadezimale Zeichenketten werden oft von ODBC benutzt, um Werte für BLOB-Spalten anzugeben.

7.1.1.4. NULL-Werte

Der NULL-Wert bedeutet ``keine Daten'' und unterscheidet sich von Werten wie 0 bei numerischen Typen oder der leeren Zeichenkette bei Zeichenkettentypen. See Abschnitt A.5.3, „Probleme mit NULL-Werten“.

NULL kann durch \N repräsentiert werden, wenn Sie die Textdatei-Import- oder Exportformate (LOAD DATA INFILE, SELECT ... INTO OUTFILE) benutzen. See Abschnitt 7.4.9, „LOAD DATA INFILE-Syntax“.

7.1.2. Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen

Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen folgen in MySQL alle denselben Regeln.

Beachten Sie, dass sich die Regeln ab MySQL-Version 3.23.6 geändert haben, als das Quoten von Bezeichnern (für Datenbank-, Tabellen- und Spaltennamen) eingeführt wurde, mit ‘`’. ‘"’ funktioniert ebenfalls, um Bezeichner zu quoten, wenn Sie im ANSI-Modus fahren. See Abschnitt 2.7.2, „MySQL im ANSI-Modus laufen lassen“.

BezeichnerMaximale LängeErlaubte Zeichen
Datenbank64Jedes Zeichen, dass für ein Verzeichnis erlaubt ist, ausser ‘/’ oder ‘.’.
Tabelle64Jedes Zeichen, dass für einen Dateinamen erlaubt ist, ausser ‘/’ oder ‘.’.
Spalte64Alle Zeichen.
Alias255Alle Zeichen.

Hinzuzufügen ist, dass Sie ASCII(0), ASCII(255) oder das Quote-Zeichen in einem Bezeichner nicht verwenden dürfen.

Beachten Sie, dass, falls der Bezeichner ein reserviertes Wort ist oder Sonderzeichen enthält, er bei der Benutzung immer in ` angegeben sein muss:

SELECT * from `select` where `select`.id > 100;

In vorherigen Versionen von MySQL sind die Namensregeln wie folgt:

  • Ein Name muss aus alphanumerischen Zeichen des aktuellen Zeichensatzes bestehen und darf darüber hinaus ‘_’ und ‘$’ enthalten. Der vorgabemäßige Zeichensatz ist ISO-8859-1 Latin1; dass kann durch die --default-character-set-Option für mysqld geändert werden. See Abschnitt 5.6.1, „Der für Daten und Sortieren benutzte Zeichensatz“.

  • Ein Name kann mit jedem Zeichen anfangen, das in einem Namen erlaubt ist. Insbesondere kann ein Name auch mit einer Zahl anfangen (das ist in vielen anderen Datenbanksystemen anders!). Jedoch kann ein Namen nicht nur aus Zahlen bestehen.

  • Sie können das ‘.’-Zeichen in Namen nicht benutzen, weil es benutzt wird, um das Format zu erweitern, mit dem man auf Spalten verweisen kann (siehe unten).

Es wird empfohlen, dass Sie keine Namen wie 1e verwenden, weil ein Ausdruck wie 1e+1 mehrdeutig ist. Er kann als der Ausdruck 1e + 1 oder als die Zahl 1e+1 interpretiert werden.

In MySQL können Sie in folgender Form auf Spalten verweisen:

SpaltenverweisBedeutung
spalten_nameSpalte des Namens spalten_name einer beliebigen, in der Anfrage verwendeten Tabelle.
tabelle.spalten_nameSpalte des Namens spalten_name der Tabelle tabelle der aktuellen Datenbank.
datenbank.tabelle.spalten_nameSpalte des Namens spalten_name der Tabelle tabelle der Datenbank datenbank. Diese Form ist ab MySQL-Version 3.22 verfügbar.
`spalte`Eine Spalte, die ein reserviertes Wort ist oder Sonderzeichen enthält.

Das tabelle- oder datenbank.tabelle-Präfix müssen Sie bei einem Spaltenverweis in einem Statement nicht angeben, es sei denn, der Verweis wäre ansonsten doppeldeutig. Nehmen Sie zum Beispiel an, die Tabellen t1 und t2 enthielten beide jeweils eine Spalte c und Sie verweisen auf c in einem SELECT-Statement, das sowohl t1 als auch t2 benutzt. In diesem Fall ist c mehrdeutig, weil es innerhalb der im Statement benutzten Tabellen nicht eindeutig ist. Daher müssen Sie angeben, welche Tabelle Sie meinen, indem Sie t1.c oder t2.c schreiben. Ähnliches gilt, wenn Sie aus einer Tabelle t in Datenbank datenbank1 und von eine Tabelle t in Datenbank datenbank2 abrufen. Dann müssen Sie auf Spalten in diesen Tabellen als datenbank1.t.spalten_name und datenbank2.t.spalten_name verweisen.

Die Syntax .tabelle bedeutet die Tabelle tabelle in der aktuellen Datenbank. Diese Syntax wird aus Gründen der ODBC-Kompatibilität akzeptiert, weil einige ODBC-Programme Tabellenname ein ‘.’-Zeichen voranstellen.

7.1.3. Groß-/Kleinschreibung in Namen

In MySQL entsprechen Datenbanken und Tabellen Verzeichnissen und Dateien innerhalb dieser Verzeichnisse. Folglich hängt die Groß-/Kleinschreibung davon ab, wie das zugrunde liegende Betriebssystem die Groß-/Kleinschreibung von Datenbank- und Tabellennamen festlegt. Das bedeutet, dass Datenbank- und Tabellennamen unter Unix von der Groß-/Kleinschreibung abhängen und unter Windows nicht. See Abschnitt 2.7.3, „MySQL-Erweiterungen zu ANSI SQL92“.

HINWEIS: Obwohl die Groß-/Kleinschreibung für Datenbank- und Tabellennamen unter Windows keine Rolle spielt, sollten Sie nicht auf eine angegebene Datenbank oder Tabelle innerhalb derselben Anfrage mit unterschiedlicher Schreibweise verweisen. Folgende Anfrage würde nicht funktionieren, weil sie auf eine Tabelle sowohl mit meine_tabelle als auch mit MEINE_TABELLE verweist:

mysql> SELECT * FROM meine_tabelle WHERE MEINE_TABELLE.spalte=1;

Spaltennamen hängen in keinem Fall von der verwendeten Groß-/Kleinschreibung ab.

Aliase auf Tabellen hängen von der Groß-/Kleinschreibung ab. Folgende Anfrage würde nicht funktionieren, weil sie auf den Alias sowohl mit a als auch mit A verweist:

mysql> SELECT spalten_name FROM tabelle AS a
           WHERE a.spalten_name = 1 OR A.spalten_name = 2;

Aliase auf Spalten hängen nicht von der verwendeten Groß-/Kleinschreibung ab.

Wenn Sie Probleme damit haben, sich an die Schreibweise von Tabellennamen zu erinnern, halten Sie sich an eine durchgehende Konvention. Benutzen Sie zum Beispiel bei der Erzeugung von Datenbanken und Tabellen Kleinschreibung in Namen.

Eine Möglichkeit, dieses Problem zu vermeiden, ist, mysqld mit -O lower_case_tabelles=1 zu starten. Vorgabemäßig ist diese Option 1 unter Windows und 0 unter Unix.

Wenn lower_case_tabelles 1 ist, wandelt MySQL alle Tabellennamen in Kleinschreibung um, sowohl beim Speichern als auch beim Nachschlagen. Wenn Sie diese Option ändern, beachten Sie, dass Sie zuerst Ihre alten Tabellennamen in Kleinschreibung umwandeln müssen, bevor Sie mysqld starten.

7.1.4. Benutzer-Variablen

MySQL unterstützt Thread-spezifische Variablen mit der @variablename-Syntax. Eine Variable kann aus alphanumerischen Zeichen des aktuellen Zeichensatzes sowie aus ‘_’, ‘$’ und ‘.’ bestehen. Der vorgabemäßige Zeichensatz ist ISO-8859-1 Latin1; das kann mit der --default-character-set-Option für mysqld geändert werden. See Abschnitt 5.6.1, „Der für Daten und Sortieren benutzte Zeichensatz“.

Variablen müssen nicht initialisiert werden. Sie enthalten vorgabemäßig NULL und können Ganzzahl-, Real- oder Zeichenketten-Werte speichern. Alle Variablen für einen Thread werden automatisch freigegeben, wenn der Thread beendet wird.

Sie können eine Variable mit der SET-Syntax setzen:

SET @variable= { ganzzahl_ausdruck | realzahl_ausdruck | zeichenketten_ausdruck } [,@variable= ...].

Sie können eine Variable in einem Ausdruck auch mit der @variable:=expr-Syntax setzen:

select @t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+
| @t1:=(@t2:=1)+@t3:=4 | @t1  | @t2  | @t3  |
+----------------------+------+------+------+
|                    5 |    5 |    1 |    4 |
+----------------------+------+------+------+

(Wir mussten hier die :=-Syntax benutzen, weil = für Vergleiche reserviert ist.)

Benutzer-Variablen können benutzt werden, wo Ausdrücke erlaubt sind. Beachten Sie, dass das momentan keine Zusammenhänge einschließt, in denen explizit Zahlen erforderlich sind, wie in der LIMIT-Klausel eines SELECT-Statements oder der IGNORE Anzahl LINES-Klausel eines LOAD DATA-Statements.

HINWEIS: In einem SELECT-Statement wird jeder Ausdruck erst dann ausgewertet, wenn er an den Client geschickt wird. Das heißt, dass Sie in der HAVING-, GROUP BY- oder ORDER BY-Klausel nicht auf einen Ausdruck verweisen können, der Variablen beinhaltet, die nicht im SELECT-Teil gesetzt wurden. Folgendes Statement zum Beispiel funktioniert erwartungsgemäß NICHT:

SELECT (@aa:=id) AS a, (@aa+3) AS b FROM tabelle HAVING b=5;

Der Grund ist, dass @aa nicht den Wert der aktuellen Zeile enthält, sondern den Wert von id der vorher akzeptierten Zeile.

7.1.5. Kommentar-Syntax

Der MySQL-Server die Kommentar-Stile # bis Zeilenende, -- bis Zeilenende und /* mittendrin oder mehrzeilig */:

mysql> select 1+1;     # Dieser Kommentar geht bis zum Zeilenende
mysql> select 1+1;     -- Dieser Kommentar geht bis zum Zeilenende
mysql> select 1 /* Das ist ein Kommentar mittendrin */ + 1;
mysql> select 1+
/*
Das ist ein
mehrzeiliger
Kommentar
*/
1;

Beachten Sie, dass Sie beim Kommentarstil -- mindestens ein Leerzeichen hinter -- setzen müssen!

Obwohl der Server die Kommentar-Syntax wie beschrieben versteht, gibt es einige Einschränkungen in der Art, wie der mysql-Client /* ... */-Kommentare parst:

  • Einfache und doppelte Anführungszeichen werden genommen, um den Anfang einer Zeichenkette zu bestimmen, selbst innerhalb eines Kommentars. Wenn die Zeichenkette nicht durch ein zweites Anführungszeichen innerhalb des Kommentars abgeschlossen wird, bemerkt der Parser nicht, dass der Kommentar zuende ist. Wenn Sie mysql interaktiv ausführen, sehen Sie, dass mysql verwirrt ist, weil sich die Eingabeaufforderung von mysql> zu to '> oder "> ändert.

  • Ein Semikolon wird genommen, um das Ende des aktuellen SQL-Statements kenntlich zu machen. Alles Folgende wird als Anfang des nächsten Statements aufgefasst.

Diese Einschränkungen gelten sowohl, wenn Sie mysql interaktiv ausführen und wenn Sie Befehle in eine Datei schreiben und mysql mit mysql < some-file anweisen, seine Eingaben aus dieser Datei zu lesen.

MySQL unterstützt nicht den ANSI-SQL-Kommentarstil '--' ohne nachfolgendes Leerzeichen. See Abschnitt 2.7.4.8, „'--' als Beginn eines Kommentars“.

7.1.6. Ist MySQL pingelig hinsichtlich reservierter Wörter?

Ein häufiges Problem rührt daher, dass versucht wird, eine Tabelle mit Spaltennamen zu erzeugen, den die Namen von Datentypen oder in MySQL eingebauten Funktionen entsprechen, wie TIMESTAMP oder GROUP. Sie dürfen das tun (beispielsweise ist ABS ein zulässiger Spaltenname), aber es sind dann keine Leerzeichen zwischen einem Funktionsname und der ‘(’ erlaubt, wenn Sie Funktionen benutzen, deren Namen auch Spaltennamen sind.

Folgende Wörter sind in MySQL explizit reserviert. Die meisten davon sind in ANSI-SQL92 als Spalten- und / oder Tabellennamen verboten (zum Beispiel group). Einige wenige sind reserviert, weil MySQL sie benötigt und (momentan) einen yacc-Parser benutzt:

actionaddaggregateall
alterafterandas
ascavgavg_row_lengthauto_increment
betweenbigintbitbinary
blobboolbothby
cascadecasecharcharacter
changecheckchecksumcolumn
columnscommentconstraintcreate
crosscurrent_datecurrent_timecurrent_timestamp
datadatabasedatabasesdate
datetimedayday_hourday_minute
day_seconddayofmonthdayofweekdayofyear
decdecimaldefaultdelayed
delay_key_writedeletedescdescribe
distinctdistinctrowdoubledrop
endelseescapeescaped
enclosedenumexplainexists
fieldsfilefirstfloat
float4float8flushforeign
fromforfullFunktion
globalgrantgrantsgroup
havingheaphigh_priorityhour
hour_minutehour_secondhostsidentified
ignoreinindexinfile
innerinsertinsert_idint
integerintervalint1int2
int3int4int8into
ifisisamjoin
keykeyskilllast_insert_id
leadingleftlengthlike
lineslimitloadlocal
locklogslonglongblob
longtextlow_prioritymaxmax_rows
matchmediumblobmediumtextmediumint
middleintmin_rowsminuteminute_second
modifymonthmonthnamemyisam
naturalnumericnonot
nullonoptimizeoption
optionallyororderouter
outfilepack_keyspartialpassword
precisionprimaryprocedureprocess
processlistprivilegesreadreal
referencesreloadregexprename
replacerestrictreturnsrevoke
rlikerowrowssecond
selectsetshowshutdown
smallintsonamesql_big_tablessql_big_selects
sql_low_priority_updatessql_log_offsql_log_updatesql_select_limit
sql_small_resultsql_big_resultsql_warningsstraight_join
startingstatusstringtable
tablestemporaryterminatedtext
thentimetimestamptinyblob
tinytexttinyinttrailingto
typeuseusingunique
unlockunsignedupdateusage
valuesvarcharvariablesvarying
varbinarymitwritewhen
whereyearyear_monthzerofill

Folgende Symbole (aus der obigen Tabelle) sind von ANSI-SQL verboten, aber von MySQL als Spalten- und Tabellennamen zugelassen. Der Grund ist, dass einige davon sehr natürliche Namen sind und viele Leute diese bereits in Benutzung haben.

  • ACTION

  • BIT

  • DATE

  • ENUM

  • NO

  • TEXT

  • TIME

  • TIMESTAMP

7.2. Spaltentypen

MySQL unterstützt eine Reihe von Spaltentypen, die in drei Kategorien eingeteilt werden können: numerische Typen, Datums- und Zeit-Typen und Zeichenketten-Typen. Dieser Abschnitt gibt zuerst einen Überblick über die verfügbaren Typen und fasst den Speicherbedarf jedes Spaltentyps zusammen. Danach folgt eine detaillierter Beschreibung der Eigenschaften der Typen jeder Kategorie. Die detailliertere Beschreibung sollte wegen zusätzlicher Informationen über bestimmte Spaltentypen herangezogen werden, wie zu den erlaubten Formaten, in denen Sie Werte festlegen können.

Die von MySQL unterstützten Spaltentypen sind unten aufgeführt. Folgende Code-Buchstaben werden in der Beschreibung benutzt:

  • M

    Gibt die maximale Anzeigebreite an. Die größte erlaubte Anzeigebreite ist 255.

  • D

    Trifft auf Fließkomma-Typen zu und bezeichnet die Anzahl von Ziffern nach dem Dezimalpunkt. Der größte mögliche Wert ist 30, aber er sollte nicht größer sein als M-2.

Eckige Klammern (‘[’ und ‘]’) geben Teile der Typ-Festlegung an, die optional sind.

Wenn Sie ZEROFILL für eine Spalte angeben, beachten Sie, dass MySQL der Spalte automatisch ein UNSIGNED-Attribut hinzufügt.

  • TINYINT[(M)] [UNSIGNED] [ZEROFILL]

    Eine sehr kleine Ganzzahl. Der vorzeichenbehaftete Bereich ist -128 bis 127. Der vorzeichenlose Bereich ist 0 to 255.

  • SMALLINT[(M)] [UNSIGNED] [ZEROFILL]

    Eine kleine Ganzzahl. Der vorzeichenbehaftete Bereich ist -32768 bis 32767. Der vorzeichenlose Bereich ist 0 bis 65535.

  • MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]

    A Ganzzahl mittlerer Größe. Der vorzeichenbehaftete Bereich ist -8388608 bis 8388607. Der vorzeichenlose Bereich ist 0 bis 16777215.

  • INT[(M)] [UNSIGNED] [ZEROFILL]

    Eine Ganzzahl normaler Größe. Der vorzeichenbehaftete Bereich ist -2147483648 bis 2147483647. Der vorzeichenlose Bereich ist 0 bis 4294967295.

  • INTEGER[(M)] [UNSIGNED] [ZEROFILL]

    Ein Synonym für INT.

  • BIGINT[(M)] [UNSIGNED] [ZEROFILL]

    Eine große Ganzzahl. Der vorzeichenbehaftete Bereich ist -9223372036854775808 bis 9223372036854775807. Der vorzeichenlose Bereich ist 0 bis 18446744073709551615.

    Einiger Dinge sollten Sie sich bei BIGINT-Spalten bewusst sein:

    • Weil alle arithmetischen Berechnungen mit vorzeichenbehafteten BIGINT- oder DOUBLE-Werten durchgeführt werden, sollten Sie keine vorzeichenlosen Ganzzahlen größer als 9223372036854775807 (63 Bits) benutzen, ausser bei Bit-Funktionen! Wenn Sie das doch tun, können einige der letzten Ziffern im Ergebnis falsch sein, weil Rundungsfehler beim Umwandeln von BIGINT in DOUBLE auftreten.

      MySQL 4.0 kann BIGINT in folgenden Fällen handhaben:

      • Benutzen Sie Ganzzahlen, um große vorzeichenlose Wert in einer BIGINT-Spalte zu speichern.

      • Bei MIN(große_ganzzahl_spalte) und MAX(große_ganzzahl_spalte).

      • Bei der Benutzung der Operatoren (+, -, * usw.), wenn beide Operanden Ganzzahlen sind.

    • Sie können immer einen genauen Ganzzahlwert in einer BIGINT-Spalte speichern, wenn Sie sie als Zeichenkette speichern, denn in diesem Fall wird diese nicht zwischendurch als Double dargestellt.

    • -’, ‘+’ und ‘*’ benutzen arithmetische BIGINT-Berechnungen, wenn beide Argumente INTEGER-Werte sind! Das heißt, wenn Sie zwei Ganzzahlen multiplizieren (oder Ergebnisse von Funktionen, die Ganzzahlen zurückgeben), erhalten Sie vielleicht unerwartete Ergebnisse, wenn das Ergebnis größer als 9223372036854775807 ist.

  • FLOAT(genauigkeit) [ZEROFILL]

    Eine Fließkommazahl. Kann nicht vorzeichenlos sein. genauigkeit ist <=24 bei einer Fließkommazahl einfacher Genauigkeit und zwischen 25 und 53 bei einer Fließkommazahl doppelter Genauigkeit. Diese Typen sind wie die unten beschriebenen FLOAT und DOUBLE-Typen. FLOAT(X) hat denselben Wertebereich wie die entsprechenden FLOAT- und DOUBLE-Typen, jedoch ist die Anzeigebreite und die Anzahl der Dezimalstellen undefiniert.

    In MySQL-Version 3.23 ist das ein echter Fließkommawert. In früheren MySQL-Versionen hat FLOAT(genauigkeit) immer 2 Dezimalstellen.

    Beachten Sie, dass bei der Benutzung von FLOAT unerwartete Probleme auftreten können, weil alle Berechnungen in MySQL mit doppelter Genauigkeit durchgeführt werden. See Abschnitt A.5.6, „Probleme bei keinen übereinstimmenden Zeilen lösen“.

    Diese Syntax steht wegen der ODBC-Kompatibilität zur Verfügung.

  • FLOAT[(M,D)] [ZEROFILL]

    Eine kleine Fließkommazahl (einfacher Genauigkeit). Kann nicht vorzeichenlos sein. Der Wertebereich umfasst -3.402823466E+38 bis -1.175494351E-38, 0 und 1.175494351E-38 bis 3.402823466E+38. M ist die Anzeigebreite und D ist die Anzahl von Dezimalstellen. FLOAT ohne Argument oder mit einem Argument <= 24 steht für eine Fließkommazahl einfacher Genauigkeit.

  • DOUBLE[(M,D)] [ZEROFILL]

    Eine normal große Fließkommazahl (doppelter Genauigkeit). Kann nicht vorzeichenlos sein. Der Wertebereich umfasst -1.7976931348623157E+308 bis -2.2250738585072014E-308, 0 und 2.2250738585072014E-308 bis 1.7976931348623157E+308. M ist die Anzeigebreite und D ist die Anzahl von Dezimalstellen. DOUBLE ohne Argument oder FLOAT(X) mit 25 <= X <= 53 steht für eine Fließkommazahl doppelter Genauigkeit.

  • DOUBLE PRECISION[(M,D)] [ZEROFILL] , REAL[(M,D)] [ZEROFILL]

    Synonyme für DOUBLE.

  • DECIMAL[(M[,D])] [ZEROFILL]

    Eine unkomprimierte Fließkommazahl. Kann nicht vorzeichenlos sein. Verhält sich wie eine CHAR-Spalte: ``Unkomprimiert'' bedeutet, dass die Zahl als Zeichenkette gespeichert wird, wobei ein Zeichen für jede Ziffer des Wertes steht. Der Dezimalpunkt und, bei negativen Zahlen, das ‘-’-Zeichen, werden in M nicht mitgezählt (aber hierfür wird Platz reserviert). Wenn D 0 ist, haben Werte keinen Dezimalpunkt oder Bruchteil. Der maximale Wertebereich von DECIMAL-Werte ist derselbe wie für DOUBLE, aber der tatsächliche Wertebereich einer gegebenen DECIMAL-Spalte kann durch die Auswahl von M und D eingeschränkt sein.

    Wenn D weggelassen wird, wird es auf 0 gesetzt. Wenn M ausgelassen wird, wird es auf 10 gesetzt.

    Beachten Sie, dass in MySQL-Version 3.22 das M-Argument den Platz für das Vorzeichen und den Dezimalpunkt beinhaltete!

  • NUMERIC(M,D) [ZEROFILL]

    Synonym für DECIMAL.

  • DATE

    Ein Datum. Der unterstützte Wertebereich ist '1000-01-01' bis '9999-12-31'. MySQL zeigt DATE-Werte im 'YYYY-MM-DD'-Format an, gestattet jedoch, DATE-Spalten Werte entweder als Zeichenketten oder als Zahlen zuzuweisen. See Abschnitt 7.2.2.2, „Die DATETIME-, DATE- und TIMESTAMP-Typen“.

  • DATETIME

    Eine Datums-/Zeit-Kombination. Der unterstützte Wertebereich ist '1000-01-01 00:00:00' bis '9999-12-31 23:59:59'. MySQL zeigt DATETIME-Werte im 'YYYY-MM-DD HH:MM:SS'-Format an, gestattet jedoch, DATETIME-Spalten Werte entweder als Zeichenketten oder als Zahlen zuzuweisen. See Abschnitt 7.2.2.2, „Die DATETIME-, DATE- und TIMESTAMP-Typen“.

  • TIMESTAMP[(M)]

    Ein Zeitstempel. Der Wertebereich ist '1970-01-01 00:00:00' bis irgendwann im Jahr 2037. MySQL zeigt TIMESTAMP-Werte im YYYYMMDDHHMMSS-, YYMMDDHHMMSS-, YYYYMMDD- oder YYMMDD-Format an, abhängig davon, ob M 14 (oder fehlend), 12, 8 oder 6 ist, gestattet aber, dass Sie TIMESTAMP-Spalten Werte entweder als Zeichenketten oder als Zahlen zuweisen. Eine TIMESTAMP-Spalte ist nützlich, um Datum und Zeit einer INSERT- oder UPDATE-Operation zu speichern, weil sie automatisch auf das Datum und die Zeit der jüngsten Operation gesetzt wird, wenn Sie nicht selbst einen Wert zuweisen. Sie können sie auch auf das aktuelle Datum und die aktuelle Zeit setzen, indem Sie einen NULL-Wert zuweisen. See Abschnitt 7.2.2, „Datums- und Zeit-Typen“.

    Ein TIMESTAMP wird immer mit 4 Bytes gespeichert. Das M-Argument betrifft nur die Anzeige der TIMESTAMP-Spalte.

    Beachten Sie, dass TIMESTAMP(X)-Spalten, bei denen X 8 oder 14 ist, als Zahlen interpretiert werden, während andere TIMESTAMP(X)-Spalten als Zeichenketten interpretiert werden. Das soll lediglich sicherstellen, dass Sie Tabellen mit diesen Typen verlässlich dumpen und wiederherstellen können! See Abschnitt 7.2.2.2, „Die DATETIME-, DATE- und TIMESTAMP-Typen“.

  • TIME

    Ein Zeit-Typ. Der Wertebereich ist '-838:59:59' bis '838:59:59'. MySQL zeigt TIME-Werte im 'HH:MM:SS'-Format an, gestattet aber, TIME-Spalten Werte entweder als Zeichenketten oder als Zahlen zuweisen. See Abschnitt 7.2.2.3, „Der TIME-Typ“.

  • YEAR[(2|4)]

    Ein Jahr in 2- oder 4-Ziffernformat (Vorgabe ist 4-Ziffern). Die zulässigen Werte reichen von 1901 bis 2155 sowie 0000 im 4-Ziffern-Jahresformat, und von 1970 bis 2069 beim 2-Ziffernformat (70 bis 69). MySQL zeigt YEAR-Werte im YYYY-Format an, gestattet aber, YEAR-Spalten Werte entweder als Zeichenketten oder als Zahlen zuweisen. (Der YEAR-Typ ist neu seit MySQL-Version 3.22.). See Abschnitt 7.2.2.4, „Der YEAR-Typ“.

  • [NATIONAL] CHAR(M) [BINARY]

    Eine Zeichenkette fester Länge, die beim Speichern rechts stets mit Leerzeichen bis zur angegebenen Länge aufgefüllt wird. Der Wertebereich von M ist 1 bis 255 Zeichen. Leerzeichen am Ende werden beim Abruf des Wertes entfernt. CHAR-Werte werden nach dem vorgabemäßigen Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung sortiert und verglichen, es sei denn, dass Schlüsselwort BINARY wird angegeben.

    NATIONAL CHAR (Kurzform NCHAR) ist die Art, wie ANSI-SQL bei einer CHAR-Spalte festlegt, dass der vorgabemäßige Zeichensatz verwendet werden soll. Das ist der Vorgabewert in MySQL.

    CHAR ist eine Abkürzung für CHARACTER.

    MySQL erlaubt das Anlegen einer Spalte des Typs CHAR(0). Das ist hauptsächlich nützlich, wenn Sie mit alten Applikationen kompatibel sein müssen, die auf die Existenz einer Spalte vertrauen, den Wert aber nicht tatsächlich benutzen. Es ist ebenfalls nett, um eine Spalte anzulegen, die nur 2 Werte annehmen kann: Eine CHAR(0), die nicht als NOT NULL definiert ist, belegt nur 1 Bit und kann 2 Werte annehmen: NULL oder "". See Abschnitt 7.2.3.1, „Die CHAR- und VARCHAR-Typen“.

  • [NATIONAL] VARCHAR(M) [BINARY]

    Eine Zeichenkette variabler Länge. HINWEIS: Leerzeichen am Ende werden bei der Speicherung des Wertes entfernt (das unterscheidet den Typ von der ANSI-SQL-Spezifikation). Der Wertebereich von M ist 1 bis 255 Zeichen. VARCHAR-Werte werden nach dem vorgabemäßigen Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung sortiert und verglichen, es sei denn, dass Schlüsselwort BINARY wird angegeben. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“.

    VARCHAR ist eine Abkürzung für CHARACTER VARYING. See Abschnitt 7.2.3.1, „Die CHAR- und VARCHAR-Typen“.

  • TINYBLOB , TINYTEXT

    Eine BLOB- oder TEXT-Spalte mit einer maximalen Länge von 255 (2^8 - 1) Zeichen. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“. See Abschnitt 7.2.3.2, „Die BLOB- und TEXT-Typen“.

  • BLOB , TEXT

    Eine BLOB- oder TEXT-Spalte mit einer maximalen Länge von 65535 (2^16 - 1) Zeichen. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“. See Abschnitt 7.2.3.2, „Die BLOB- und TEXT-Typen“.

  • MEDIUMBLOB , MEDIUMTEXT

    Eine BLOB- oder TEXT-Spalte mit einer maximalen Länge von 16777215 (2^24 - 1) Zeichen. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“. See Abschnitt 7.2.3.2, „Die BLOB- und TEXT-Typen“.

  • LONGBLOB , LONGTEXT

    Eine BLOB- oder TEXT-Spalte mit einer maximalen Länge von 4294967295 (2^32 - 1) Zeichen. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“. Beachten Sie, dass Sie nicht den gesamten Wertebereich dieses Typs benutzen können, weil das Client-Server-Protokoll und MyISAM-Tabellen momentan eine Beschränkungen auf 16 MB pro Kommunikationspaket / Tabellenzeile haben. See Abschnitt 7.2.3.2, „Die BLOB- und TEXT-Typen“.

  • ENUM('wert1','wert2',...)

    An Aufzählung. Ein Zeichenkettenobjekt, das nur einen Wert haben kann, der aus den Auflistungswerten 'wert1', 'wert2', ..., NULL oder dem speziellen ""-Fehlerwert ausgewählt wird. Eine ENUM kann maximal 65535 unterschiedliche Werte haben. See Abschnitt 7.2.3.3, „Der ENUM-Typ“.

  • SET('wert1','wert2',...)

    Eine Reihe. Ein Zeichenkettenobjekt, das 0 oder mehr Werte haben kann, von denen jeder aus den Auflistungswerten 'wert1', 'wert2', ... ausgewählt werden muss. Eine SET kann maximal 64 Elemente haben. See Abschnitt 7.2.3.4, „Der SET-Typ“.

7.2.1. Numerische Typen

MySQL unterstützt alle numerischen Typen von ANSI/ISO-SQL92. Diese Typen beinhalten die exakten numerischen Datentypen (NUMERIC, DECIMAL, INTEGER und SMALLINT) sowie die näherungsweisen numerischen Datentypen (FLOAT, REAL und DOUBLE PRECISION). Das Schlüsselwort INT ist ein Synonym für INTEGER und das Schlüsselwort DEC ist ein Synonym für DECIMAL.

Die NUMERIC- und DECIMAL-Typen sind in MySQL als derselbe Typ implementiert, wie es vom SQL92-Standard zugelassen ist. Sie werden für Werte benutzt, bei denen es wichtig ist, die exakte Genauigkeit zu bewahren, zum Beispiel bei monetären Daten. Wenn Sie eine Spalte mit einem dieser Typen deklarieren, können Genauigkeit und Bereich festgelegt werden (und werden das üblicherweise auch). Beispiel:

    gehalt DECIMAL(9,2)

In diesem Beispiel repräsentiert 9 (genauigkeit) die Anzahl signifikanter Dezimalziffern, die für Werte gespeichert werden, und 2 (bereich) repräsentiert die Anzahl von Ziffern, die nach dem Dezimalpunkt gespeichert werden. In diesem Fall liegt der Wertebereich, der in der gehalt-Spalte gespeichert werden kann, deswegen zwischen -9999999.99 und 9999999.99. (MySQL kann tatsächlich Zahlen bis zu 9999999.99 in dieser Spalte speichern, weil er nicht das Vorzeichen für positive Zahlen speichern muss).

In ANSI/ISO-SQL92 ist die Syntax DECIMAL(p) äquivalent zu DECIMAL(p,0). Gleichermaßen ist die Syntax DECIMAL äquivalent zu DECIMAL(p,0), wobei es der Implementation überlassen bleibt, den Wert von p festzulegen. MySQL unterstützt momentan keine dieser abweichenden Formen der DECIMAL- / NUMERIC-Datentypen. Das ist im Allgemeinen kein ernstes Problem, weil der hauptsächliche Nutzen dieser Typen darin liegt, sowohl Genauigkeit als auch Bereich explizit steuern zu können.

DECIMAL- und NUMERIC-Werte sind als Zeichenketten gespeichert statt als Fließkommazahlen, um die dezimale Genauigkeit dieser Werte zu bewahren. Ein Zeichen wird benutzt für jede Ziffer des Werts, den Dezimalpunkt (wenn bereich > 0) und das ‘-’-Zeichen (für negative Zahlen). Wenn bereich 0 ist, enthalten DECIMAL- und NUMERIC-Werte weder Dezimalpunkt noch Bruchteil.

Der maximale Wertebereich von DECIMAL- und NUMERIC-Werten ist derselbe wie für DOUBLE, aber der tatsächliche Wertebereich einer gegebenen DECIMAL- oder NUMERIC-Spalte kann durch genauigkeit oder bereich für eine gegebene Spalte beschränkt werden. Wenn einer solchen Spalte ein Wert mit mehr Ziffern nach dem Dezimalpunkt zugewiesen wird, als durch bereich zugelassen, wird der Wert auf diesen bereich gerundet. Wenn einer DECIMAL- oder NUMERIC-Spalte ein Wert zugewiesen wird, dessen Größe den Wertebereich überschreitet, der von der festgelegten (oder vorgabemäßigen) genauigkeit und bereich festgelegt wird, speichert MySQL den Wert des entsprechenden Endpunkts des Wertebereichs.

Als Erweiterung zum ANSI/ISO-SQL92-Standard unterstützt MySQL auch die Ganzzahltypen TINYINT, MEDIUMINT und BIGINT, wie oben aufgelistet. Ein andere Erweiterung wird von MySQL unterstützt, um optional die Anzeigebreite eines Ganzzahlwerts in Klammern festzulegen, die auf das Basis-Schlüsselwort des Typs folgen (zum Beispiel INT(4)). Die optionale Breitenspezifizierung wird benutzt, um die Anzeige von Werten, deren Breite geringer ist als für die Spalte festgelegt, linksseitig mit Leerzeichen aufzufüllen. Das begrenzt allerdings nicht den Wertebereich, der in der Spalte gespeichert werden kann, noch die Anzahl von Ziffern, die bei Werten angezeigt werden, die die angegebene Breite für die Spalte überschreiten. In Verbindung mit dem optionalen Erweiterungsattribut ZEROFILL wird - statt vorgabemäßig mit Leerzeichen - mit Nullen aufgefüllt. Bei einer Spalte zum Beispiel, die als INT(5) ZEROFILL deklariert wurde, wird 4 als 00004 dargestellt. Beachten Sie, dass Werte in einer Ganzzahlspalte, die größer sind als die Anzeigebreite, Probleme bei der Erzeugung temporärer Tabellen für einige komplizierte Joins durch MySQL auftreten können, weil MySQL in diesen Fällen darauf vertraut, dass die Daten in die Original-Spaltenbreite passten.

Alle Ganzzahl-Typen können ein optionales (Nicht-Standard-) Attribut UNSIGNED haben. Vorzeichenlose Werte können dafür benutzt werden, nur positive Zahlen in einer Spalte zuzulassen, wenn Sie eine Wertebereich brauchen, der etwas größer ausfällt.

Der FLOAT-Typ wird benutzt, um näherungsweise numerische Datentypen zu repräsentieren. Der ANSI/ISO-SQL92-Standard erlaubt eine optionale Festlegung der Genauigkeit (aber nicht den Wertebereich des Exponenten) in Bits, gefolgt vom Schlüsselwort FLOAT in Klammern. Die MySQL-Implementation unterstützt ebenfalls diese optionale Genauigkeitsfestlegung. Wenn das Schlüsselwort FLOAT für einen Spaltentyp ohne Genauigkeitsfestlegung benutzt wird, benutzt MySQL 4 Bytes, um die Werte zu speichern. Eine abweichende Syntax wird ebenfalls unterstützt, wobei zwei Zahlen in Klammern dem FLOAT-Schlüsselwort folgen. Mit dieser Option legt die erste Zahl wie gehabt den Speicherbedarf für den Wert in Bytes fest, und die zweite Zahl legt die Anzahl von Ziffern fest, die nach dem Dezimalpunkt gespeichert und angezeigt werden sollen (wie bei DECIMAL und NUMERIC). Wenn MySQL in einer solchen Spalte einen Wert mit mehr Dezimalziffern nach dem Dezimalpunkt speichern soll als für die Spalte festgelegt, wird der Wert beim Speichern gerundet, um die zusätzlichen Ziffern zu entfernen.

Die REAL- und DOUBLE PRECISION-Typen akzeptieren keine Genauigkeitsfestlegungen. Als Erweiterung zum ANSI/ISO-SQL92-Standard erkennt MySQL DOUBLE als ein Synonym für den DOUBLE PRECISION-Typ. Im Gegensatz zur Anforderung des Standard, dass die Genauigkeit für REAL kleiner sein muss als die für DOUBLE PRECISION, implementiert MySQL beide als 8-Byte-Fließkommawerte doppelter Genauigkeit (wenn er nicht im ``ANSI-Modus'' läuft). Für maximale Portabilität sollte Code, der die Speicherung näherungsweiser numerischer Daten erfordert, FLOAT oder DOUBLE PRECISION ohne Festlegung der Genauigkeit oder Anzahl von Dezimalstellen benutzen.

Wenn ein Wert in einer numerischen Spalte gespeichert werden soll, der ausserhalb des erlaubten Wertebereichs des Spaltentyps ist, schneidet MySQL den Wert auf den entsprechenden Endpunkt des Wertebereichs ab und speichert statt dessen diesen Wert.

Der Wertebereich einer INT-Spalte ist zum Beispiel -2147483648 bis 2147483647. Wenn Sie versuchen, -9999999999 in eine INT-Spalte einzufügen, wird der Wert auf den unteren Endpunkt des Bereichs abgeschnitten, und es wird -2147483648 gespeichert. Gleichermaßen wird beim Einfügen in eine solche Spalte nicht 9999999999, sondern 2147483647 gespeichert.

Wenn die INT-Spalte UNSIGNED ist, ist die Größe des Wertebereichs dieselbe, aber ihre Endpunkte verschieben sich zu 0 und 4294967295. Wenn Sie versuchen, -9999999999 bzw. 9999999999 zu speichern, werden die in der Spalte gespeicherten Werte statt dessen zu 0 bzw. 4294967296.

Umwandlungen, die aufgrund von Abschneiden geschehen, werden als ``Warnungen'' bei ALTER TABLE, LOAD DATA INFILE, UPDATE und in mehrzeiligen INSERT-Statements berichtet.

7.2.2. Datums- und Zeit-Typen

Die Datums- und Zeit-Typen sind DATETIME, DATE, TIMESTAMP, TIME und YEAR. Jeder dieser Typen hat einen zulässigen Wertebereich sowie einen ``0''-Wert, der benutzt wird, wenn Sie einen wirklich unzulässigen Wert speichern. Beachten Sie, dass MySQL es zuläßt, dass Sie bestimmte 'nicht ganz' zulässige Datumswerte speichern, zum Beispiel 1999-11-31. Der Grund hierfür ist, dass wir meinen, dass es in der Verantwortung der Applikation liegt, Datumsüberprüfungen vorzunehmen, und nicht beim SQL-Server. Um Datumsprüfungen 'schnell' zu machen, überprüft MySQL nur, dass der Monat im Bereich 0 bis 12 liegt und der Tag im Bereich 0 bis 31. Diese Bereiche sind deshalb so definiert, weil es MySQL zuläßt, dass Sie in einer DATE- oder DATETIME-Spalte Datumsangaben speichern, bei denen der Tag oder Monat-Tag 0 sind. Das ist extrem nützlich für Applikationen, die einen Geburtstag speichern müssen, dessen exaktes Datum unbekannt ist. In diesem Fall können Sie einfach Datumsangaben wie 1999-00-00 oder 1999-01-00 speichern. (Sie können nicht erwarten, von Funktionen wie DATE_SUB() oder DATE_ADD für solche Datumsangaben korrekte Werte zu erhalten.)

Einige allgemeine Überlegungen, die man im Kopf behalten sollte, wenn man mit Datums- und Zeit-Typen arbeitet:

  • MySQL ruft Werte für einen gegebenen Datums- oder Zeit-Typ in einem Standard-Format ab, versucht aber, eine Vielzahl von Formaten zu interpretieren, die Sie bereit stellen (wenn Sie zum Beispiel einen Wert angeben, der zugewiesen oder mit einem Datums- oder Zeit-Typ verglichen werden soll). Dennoch werden nur die in den folgenden Abschnitten beschriebenen Formate unterstützt. Es wird davon ausgegangen, dass Sie zulässige Werte bereitstellen; und es können unvorhersehbare Ergebnisse zustande kommen, wenn Sie Werte in anderen Formaten angeben.

  • Obwohl MySQL versucht, Werte in verschiedenen Formaten zu interpretieren, erwartet er immer, dass der Jahresanteil von Datumswerten ganz links steht. Datumsangaben müssen in der Reihenfolge Jahr - Monat - Tag gemacht werden (zum Beispiel '98-09-04') statt in der Reihenfolge Monat - Tag - Jahr oder Tag - Monat - Jahr, die anderswo häufig gebraucht werden (zum Beispiel '09-04-98', '04-09-98').

  • MySQL wandelt einen Datums- oder Zeitwert automatisch in eine Zahl um, wenn der Wert in einem numerischen Zusammenhang benutzt wird, und umgekehrt.

  • Wenn MySQL auf einen Datums- oder Zeitwert trifft, der ausserhalb des Wertebereichs oder in sonstiger Weise für den Typ nicht zulässig ist (siehe Anfang dieses Abschnitts), wird der Wert zum ``0''-Wert dieses Typs umgewandelt. (Die Ausnahme ist, dass TIME-Werte ausserhalb des Wertebereichs auf den entsprechenden Endpunkt des TIME-Wertebereichs abgeschnitten werden.) Die unten stehende Tabelle zeigt das Format des ``0''-Werts für jeden Typ:

    Spaltentyp``0''-Wert
    DATETIME'0000-00-00 00:00:00'
    DATE'0000-00-00'
    TIMESTAMP00000000000000 (Länge abhängig von der Anzeigebreite)
    TIME'00:00:00'
    YEAR0000
  • Die ``0''-Werte sind speziell, aber Sie können diese explizit speichern oder auf sie verweisen, indem Sie die in der Tabelle dargestellten Werte benutzen. Sie können das auch mit den Werten '0' oder 0 machen, die leichter zu schreiben sind.

  • ``0''-Datums- oder -Zeitwerte, die über MyODBC benutzt werden, werden in MyODBC-Version 2.50.12 und höher automatisch in NULL umgewandelt, weil ODBC solche Werte nicht handhaben kann.

7.2.2.1. Jahr-2000-Probleme und Datumstypen

MySQL selbst ist Jahr-2000-konform (Jahr-2000-sicher, see Abschnitt 2.2.4, „Jahr-2000-Konformität“), aber Eingabewerte, die an MySQL übergeben werden, sind das möglicherweise nicht. Jede Eingabe von Jahreswerten mit 2 Ziffern ist mehrdeutig, weil das Jahrhundert unbekannt ist. Solche Werte müssen in 4-stellige Form umgedeutet werden, weil MySQL Jahre intern mit 4 Ziffern speichert.

Bei DATETIME-, DATE-, TIMESTAMP- und YEAR-Typen interpretiert MySQL Datumsangaben mit mehrdeutigen Jahreswerten nach folgenden Regeln:

  • Jahreswerte im Bereich 00 bis 69 werden in 2000 bis 2069 umgewandelt.

  • Jahreswerte im Bereich 70 bis 99 werden in 1970 bis 1999 umgewandelt.

Denken Sie daran, dass diese Regeln nur eine vernünftige Schätzung dessen bedeuten, was die Daten tatsächlich darstellen sollen. Wenn die von MySQL benutzten Heuristiken keine korrekten Werte ergeben, müssen Sie eindeutige Eingaben in Form 4-stelliger Jahreswerte bereit stellen.

ORDER BY sortiert 2-stellige YEAR/DATE/DATETIME-Typen korrekt.

Beachten Sie, dass einige Funktionen wie MIN() und MAX() ein TIMESTAMP / DATE in eine Zahl umwandeln. Das heißt, dass ein Zeitstempel mit einer 2-stelligen Jahresangabe bei diesen Funktionen nicht korrekt funktioniert. Das kann in diesem Fall dadurch behoben werden, dass der TIMESTAMP / DATE in ein 4-stelliges Jahresformat umgewandelt wird, oder etwas wie MIN(DATE_ADD(zeitstempel,INTERVAL 0 DAYS)) benutzt wird.

7.2.2.2. Die DATETIME-, DATE- und TIMESTAMP-Typen

Die DATETIME-, DATE- und TIMESTAMP-Typen sind verwandt. Dieser Abschnitt beschreibt ihre Charakteristiken, wo sie sich ähnlich sind und wo sie sich unterscheiden.

Der DATETIME-Typ wird benutzt, wenn Sie Werte brauchen, die sowohl Datums- als auch Zeitinformationen beinhalten. MySQL ruft DATETIME-Werte ab und zeigt sie an im 'YYYY-MM-DD HH:MM:SS'-Format. Der unterstützte Wertebereich ist '1000-01-01 00:00:00' bis '9999-12-31 23:59:59'. (``Unterstützt'' heißt, dass frühere Werte zwar funktionieren können, dass es aber keine Garantie dafür gibt.)

Der DATE-Typ wird benutzt, wenn Sie nur einen Datumswert brauchen, ohne Zeitanteil. MySQL ruft DATE-Werte ab und zeigt sie an im 'YYYY-MM-DD'-Format. Der unterstützte Wertebereich ist '1000-01-01' bis '9999-12-31'.

Der TIMESTAMP-Typ ist ein Typ, den Sie dafür benutzen können, um INSERT- oder UPDATE-Operationen mit dem aktuellen Datum und der aktuellen Zeit zu stempeln. Wenn Sie mehrfache TIMESTAMP-Spalten haben, wird nur die erste automatisch aktualisiert.

Die automatische Aktualisierung der TIMESTAMP-Spalte geschieht unter einer der folgenden Bedingungen:

  • Die Spalte wird in einem INSERT- oder LOAD DATA INFILE-Statement nicht explizit angegeben.

  • Die Spalte wird in einem UPDATE-Statement nicht explizit angegeben, aber ein anderer Spaltenwert ändert sich. (Beachten Sie, dass ein UPDATE, das eine Spalte auf einen Wert setzt, den diese bereits hat, nicht dazu führt, dass die TIMESTAMP-Spalte aktualisiert wird, weil MySQL das Aktualisieren in einem solchen Fall auf Effizienzgründen ignoriert.)

  • Wenn Sie die TIMESTAMP-Spalte explizit auf NULL setzen.

TIMESTAMP-Spalten abgesehen von der ersten können ebenfalls auf das aktuelle Datum und die aktuelle Zeit gesetzt werden. Setzen Sie die Spalte einfach auf NULL oder auf NOW().

Sie können jede TIMESTAMP-Spalte auf einen Wert setzen, der vom aktuellen Datum und der aktuellen Zeit abweicht, indem Sie sie explizit auf den gewünschten Wert setzen. Das gilt sogar für die erste TIMESTAMP-Spalte. Sie können diese Eigenschaft benutzen, wenn Sie einen TIMESTAMP auf das aktuelle Datum und die aktuelle Zeit setzen wollen, wenn Sie eine Zeile erzeugen, nicht aber, wenn die Zeile später aktualisiert wird:

  • Lassen Sie MySQL die Spalte setzen, wenn die Zeile erzeugt wird. Das initialisiert sie auf das aktuelle Datum und die aktuelle Zeit.

  • Wenn Sie nachfolgende Aktualisierungen anderer Spalten in der Zeile durchführen, setzen Sie die TIMESTAMP-Spalte explizit auf ihren aktuellen Wert.

Auf der anderen Seite finden Sie vielleicht mindestens so einfach, eine DATETIME-Spalte zu benutzen, die Sie auf NOW() initialisieren, wenn die Zeile erzeugt wird, und die Sie bei nachfolgenden Aktualisierungen nicht anfassen.

TIMESTAMP-Werte haben einen Wertebereich von 1970 bis irgendwann im Jahr 2037, bei einer Auflösung von einer Sekunde. Werte werden als Zahlen angezeigt.

Das Format, in dem MySQL TIMESTAMP-Werte abruft und anzeigt, hängt von der Anzeigebreite ab, wie in der obigen Tabelle dargestellt. Das `volle' TIMESTAMP-Format ist 14 Ziffern, aber TIMESTAMP-Spalten können mit kürzeren Anzeigebreiten angelegt werden:

SpaltentypAnzeigeformat
TIMESTAMP(14)YYYYMMDDHHMMSS
TIMESTAMP(12)YYMMDDHHMMSS
TIMESTAMP(10)YYMMDDHHMM
TIMESTAMP(8)YYYYMMDD
TIMESTAMP(6)YYMMDD
TIMESTAMP(4)YYMM
TIMESTAMP(2)YY

Alle TIMESTAMP-Spalten haben dieselbe Speichergröße, unabhängig von der Anzeigebreite. Die gebräuchlichsten Anzeigebreiten sind 6, 8, 12 und 14. Sie können zur Zeit der Tabellenerzeugung beliebige Anzeigebreiten festlegen, aber Werte von 0 oder größer als 14 werden auf 14 gesetzt. Ungerade Werte im Bereich von 1 bis 13 werden auf die nächst höhere gerade Zahl gesetzt.

Sie können DATETIME-, DATE- und TIMESTAMP-Werte mit folgenden Formaten festlegen:

  • Als eine Zeichenkette im 'YYYY-MM-DD HH:MM:SS'- oder 'YY-MM-DD HH:MM:SS'-Format. Eine ``entspannte'' Syntax ist zugelassen - jedes Satzzeichen kann als Begrenzer zwischen Datumsanteilen oder Zeitanteilen verwendet werden. Beispielsweise sind '98-12-31 11:30:45', '98.12.31 11+30+45', '98/12/31 11*30*45' und '98@12@31 11^30^45' äquivalent.

  • Als eine Zeichenkette im 'YYYY-MM-DD'- oder 'YY-MM-DD'-Format. Auch hier ist eine ``entspannte'' Syntax zugelassen. Beispielsweise sind '98-12-31', '98.12.31', '98/12/31' und '98@12@31' äquivalent.

  • Als eine Zeichenkette ohne Begrenzer im 'YYYYMMDDHHMMSS'- oder 'YYMMDDHHMMSS'-Format, vorausgesetzt, die Zeichenkette ergibt als Datum einen Sinn. '19970523091528' und '970523091528' beispielsweise werden als '1997-05-23 09:15:28' interpretiert, aber '971122129015' ist unzulässig (es hat einen Minutenanteil, der keinen Sinn ergibt) und wird in '0000-00-00 00:00:00' umgewandelt.

  • Als eine Zeichenkette ohne Begrenzer im 'YYYYMMDD'- oder 'YYMMDD'-Format, vorausgesetzt, die Zeichenkette ergibt als Datum einen Sinn. '19970523' und '970523' werden als '1997-05-23' interpretiert, aber '971332' ist unzulässig (es hat einen Monatsanteil und einen Tagesanteil, der keinen Sinn ergibt) und wird in '0000-00-00' umgewandelt.

  • Als eine Zahl im YYYYMMDDHHMMSS- oder YYMMDDHHMMSS-Format, vorausgesetzt, die Zahl ergibt als Datum einen Sinn. 19830905132800 und 830905132800 zum Beispiel werden als '1983-09-05 13:28:00' interpretiert.

  • Als eine Zahl im YYYYMMDD- oder YYMMDD-Format, vorausgesetzt, die Zahl ergibt als Datum einen Sinn. 19830905 und 830905 zum Beispiel werden als '1983-09-05' interpretiert.

  • Als Ergebnis einer Funktion, die einen Wert zurückgibt, der in einem DATETIME-, DATE- oder TIMESTAMP-Zusammenhang einen Sinn ergibt, wie NOW() oder CURRENT_DATE.

Unzulässige DATETIME-, DATE- oder TIMESTAMP-Werte werden in den ``0''-Wert des jeweiligen Typs umgewandelt ('0000-00-00 00:00:00', '0000-00-00' oder 00000000000000).

Bei Werten, die als Zeichenketten angegeben werden, die Begrenzer für Datumsanteile enthalten, ist es nicht notwendig, zwei Ziffern für Monats- oder Tageswerte anzugeben, die weniger als 10 sind. '1979-6-9' ist dasselbe wie '1979-06-09'. Gleichermaßen ist es bei Zeichenketten, die Begrenzer für Zeitanteile enthalten, nicht notwendig, zwei Ziffern für Stunden-, Monats- oder Sekundenwerte anzugeben, die weniger als 10 sind. '1979-10-30 1:2:3' ist dasselbe wie '1979-10-30 01:02:03'.

Werte, die als Zahlen angegeben sind, sollten 6, 8, 12 oder 14 Ziffern lang sein. Wenn die Zahl 8 oder 14 Ziffern lang ist, wird angenommen, dass sie im YYYYMMDD- oder YYYYMMDDHHMMSS-Format ist und dass das Jahr durch die ersten 4 Ziffern angegeben wird. Wenn die Zahl 6 oder 12 Ziffern lang ist, wird angenommen, dass sie im YYMMDD- oder YYMMDDHHMMSS-Format ist und dass das Jahr durch die ersten 2 Ziffern angegeben wird. Zahlen, die nicht diesen Längen entsprechen, werden interpretiert, als ob sie mit führenden Nullen auf die nächst mögliche Länge gebracht worden wären.

Werte, die als nicht begrenzte Zeichenketten angegeben werden, werden interpretiert, indem ihre Länge als gegeben angenommen wird. Wenn die Zeichenkette 8 oder 14 Zeichen lang ist, wird angenommen, dass das Jahr durch die ersten 4 Zeichen angegeben wird. Ansonsten wird angenommen, dass das Jahr durch die ersten 2 Zeichen angegeben wird. Die Zeichenkette wird von links nach rechts interpretiert, um die Jahres-, Monats-, Tages-, Stunden- und Sekundenwerte zu finden, für so viele Anteile, wie in der Zeichenkette vorkommen. Das bedeutet, dass Sie keine Zeichenketten benutzen sollten, die weniger als 6 Zeichen haben. Wenn Sie zum Beispiel '9903' angeben, in der Annahme, dass das März 1999 darstellt, werden Sie feststellen, dass MySQL einen ``0''-Datumswert in Ihre Tabelle einfügt. Das liegt daran, dass die Jahres- und Monatswerte 99 und 03 sind, aber der Tagesanteil fehlt (0), so dass der Wert kein zulässiges Datum darstellt.

TIMESTAMP-Spalten speichern zulässige Werte mit der vollen Genauigkeit, mit der der Wert angegeben wurde, unabhängig von der Anzeigebreite. Das hat mehrere Auswirkungen:

  • Geben Sie immer Jahr, Monat und Tag an, selbst wenn Ihre Spaltentypen TIMESTAMP(4) oder TIMESTAMP(2) sind. Ansonsten wäre der Wert kein zulässiges Datum und 0 würde gespeichert werden.

  • Wenn Sie ALTER TABLE benutzen, um eine enge TIMESTAMP-Spalte breiter zu machen, werden Informationen angezeigt, die vorher ``versteckt'' waren.

  • Gleichermaßen führt das Verengen einer TIMESTAMP-Spalte nicht dazu, dass Informationen verloren gehen, ausser in dem Sinn, dass weniger Informationen dargestellt werden, wenn die Werte angezeigt werden.

  • Obwohl TIMESTAMP-Werte mit voller Genauigkeit gespeichert werden, ist die einzige Funktion, die direkt mit dem zugrunde liegenden gespeicherten Wert arbeitet, UNIX_TIMESTAMP(). Alle anderen Funktionen arbeiten mit dem formatierten, abgerufenen Wert. Das bedeutet, Sie können keine Funktionen wie HOUR() oder SECOND() benutzen, wenn nicht auch der relevante Teil des TIMESTAMP-Werts im formatierten Werte enthalten ist. Wenn zum Beispiel der HH-Teil einer TIMESTAMP-Spalte nicht angezeigt wird, wenn die Anzeigebreite nicht mindestens 10 beträgt, wird der Versuch, HOUR() auf kürzere TIMESTAMP-Werte anzuwenden, unsinnige Ergebnisse erzeugen.

Bis zu einem gewissen Grad können Sie einem Objekt eines Datumstyp Werte eines anderen Datumstyps zuweisen. Jedoch kann eine Änderung des Wertes oder ein Informationsverlust eintreten:

  • Wenn Sie einem DATETIME- oder TIMESTAMP-Objekt einen DATE-Wert zuweisen, wird der Zeitanteil im Ergebniswert auf '00:00:00' gesetzt, weil der DATE-Wert keine Zeitinformationen enthält.

  • Wenn Sie einem DATE-Objekt einen DATETIME- oder TIMESTAMP-Wert zuweisen, wird der Zeitanteil des Ergebniswerts gelöscht, weil der DATE-Typ keine Zeitinformationen speichert.

  • Denken Sie daran, dass DATETIME-, DATE- und TIMESTAMP-Werte zwar in denselben Formaten angegeben werden können, dass die Typen jedoch nicht alle denselben Wertebereich haben. TIMESTAMP-Werte zum Beispiel können nicht früher als 1970 oder später als 2037 sein. Das bedeutet, dass ein Datum wie '1968-01-01', was als DATETIME oder DATE-Wert zulässig wäre, kein gültiger TIMESTAMP-Wert ist und in 0 umgewandelt wird, wenn er einem solchen Objekt zugewiesen wird.

Seien Sie auf der Hut vor Fallstricken, wenn Sie Datumswerte angeben:

  • Das entspannte Format läßt Werte als Zeichenketten zu, die täuschen können. Ein Wert wie '10:11:12' zum Beispiel sieht wegen des ‘:’-Begrenzers wie ein Zeitwert aus, wird er aber in einem Datums-Zusammenhang benutzt, wird er als das Datum '2010-11-12' interpretiert. Der Wert '10:45:15' wird in '0000-00-00' umgewandelt, weil '45' kein zulässiger Monat ist.

  • Jahreswerte, die als zwei Ziffern angegeben werden, sind mehrdeutig, weil das Jahrhundert unbekannt ist. unknown. MySQL interpretiert 2-stellige Jahreswerte nach folgenden Regeln:

    • Jahreswerte im Bereich 00 bis 69 werden in 2000 bis 2069 umgewandelt.

    • Jahreswerte im Bereich 70 bis 99 werden in 1970 bis 1999 umgewandelt.

7.2.2.3. Der TIME-Typ

MySQL ruft TIME-Werte ab und zeigt sie an im 'HH:MM:SS'-Format (oder 'HHH:MM:SS'-Format für große Stundenwerte). TIME-Werte rangieren von '-838:59:59' bis '838:59:59'. Der Grund dafür, dass der Stundenanteil so Groß sein kann, liegt darin, dass der TIME-Typ nicht nur benutzt werden kann, um die Tageszeit zu repräsentieren (wobei die Stunden weniger als 24 sein müssen), sondern auch abgelaufene Zeit oder ein Zeitintervall zwischen zwei Ereignissen (was viel größer als 24 Stunden oder sogar negativ sein kann).

Sie können TIME-Werte in einer Vielzahl von Formaten angeben:

  • Als eine Zeichenkette im 'D HH:MM:SS.bruchteil'-Format. (Beachten Sie, dass MySQL bislang nicht den Bruchteil für die TIME-Spalte speichert.) Man kann auch folgende ``entspannte'' Syntax benutzen:

    HH:MM:SS.bruchteil, HH:MM:SS, HH:MM, D HH:MM:SS, D HH:MM, D HH oder SS. Hierbei ist D Tage zwischen 0 und 33.

  • Als eine Zeichenkette ohne Begrenzer im 'HHMMSS'-Format, vorausgesetzt, dass diese als Zeitangabe einen Sinn ergibt. '101112' zum Beispiel wird als '10:11:12' interpretiert, aber '109712' ist unzulässig (es hat einen Minutenanteil, der keinen Sinn ergibt) und wird in '00:00:00' umgewandelt.

  • Als eine Zahl im HHMMSS-Format, vorausgesetzt, dass diese als Zeitangabe einen Sinn ergibt. 101112 zum Beispiel wird als '10:11:12' interpretiert. Folgende alternativen Formate werden ebenfalls verstanden: SS, MMSS, HHMMSS, HHMMSS.bruchteil. Beachten Sie, dass MySQL bislang noch nicht den Bruchteil speichert.

  • Als Ergebnis einer Funktion, die einen Wert zurück gibt, der in einem TIME-Zusammenhang akzeptabel ist, wie CURRENT_TIME.

Bei TIME-Werten, die als Zeichenketten angegeben sind, die einen Begrenzer für den Zeitanteil beinhalten, ist es nicht notwendig, zwei Ziffern für Stunden-, Minuten- oder Sekunden-Werte anzugeben, die weniger als 10 sind. '8:3:2' ist dasselbe wie '08:03:02'.

Seien Sie vorsichtig damit, einer TIME-Spalte ``kurze'' TIME-Werte zuzuweisen. Ohne Semikolon interpretiert MySQL Werte unter der Annahme, dass die am weitesten rechts stehenden Ziffern Sekunden repräsentieren. (MySQL interpretiert TIME-Werte als vergangene Zeit statt als Tageszeit.) Sie könnten zum Beispiel denken, dass '1112' und 1112 '11:12:00' bedeuten (12 Minuten nach 11 Uhr), aber MySQL interpretiert sie als '00:11:12' (11 Minuten, 12 Sekunden). Gleichermaßen wird '12' und 12 als '00:00:12' interpretiert. TIME-Werte mit Semikolon werden statt dessen immer als Tageszeit interpretiert. Das heißt, '11:12' bedeutet '11:12:00', nicht '00:11:12'.

Werte, die ausserhalb des TIME-Wertebereichs liegen, ansonsten aber zulässig sind, werden auf den entsprechenden Endpunkt des Wertebereichs abgeschnitten. '-850:00:00' bzw. '850:00:00' werden in '-838:59:59' bzw. '838:59:59' umgewandelt.

Unzulässige TIME-Werte werden in '00:00:00' umgewandelt. Beachten Sie, dass es keine Möglichkeit gibt zu unterscheiden, wenn ein Wert von '00:00:00' in einer Tabelle gespeichert ist, ob dieser originär als '00:00:00' eingegeben wurde oder ob es ein unzulässiger Wert war, weil '00:00:00' selbst ein zulässiger TIME-Wert ist.

7.2.2.4. Der YEAR-Typ

Der YEAR-Typ ist ein 1-Byte-Typ, der für die Darstellung von Jahren benutzt wird.

MySQL ruft YEAR-Werte ab und speichert sie im YYYY-Format. Der Wertebereich ist 1901 bis 2155.

Sie können YEAR-Werte in einer Vielzahl von Formaten angeben:

  • Als vierstellige Zeichenkette im Wertebereich von '1901' bis '2155'.

  • Als vierstellige Zahl im Wertebereich von 1901 bis 2155.

  • Als zweistellige Zeichenkette im Wertebereich von '00' bis '99'. Werte in den Bereichen von '00' bis '69' und '70' bis '99' werden in YEAR-Werte in den Bereichen von 2000 bis 2069 und 1970 bis 1999 umgewandelt.

  • Als zweistellige Zahl im Wertebereich von 1 bis 99. Werte in den Bereichen von 1 bis 69 und 70 bis 99 werden in YEAR-Werte in den Bereichen von 2001 bis 2069 und 1970 bis 1999 umgewandelt. Beachten Sie, dass der Wertebereich für zweistellige Zahlen sich geringfügig vom Wertebereich für zweistellige Zeichenketten unterscheidet, weil Sie 0 nicht direkt als Zahl eingeben können und sie dann als 2000 interpretiert wird. Sie müssen sie als Zeichenkette '0' oder '00' angeben, oder sie wird als 0000 interpretiert.

  • Als Ergebnis einer Funktion, die einen Wert zurück gibt, der in einem YEAR-Zusammenhang akzeptabel ist, wie NOW().

Unzulässige YEAR-Werte werden in 0000 umgewandelt.

7.2.3. Zeichenketten-Typen

Die Zeichenketten-Typen sind CHAR, VARCHAR, BLOB, TEXT, ENUM und SET. Dieser Abschnitt beschreibt, wie diese Typen funktionieren, ihren Speicherbedarf und wie sie in Anfragen benutzt werden.

7.2.3.1. Die CHAR- und VARCHAR-Typen

Die CHAR- und VARCHAR-Typen sind ähnlich, unterscheiden sich aber in der Art, wie sie gespeichert und abgerufen werden.

Die Länge einer CHAR-Spalte wird auf die Länge festgelegt, die Sie bei der Erzeugung der Tabelle angeben. Die Länge kann zwischen 1 und 255 variieren. (Ab MySQL-Version 3.23 kann die Länge zwischen 0 und 255 liegen.) Wenn CHAR-Werte gespeichert werden, werden sie am rechten Ende bis zur festgelegten Länge mit Leerzeichen aufgefüllt. Wenn CHAR-Werte abgerufen werden, werden die Leerzeichen am Ende entfernt.

Werte in VARCHAR-Spalten sind Zeichenketten variabler Länge. Sie können eine VARCHAR-Spalte mit jeder Länge zwischen 1 und 255 deklarieren, genau wie für CHAR-Spalten. Im Gegensatz zu CHAR werden VARCHAR-Werte jedoch nur mit so vielen Zeichen wie nötig gespeichert, plus 1 Byte, um die Länge zu speichern. Die Werte werden nicht aufgefüllt; statt dessen werden Leerzeichen am Ende beim Speichern entfernt. (Diese Entfernung von Leerzeichen weicht von der ANSI-SQL-Spezifikation ab.)

Wenn Sie einer CHAR- oder VARCHAR-Spalte einen Wert zuweisen, der die maximale Spaltenlänge überschreitet, wird der Wert so zurecht geschnitten, das er passt.

Die unten stehende Tabelle stellt die Unterschiede zwischen den beiden Spaltentypen dar, indem das Ergebnis der Speicherung unterschiedlicher Zeichenkettenwerte in CHAR(4)- und VARCHAR(4)-Spalten gezeigt wird:

WertCHAR(4)SpeicherbedarfVARCHAR(4)Speicherbedarf
'''    '4 Bytes''1 Byte
'ab''ab  '4 Bytes'ab'3 Bytes
'abcd''abcd'4 Bytes'abcd'5 Bytes
'abcdefgh''abcd'4 Bytes'abcd'5 Bytes

Die Werte, die aus den CHAR(4)- und VARCHAR(4)-Spalten abgerufen werden, sind in jedem Fall gleich, weil Leerzeichen am Ende von CHAR-Spalten beim Abruf entfernt werden.

Werte in CHAR- und VARCHAR-Spalten werden unabhängig von der Groß-/Kleinschreibung sortiert und verglichen, es sei denn, beim Erzeugen der Tabelle wurde das BINARY-Attribut festgelegt. Das BINARY-Attribut bedeutet, dass Spaltenwerte abhängig von der Groß-/Kleinschreibung in Übereinstimmung mit der ASCII-Reihenfolge der Maschine sortiert und verglichen werden, auf der der MySQL-Server läuft. BINARY beeinflusst nicht, wie die Spalte gespeichert oder abgerufen wird.

Das BINARY-Attribut ist 'klebrig', das heißt, dass der gesamte Ausdruck als ein BINARY-Wert verglichen wird, sobald eine BINARY-Spalte im Ausdruck benutzt wird.

MySQL ändert eventuell 'still' den Typ von CHAR- oder VARCHAR-Spalten bei der Tabellenerzeugung.

See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“.

7.2.3.2. Die BLOB- und TEXT-Typen

Ein BLOB ist großes Binärobjekt (Binary Large OBject), das eine variable Menge von Daten enthalten kann. Die vier BLOB-Typen TINYBLOB, BLOB, MEDIUMBLOB und LONGBLOB unterscheiden sich nur hinsichtlich der maximalen Länge der Werte, die sie aufnehmen können. See Abschnitt 7.2.6, „Speicherbedarf von Spaltentypen“.

Die vier TEXT-Typen TINYTEXT, TEXT, MEDIUMTEXT und LONGTEXT entsprechen den vier BLOB-Typen und haben dieselben maximalen Längen und denselben Speicherbedarf. Der einzige Unterschied zwischen BLOB- und TEXT-Typen ist, dass beim Sortieren und Vergleichen bei BLOB-Werten Groß-/Kleinschreibung berücksichtigt wird, bei TEXT-Werten dagegen nicht. Mit anderen Worten ist ein TEXT ein BLOB ohne Berücksichtigung der Groß-/Kleinschreibung.

Wenn Sie einer BLOB- oder TEXT-Spalte einen Wert zuweisen, der die maximale Länge des Spaltentyps überschreitet, wird der Wert so zurecht geschnitten, dass er passt.

In fast jeder Hinsicht können Sie eine TEXT-Spalte als eine VARCHAR-Spalte betrachten, die so Groß sein kann, wie Sie wollen. Gleichermaßen können Sie eine BLOB-Spalte als eine VARCHAR BINARY-Spalte betrachten. Die Unterschiede sind:

  • Seit MySQL-Version 3.23.2 können Sie Indexe auf BLOB- und TEXT-Spalten anlegen. Ältere Versionen von MySQL unterstützten das nicht.

  • Leerzeichen am Ende werden beim Speichern von BLOB- und TEXT-Spalten nicht wie bei VARCHAR-Spalten entfernt.

  • BLOB- und TEXT-Spalten können keine DEFAULT-Werte haben.

MyODBC definiert BLOB-Werte als LONGVARBINARY und TEXT-Werte als LONGVARCHAR.

Weil BLOB- und TEXT-Werte extrem lang sein können, treffen Sie bei der Benutzung eventuell auf Beschränkungen:

  • Wenn Sie GROUP BY oder ORDER BY für BLOB- oder TEXT-Spalten benutzen wollen, müssen Sie den Spaltenwert in ein Objekt fester Länge umwandeln. Standardmäßig wird das mit der SUBSTRING-Funktion gemacht. Beispiel:

    mysql> select kommentar from tabelle,substring(kommentar,20) as substr
           ORDER BY substr;
    

    Wenn Sie das nicht tun, werden nur die ersten max_sort_length Bytes der Spalte beim Sortieren benutzt. Der Vorgabewert von max_sort_length ist 1024; dieser Wert kann mit der -O-Option geändert werden, wenn der mysqld-Server gestartet wird. Sie können auf einen Ausdruck, der BLOB- oder TEXT-Werte enthält, gruppieren, indem Sie die Spaltenposition angeben oder ein Alias benutzen:

    mysql> select id,substring(blob_spalte,1,100) from tabelle
               GROUP BY 2;
    mysql> select id,substring(blob_spalte,1,100) as b from tabelle
               GROUP BY b;
    
  • Die maximale Größe eines BLOB- oder TEXT-Objekts wird durch seinen Typ festgelegt, aber der größte Wert, den Sie tatsächlich zwischen Client und Server übertragen können, wird von der Menge verfügbaren Arbeitsspeichers und der Größe des Kommunikationspuffers festgelegt. Sie können die Nachrichtenpuffergröße ändern, müssen das aber auf beiden Seiten, also beim Client und beim Server, tun. See Abschnitt 6.5.2, „Serverparameter tunen“.

Beachten Sie, dass intern jeder BLOB- oder TEXT-Wert durch ein separat zugewiesenes Objekt dargestellt wird. Das steht im Gegensatz zu allen anderen Spaltentypen, für die Speicherplatz einmal pro Spalte zugewiesen wird, wenn die Tabelle geöffnet wird.

7.2.3.3. Der ENUM-Typ

Ein ENUM ist ein Zeichenketten-Objekt, dessen Wert normalerweise aus einer Liste zulässiger Werte ausgesucht wird, die explizit bei der Spaltenspezifizierung bei der Tabellenerzeugung aufgezählt werden.

Der Wert kann unter bestimmten Umständen auch die leere Zeichenkette ("") oder NULL sein:

  • Wenn Sie in eine ENUM einen ungültigen Wert einfügen (das ist eine Zeichenkette, die es in der Auflistung zugelassener Werte nicht gibt), wird statt dessen die leere Zeichenkette als spezieller Fehlerwert eingefügt. Diese Zeichenkette kann von einer 'normalen' leeren Zeichenkette dadurch unterschieden werden, dass diese Zeichenkette den numerischen Wert 0 hat. Mehr dazu später.

  • Wenn ein ENUM als NULL deklariert ist, ist NULL ebenfalls ein zulässiger Wert für die Spalte und der Vorgabewert ist NULL. Wenn ein ENUM als NOT NULL deklariert ist, ist der Vorgabewert das erste Element der Auflistung erlaubter Werte.

Jeder Aufzählungswert hat einen Index:

  • Werte der Auflistung zulässiger Elemente in der Spaltenspezifikation fangen mit 1 an.

  • Der Indexwert des Fehlerwerts leere Zeichenkette ist 0. Folglich können Sie folgendes SELECT-Statement benutzen, um Zeilen zu finden, denen unzulässige ENUM-Werte zugewiesen wurden:

    mysql> SELECT * FROM tabelle WHERE enum_spalte=0;
    
  • Der Index des NULL-Werts ist NULL.

Wenn beispielsweise eine Spalte als ENUM("eins", "zwei", "drei") festgelegt wurde, kann sie einen der unten dargestellen Werte besitzen. Der Index jedes Werts wird auch dargestellt:

WertIndex
NULLNULL
""0
"eins"1
"zwei"2
"drei"3

Eine Aufzählung kann maximal 65535 Elemente enthalten.

Groß-/Kleinschreibung ist irrelevant, wenn Sie einer ENUM-Spalte Werte zuweisen. Jedoch haben Werte, die später aus der Spalte abgerufen werden, dieselbe Groß-/Kleinschreibung wie die Werte, die für die Festlegung zulässiger Werte bei der Tabellenerzeugung verwendet wurden.

Wenn Sie eine ENUM in einem numerischen Zusammenhang benutzen, wird der Index des Spaltenwerts zurückgegeben. Sie können beispielsweise numerische Werte aus einer ENUM-Spalte wie folgt abrufen:

mysql> SELECT enum_spalte+0 FROM tabelle;

Wenn Sie eine Zahl in eine ENUM speichern, wird die Zahl als Index behandelt und der gespeicherte Wert ist das Aufzählungselement mit diesem Index. (Das funktioniert jedoch nicht bei LOAD DATA, was alle Eingaben als Zeichenketten behandelt.)

ENUM-Werte werden in der Reihenfolge sortiert, wie die Aufzählungselemente bei der Spaltenspezifizierung eingegeben wurden. (Mit anderen Worten werden ENUM-Werte nach ihren Indexzahlen sortiert.) So wird beispielsweise "a" vor "b" einsortiert bei ENUM("a", "b"), aber "b" wird vor "a" einsortiert bei ENUM("b", "a"). Die leere Zeichenkette wird vor nicht leeren Zeichenketten und NULL-Werte vor allen anderen Aufzählungswerten einsortiert.

Wenn Sie alle möglichen Werte einer ENUM-Spalte erhalten wollen, benutzen Sie: SHOW COLUMNS FROM tabelle LIKE enum_spalte und gehen die ENUM-Definition in der zweiten Spalte durch.

7.2.3.4. Der SET-Typ

Ein SET ist ein Zeichenketten-Objekt, das 0 oder mehr Werte haben kann, wovon jedes aus einer Auflistung zulässiger Werte stammen muss, die bei der Tabellenerzeugung festgelegt wurden. SET-Spaltenwerte, die aus mehrfachen SET-Elementen bestehen, werden angegeben, indem die Elemente durch Kommas (‘,’) getrennt werden. Daraus ergibt sich, dass SET-Elemente selbst keine Kommas enthalten dürfen.

Eine Spalte beispielsweise, die als SET("eins", "zwei") NOT NULL festgelegt wurde, kann folgende Werte haben:

""
"eins"
"zwei"
"eins,zwei"

Eine SET kann maximal 64 unterschiedliche Elemente besitzen.

MySQL speichert SET-Werte numerisch, wobei das niedrigste Bit in der Reihenfolge der gespeicherten Werte dem ersten SET-Element entspricht. Wenn Sie einen SET-Wert in einem numerischen Zusammenhang abrufen, hat der abgerufene Werte Bits gesetzt, die den SET-Elementen, aus denen sich der Spaltenwert zusammensetzt, entspricht. Beispielsweise können Sie numerische Werte aus einer SET-Spalte wie folgt abrufen:

mysql> SELECT set_spalte+0 FROM tabelle;

Wenn in einer SET-Spalte eine Zahl gespeichert wird, legen die Bits, die in der binären Darstellung der Zahl gesetzt sind, die SET-Elemente im Spaltenwert fest. Angenommen, eine Spalte ist als SET("a","b","c","d") festgelegt, dann haben die Elemente folgende Bitwerte:

SET ElementDezimalwertBinärwert
a10001
b20010
c40100
d81000

Wenn Sie dieser Spalte einen Wert von 9 zuweisen, ist das binär 1001. Daher werden der erste und der vierte SET-Wert, die Elemente "a" und "d", ausgewählt, und der Ergebniswert ist "a,d".

Bei einem Wert, der mehr als ein SET-Element enthält, spielt es keine Rolle, in welcher Reihenfolge die Elemente aufgelistet sind, wenn Sie den Wert einfügen. Es spielt ebenfalls keine Rolle, wie oft ein gegebenes Element im Wert aufgelistet ist. Wenn der Wert später abgerufen wird, erscheint jedes Element im Wert einmal, wobei die Elemente in der Reihenfolge erscheinen, in der sie bei der Tabellenerzeugung festgelegt wurden. Wenn eine Spalte beispielsweise als SET("a","b","c","d") festgelegt ist, erscheinen "a,d", "d,a" und "d,a,a,d,d" als "a,d", wenn sie abgerufen werden.

SET-Werte werden numerisch sortiert. NULL-Werte werden vor Nicht-NULL-SET-Werten einsortiert.

Normalerweise führt man SELECT auf eine SET-Spalte mit dem LIKE-Operator oder der FIND_IN_SET()-Funktion aus:

mysql> SELECT * FROM tabelle WHERE set_spalte LIKE '%wert%';
mysql> SELECT * FROM tabelle WHERE FIND_IN_SET('wert',set_spalte)>0;

Aber auch folgendes funktioniert:

mysql> SELECT * FROM tabelle WHERE set_spalte = 'wert1,wert2';
mysql> SELECT * FROM tabelle WHERE set_spalte & 1;

Das erste dieser Statements sucht nach einer exakten Übereinstimmung, das zweite sucht Werte, die das erste SET-Element enthalten.

Wenn Sie alle möglichen Werte einer SET-Spalte erhalten wollen, benutzen Sie: SHOW COLUMNS FROM tabelle LIKE set_spalte und gehen die SET-Definition in der zweiten Spalte durch.

7.2.4. Den richtigen Typ für eine Spalte auswählen

Um möglichst effizient zu speichern, benutzen Sie in jedem Fall den präzisesten Typ. Wenn zum Beispiel eine Ganzzahl-Spalte für Werte im Bereich zwischen 1 und 99999 benutzt wird, ist MEDIUMINT UNSIGNED der beste Typ.

Akkurate Darstellung monetärer Werte ist ein häufiges Problem. In MySQL sollten Sie den DECIMAL-Typ benutzen. Dieser wird als Zeichenkette gepeichert, weshalb kein Genauigkeitsverlust auftreten sollte. Wenn Genauigkeit nicht allzu wichtig ist, sollte auch der DOUBLE-Typ ausreichen.

Um hohe Präzision zu erzielen, können Sie immer auch in einen Festkommawert umwandeln, der in einer BIGINT gespeichert wird. Das erlaubt Ihnen, alle Berechnungen mit Ganzzahlen durchzuführen und die Ergebnisse nur wenn notwendig in Fließkommawerte zurückzuwandeln.

7.2.5. Spaltentypen anderer Datenbanken benutzen

Um es einfacher zu machen, Code zu verwenden, der für SQL-Implementationen anderer Hersteller geschrieben wurde, ordnet (mappt) MySQL Spaltentypen zu wie in unten stehender Tabelle dargestellt. Diese Mappings machen es leichter, Tabellendefinitionen anderer Datenbanken nach MySQL zu verschieben:

Typ anderer HerstellerMySQL-Typ
BINARY(NUM)CHAR(NUM) BINARY
CHAR VARYING(NUM)VARCHAR(NUM)
FLOAT4FLOAT
FLOAT8DOUBLE
INT1TINYINT
INT2SMALLINT
INT3MEDIUMINT
INT4INT
INT8BIGINT
LONG VARBINARYMEDIUMBLOB
LONG VARCHARMEDIUMTEXT
MIDDLEINTMEDIUMINT
VARBINARY(NUM)VARCHAR(NUM) BINARY

Dass Zuordnen (Mapping) von Spaltentypen geschieht bei der Erzeugung der Tabelle. Wenn Sie eine Tabelle mit Typen erzeugen, die von anderen Herstellern benutzt werden, und dann ein DESCRIBE tabelle-Statement absetzen, zeigt MySQL die Tabellenstruktur mit den äquivalenten MySQL-Typen an.

7.2.6. Speicherbedarf von Spaltentypen

Der Speicherbedarf jedes Spaltentyps, der von MySQL unterstützt wird, ist unten nach Kategorie sortiert aufgelistet:

Speicherbedarf für numerische Typen

SpaltentypSpeicherbedarf
TINYINT1 Byte
SMALLINT2 Bytes
MEDIUMINT3 Bytes
INT4 Bytes
INTEGER4 Bytes
BIGINT8 Bytes
FLOAT(X)4, wenn X <= 24, oder 8, wenn 25 <= X <= 53
FLOAT4 Bytes
DOUBLE8 Bytes
DOUBLE PRECISION8 Bytes
REAL8 Bytes
DECIMAL(M,D)M+2 Bytes, wenn D > 0, M+1 Bytes, wenn D = 0 (D+2, wenn M < D)
NUMERIC(M,D)M+2 Bytes, wenn D > 0, M+1 Bytes, wenn D = 0 (D+2, wenn M < D)

Speicherbedarf für Datums- und Zeit-Typen

SpaltentypSpeicherbedarf
DATE3 Bytes
DATETIME8 Bytes
TIMESTAMP4 Bytes
TIME3 Bytes
YEAR1 Byte

Speicherbedarf für Zeichenketten-Typen

SpaltentypSpeicherbedarf
CHAR(M)M Bytes, 1 <= M <= 255
VARCHAR(M)L+1 Bytes, wobei L <= M und 1 <= M <= 255
TINYBLOB, TINYTEXTL+1 Bytes, wobei L < 2^8
BLOB, TEXTL+2 Bytes, wobei L < 2^16
MEDIUMBLOB, MEDIUMTEXTL+3 Bytes, wobei L < 2^24
LONGBLOB, LONGTEXTL+4 Bytes, wobei L < 2^32
ENUM('wert1','wert2',...)1 oder 2 Bytes, abhängig von der Anzahl der Aufzählungswerte (65535 Werte maximal)
SET('wert1','wert2',...)1, 2, 3, 4 oder 8 Bytes, abhängig von der Anzahl von SET-Elementen (64 Elemente maximal)

VARCHAR und die BLOB- und TEXT-Typen sind Typen variabler Länge, bei denen der Speicherbedarf von der tatsächlichen Länge der Spaltenwerte abhängt (in der vorstehenden Tabelle dargestellt durch L) statt von der maximal möglichen Größe des Typs. VARCHAR(10) zum Beispiel kann eine Zeichenkette mit einer maximalen Länge von 10 Zeichen enthalten. Der tatsächliche Speicherbedarf ist die Länge der Zeichenkette (L) plus 1 Byte, um die Länge zu speichern. Bei der Zeichenkette 'abcd' ist L 4 und der Speicherbedarf 5 Bytes.

Die BLOB- und TEXT-Typen benötigen 1, 2, 3 oder 4 Bytes, um die Länge des Spaltenwerts zu speichern, abhängig von der maximal möglichen Länge des Typs. See Abschnitt 7.2.3.2, „Die BLOB- und TEXT-Typen“.

Wenn eine Tabelle irgend welche Spaltentypen variabler Länge enthält, ist das Datensatzformat ebenfalls von variabler Länge. Beachten Sie, dass MySQL bei der Erzeugung einer Tabelle unter bestimmten Umständen eine Spalte eines Typs variabler Länge in einen Typ fester Länge umwandelt, und umgekehrt. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“.

Die Größe eines ENUM-Objekts hängt von der Anzahl unterschiedlicher Aufzählungswerte ab. Bei Aufzählungen mit bis zu 255 möglichen Werten wird 1 Byte benutzt, bei Aufzählungen mit bis zu 65535 Werten 2 Bytes. See Abschnitt 7.2.3.3, „Der ENUM-Typ“.

Die Größe eines SET-Objekts hängt von der Anzahl unterschiedlicher SET-Elemente ab. Wenn die SET-Größe N ist, belegt das Objekt (N+7)/8 Bytes, gerundet auf 1, 2, 3, 4 oder 8 Bytes. Ein SET kann maximal 64 Elemente besitzen. See Abschnitt 7.2.3.4, „Der SET-Typ“.

7.3. Funktionen für die Benutzung in SELECT- und WHERE-Klauseln

Ein select_ausdruck oder eine where_definition in einem SQL-Statement kann aus jedem beliebigen Ausdruck bestehen, der die unten beschriebenen Funktionen benutzt.

Ein Ausdruck, der NULL enthält, erzeugt immer einen NULL-Wert, wenn es in der Dokumentation für die Operatoren und Funktionen, die im Ausdruck vorkommen, nicht anders beschrieben ist.

HINWEIS: Zwischen Funktionsname und der folgenden Klammer darf kein Leerraum stehen. Das hilft dem MySQL-Parser, zwischen Funktionsaufrufen und Tabellen- oder Spaltenverweisen zu unterscheiden, die denselben Namen haben wie eine Funktion. Leerzeichen um Argumente herum sind dagegen zulässig.

Sie können MySQL zwingen, Leerzeichen nach dem Funktionsnamen zu akzeptieren, indem Sie mysqld mit --ansi starten oder CLIENT_IGNORE_SPACE bei mysql_connect(), benutzen, aber in diesem Fall werden alle Funktionsnamen zu reservierten Wörtern. See Abschnitt 2.7.2, „MySQL im ANSI-Modus laufen lassen“.

Der Kürze zuliebe sind die Ausgaben des mysql-Programms in gekürzter Form dargestellt. Daher wird

mysql> select MOD(29,9);
+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+
1 rows in set (0.00 sec)

wie folgt dargestellt:

mysql> select MOD(29,9);
        -> 2

7.3.1. Nicht typenspezifische Operatoren und Funktionen

7.3.1.1. Klammer

( ... )

Benutzen Sie Klammern, um die Reihenfolge der Auswertung in einem Ausdruck zu erzwingen. Beispiel:

mysql> select 1+2*3;
        -> 7
mysql> select (1+2)*3;
        -> 9

7.3.1.2. Vergleichsoperatoren

Vergleichsoperationen ergeben einen Wert von 1 (TRUE), 0 (FALSE) oder NULL. Diese Funktionen funktionieren sowohl bei Zahlen als auch bei Zeichenketten. Zeichenketten werden bei Bedarf automatisch in Zahlen und Zahlen in Zeichenketten umgewandelt (wie in Perl oder PHP).

MySQL führt Vergleiche nach folgenden Regeln durch:

  • Wenn ein oder beide Argumente NULL sind, ist das Ergebnis des Vergleichs NULL, ausser beim <=> Operator.

  • Wenn beide Argumente in einer Vergleichsoperation Zeichenketten sind, werden sie als Zeichenketten verglichen.

  • Wenn beide Argumente Ganzzahlen sind, werden sie als Ganzzahlen verglichen.

  • Hexadezimale Werte werden als binäre Zeichenketten behandelt, wenn sie nicht mit einer Zahl verglichen werden.

  • Wenn eins der Argumente eine TIMESTAMP- oder DATETIME-Spalte ist und das andere Argument eine Konstante, wird die Konstante in einen Zeitstempel umgewandelt, bevor der Vergleich durchgeführt wird. Das wird gemacht, um ODBC-freundlicher zu sein.

  • In allen anderen Fällen werden die Argumente als Fließkommazahlen verglichen.

Vorgabemäßig werden Zeichenketten-Vergleiche unabhängig von der verwendeten Groß-/Kleinschreibung durchgeführt, indem der aktuelle Zeichensatz benutzt wird (vorgabemäßig ISO-8859-1 Latin1, der auch für englisch exzellent funktioniert).

Die unten stehenden Beispiele erläutern die Umwandlung von Zeichenketten in Zahlen für Vergleichsoperationen:

mysql> SELECT 1 > '6x';
         -> 0
mysql> SELECT 7 > '6x';
         -> 1
mysql> SELECT 0 > 'x6';
         -> 0
mysql> SELECT 0 = 'x6';
         -> 1
  • =

    Gleich:

    mysql> select 1 = 0;
            -> 0
    mysql> select '0' = 0;
            -> 1
    mysql> select '0.0' = 0;
            -> 1
    mysql> select '0.01' = 0;
            -> 0
    mysql> select '.01' = 0.01;
            -> 1
    

  • <> , !=

    Ungleich:

    mysql> select '.01' <> '0.01';
            -> 1
    mysql> select .01 <> '0.01';
            -> 0
    mysql> select 'zapp' <> 'zappp';
            -> 1
    

  • <=

    Kleiner oder gleich:

    mysql> select 0.1 <= 2;
            -> 1
    

  • <

    Kleiner als:

    mysql> select 2 < 2;
            -> 0
    

  • >=

    Größer oder gleich:

    mysql> select 2 >= 2;
            -> 1
    

  • >

    Größer als:

    mysql> select 2 > 2;
            -> 0
    

  • <=>

    Null-sicheres gleich:

    mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
            -> 1 1 0
    

  • IS NULL , IS NOT NULL

    Testet, ob eine Wert NULL ist oder nicht:

    mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL;
            -> 0 0 1
    mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
            -> 1 1 0
    

  • ausdruck BETWEEN min AND max

    Wenn ausdruck größer oder gleich min ist und ausdruck kleiner oder gleich max ist, gibt BETWEEN 1 zurück, andernfalls 0. Das ist äquivalent zum Ausdruck (min <= ausdruck AND ausdruck <= max), wenn alle Argumente vom selben Typ sind. Das erste Argument (ausdruck) legt fest, wie der Vergleich durchgeführt wird:

    • Wenn ausdruck eine TIMESTAMP-, DATE- oder DATETIME-Spalte ist, werden MIN() und MAX() im selben Format formatiert als wären sie Konstanten.

    • Wenn ausdruck ein Zeichenketten-Ausdruck ohne Berücksichtigung der Groß-/Kleinschreibung ist, wird ein Zeichenkettenvergleich ohne Berücksichtigung der Groß-/Kleinschreibung durchgeführt.

    • Wenn ausdruck ein Zeichenketten-Ausdruck mit Berücksichtigung der Groß-/Kleinschreibung ist, wird ein Zeichenkettenvergleich mit Berücksichtigung der Groß-/Kleinschreibung durchgeführt.

    • Wenn ausdruck ist ein Ganzzahl-Ausdruck ist, wird ein Ganzzahlvergleich durchgeführt.

    • Ansonsten wird ein Fließkommazahlenvergleich durchgeführt.

    mysql> select 1 BETWEEN 2 AND 3;
            -> 0
    mysql> select 'b' BETWEEN 'a' AND 'c';
            -> 1
    mysql> select 2 BETWEEN 2 AND '3';
            -> 1
    mysql> select 2 BETWEEN 2 AND 'x-3';
            -> 0
    

  • ausdruck IN (wert,...)

    Gibt 1 zurück, wenn ausdruck einen Wert hat, der in der IN-Liste enthalten ist, ansonsten 0. Wenn alle Werte Konstanten sind, werden alle Werte gemäß dem Typ von ausdruck ausgewertet und sortiert. Danach wird ein Element mittels binärer Suche gesucht. Das heißt, dass IN sehr schnell ist, wenn die IN-Werteliste ausschließlich aus Konstanten besteht. Wenn ausdruck ein Zeichenketten-Ausdruck mit Berücksichtigung der Groß-/Kleinschreibung ist, wird der Zeichenkettenvergleich unter Berücksichtigung der Groß-/Kleinschreibung durchgeführt:

    mysql> select 2 IN (0,3,5,'wefwf');
            -> 0
    mysql> select 'wefwf' IN (0,3,5,'wefwf');
            -> 1
    

  • ausdruck NOT IN (wert,...)

    Dasselbe wie NOT (ausdruck IN (wert,...)).

  • ISNULL(ausdruck)

    Wenn ausdruck NULL ist, gibt ISNULL() 1 zurück, ansonsten 0:

    mysql> select ISNULL(1+1);
            -> 0
    mysql> select ISNULL(1/0);
            -> 1
    

    Beachten Sie, dass ein Vergleich von NULL-Werten mit = immer UNWAHR ergibt!

  • COALESCE(liste)

    Gibt das erste Nicht-NULL-Element in der Liste zurück:

    mysql> select COALESCE(NULL,1);
            -> 1
    mysql> select COALESCE(NULL,NULL,NULL);
            -> NULL
    

  • INTERVAL(N,N1,N2,N3,...)

    Gibt 0 zurück, wenn N < N1, 1, wenn N < N2 usw. Alle Argumente werden als Ganzzahlen behandelt. Es ist erforderlich, dass N1 < N2 < N3 < ... < Nn ist, damit diese Funktion korrekt funktioniert. Das liegt daran, dass eine (sehr schnelle) binäre Suche benutzt wird:

    mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
            -> 3
    mysql> select INTERVAL(10, 1, 10, 100, 1000);
            -> 2
    mysql> select INTERVAL(22, 23, 30, 44, 200);
            -> 0
    

Wenn Sie eine Zeichenkette, die Groß-/Kleinschreibung nicht berücksichtigt, mit einem der Standard-Operatoren vergleichen (=, <>..., aber nicht LIKE), werden Leerzeichen am Ende ignoriert:

mysql> select "a" ="A ";
        -> 1

7.3.1.3. Logische Operatoren

Alle logischen Funktionen geben 1 (TRUE), 0 (FALSE) oder NULL (unbekannt, was in den meisten Fällen dasselbe wie FALSE ist) zurück:

  • NOT , !

    Logisch NOT. Gibt 1 zurück, wenn das Argument 0 ist, ansonsten 0. Ausnahme: NOT NULL gibt NULL zurück:

    mysql> select NOT 1;
            -> 0
    mysql> select NOT NULL;
            -> NULL
    mysql> select ! (1+1);
            -> 0
    mysql> select ! 1+1;
            -> 1
    

    Das letzte Beispiel gibt 1 zurück, weil der Ausdruck auf dieselbe Art ausgewertet wird wie (!1)+1.

  • OR , ||

    Logisch OR. Gibt 1 zurück, wenn eins der Argumente nicht 0 und nicht NULL ist:

    mysql> select 1 || 0;
            -> 1
    mysql> select 0 || 0;
            -> 0
    mysql> select 1 || NULL;
            -> 1
    
    

  • AND , &&

    Logisch AND. Gibt 0 zurück, wenn eins der Argumente 0 oder NULL ist, ansonsten 1:

    mysql> select 1 && NULL;
            -> 0
    mysql> select 1 && 0;
            -> 0
    

7.3.1.4. Ablaufsteuerungsfunktionen

  • IFNULL(ausdruck1,ausdruck2)

    Wenn ausdruck1 nicht NULL ist, gibt IFNULL() ausdruck1 zurück, ansonsten ausdruck2. IFNULL() gibt einen numerischen oder einen Zeichenketten-Wert zurück, je nachdem, in welchem Zusammenhang es benutzt wird:

    mysql> select IFNULL(1,0);
            -> 1
    mysql> select IFNULL(NULL,10);
            -> 10
    mysql> select IFNULL(1/0,10);
            -> 10
    mysql> select IFNULL(1/0,'ja');
            -> 'ja'
    

  • NULLIF(ausdruck1,ausdruck2)

    Wenn ausdruck1 = ausdruck2 wahr ist, gibt die Funktion NULL zurück, ansonsten ausdruck1. Das ist dasselbe wie CASE WHEN x = y THEN NULL ELSE x END:

    mysql> select NULLIF(1,1);
            -> NULL
    mysql> select NULLIF(1,2);
            -> 1
    

    Beachten Sie, dass ausdruck1 in MySQL zweimal ausgewertet wird, wenn die Argumente gleich sind.

  • IF(ausdruck1,ausdruck2,ausdruck3)

    Wenn ausdruck1 TRUE ist (ausdruck1 <> 0 und ausdruck1 <> NULL), gibt IF() ausdruck2 zurück, ansonsten ausdruck3. IF() gibt einen numerischen oder einen Zeichenketten-Wert zurück, je nachdem, in welchem Zusammenhang es benutzt wird:

    mysql> select IF(1>2,2,3);
            -> 3
    mysql> select IF(1<2,'ja','nein');
            -> 'ja'
    mysql> select IF(strcmp('test','test1'),'nein','ja');
            -> 'nein'
    

    ausdruck1 wird als Ganzzahlwert ausgewertet, woraus folgt, dass Sie das Testen auf Fließkomma- oder Zeichenketten-Werte mit einer Vergleichsoperation durchführen sollten:

    mysql> select IF(0.1,1,0);
            -> 0
    mysql> select IF(0.1<>0,1,0);
            -> 1
    

    Im ersten Fall gibt IF(0.1) 0 zurück, weil 0.1 in einen Ganzzahlwert umgewandelt wird, wodurch es auf IF(0) getestet wird. Das ist vielleicht nicht das, was Sie erwarten. Im zweiten Fall testet der Vergleich den Original-Fließkommawert, um zu sehen, ob er nicht 0 ist. Das Ergebnis des Vergleichs wird als Ganzzahl benutzt.

    Der vorgabemäßige Rückgabewert von IF() (der eine Rolle spielen kann, wenn er in einer temporären Tabelle gespeichert wird), wird in MySQL-Version 3.23 wie folgt berechnet:

    AusdruckRückgabewert
    ausdruck2 oder ausdruck3 gibt Zeichenkette zurückZeichenkette
    ausdruck2 oder ausdruck3 gibt Fließkommawert zurückFließkommawert
    ausdruck2 oder ausdruck3 gibt Ganzzahl zurückGanzzahl
  • CASE wert WHEN [vergleichs-wert] THEN ergebnis [WHEN [vergleichs-wert] THEN ergebnis ...] [ELSE ergebnis] END , CASE WHEN [bedingung] THEN ergebnis [WHEN [bedingung] THEN ergebnis ...] [ELSE ergebnis] END

    Die erste Version gibt ergebnis zurück, wo wert=vergleichs-wert. Die zweite Version gibt das Ergebnis für die erste Bedingung zurück, die WAHR ist. Wenn es keinen übereinstimmenden Ergebniswert gab, wird das Ergebnis nach ELSE zurückgegeben. Wenn es keinen ELSE-Teil gibt, wird NULL zurückgegeben:

    mysql> SELECT CASE 1 WHEN 1 THEN "eins" WHEN 2 THEN "zwei" ELSE "mehr" END;
           -> "eins"
    mysql> SELECT CASE WHEN 1>0 THEN "wahr" ELSE "unwahr" END;
           -> "wahr"
    mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
           -> NULL
    

Der Typ des Rückgabewerts (INTEGER, DOUBLE oder STRING) ist derselbe wie der Typ des ersten zurückgegebenen Werts (der Ausdruck nach dem ersten THEN).

7.3.2. Zeichenketten-Funktionen

Funktionen für Zeichenkettenwerte geben NULL zurück, wenn die Länge des Ergebnisses größer wäre als der max_allowed_packet-Serverparameter. See Abschnitt 6.5.2, „Serverparameter tunen“.

Bei Funktionen, die mit Zeichenkettenpositionen arbeiten, wird die erste Position als 1 gezählt.

  • ASCII(zeichenkette)

    Gibt den ASCII-Code-Wert des äußersten linken Zeichens der Zeichenkette zeichenkette zurück. Gibt 0 zurück, wenn zeichenkette die leere Zeichenkette ist. Gibt NULL zurück, wenn zeichenkette NULL ist:

    mysql> select ASCII('2');
            -> 50
    mysql> select ASCII(2);
            -> 50
    mysql> select ASCII('dx');
            -> 100
    

    Siehe auch ORD()-Funktion.

  • ORD(zeichenkette)

    Wenn das äußerste linke Zeichen der Zeichenkette zeichenkette ein Multi-Byte-Zeichen ist, gibt diese Funktion den Code des Multi-Byte-Zeichens zurück, indem der ASCII-Code-Wert des Zeichens in folgendem Format zurückgegeben wird: ((erstes byte ASCII code)*256+(zweites byte ASCII code))[*256+drittes byte ASCII code...]. Wenn das äußerste linke Zeichen kein Multi-Byte-Zeichen ist, wird derselbe Wert wie bei der ASCII()-Funktion zurückgegeben:

    mysql> select ORD('2');
            -> 50
    

  • CONV(N,von_basis,zu_basis)

    Wandelt Zahlen zwischen verschiedenen Zahlsystemen um. Gibt eine Zeichenkettendarstellung der Zahl N zurück, umgewandelt von Basis von_basis zu Basis zu_basis. Gibt NULL zurück, wenn irgend ein Argument NULL ist. Das Argument N wird als Ganzzahl interpretiert, kann aber als Ganzzahl oder Zeichenkette angegeben werden. Die kleinste Basis ist 2 und die größte Basis 36. Wenn zu_basis eine negative Zahl ist, wird N als vorzeichenbehaftete Zahl betrachtet. Ansonsten wird N als vorzeichenlos behandelt. CONV arbeitet mit 64-Bit-Genauigkeit:

    mysql> select CONV("a",16,2);
            -> '1010'
    mysql> select CONV("6E",18,8);
            -> '172'
    mysql> select CONV(-17,10,-18);
            -> '-H'
    mysql> select CONV(10+"10"+'10'+0xa,10,10);
            -> '40'
    

  • BIN(N)

    Gibt eine Zeichenkettendarstellung des Binärwerts von N zurück, wobei N eine BIGINT-Zahl ist. Das ist äquivalent zu CONV(N,10,2). Gibt NULL zurück, wenn N NULL ist:

    mysql> select BIN(12);
            -> '1100'
    

  • OCT(N)

    Gibt eine Zeichenkettendarstellung des Oktalwerts von N zurück, wobei N eine BIGINT-Zahl ist. Das ist äquivalent zu CONV(N,10,8). Gibt NULL zurück, wenn N NULL ist:

    mysql> select OCT(12);
            -> '14'
    

  • HEX(N)

    Gibt eine Zeichenkettendarstellung des hexadezimalen Werts von N zurück, wobei N eine BIGINT-Zahl ist. Das ist äquivalent zu CONV(N,10,16). Gibt NULL zurück, wenn N NULL ist:

    mysql> select HEX(255);
            -> 'FF'
    

  • CHAR(N,...)

    CHAR() interpretiert die Argumente als Ganzzahlen und gibt eine Zeichenkette zurück, die aus den Zeichen besteht, die durch die ASCII-Code-Werte dieser Ganzzahlen gegeben sind. NULL-Werte werden übersprungen:

    mysql> select CHAR(77,121,83,81,'76');
            -> 'MySQL'
    mysql> select CHAR(77,77.3,'77.3');
            -> 'MMM'
    

  • CONCAT(zeichenkette1,zeichenkette2,...)

    Gibt die Zeichenkette zurück, die durch die Verkettung der Argumente entsteht. Gibt NULL zurück, wenn irgend ein Argument NULL ist. Kann mehr als 2 Argumente haben. Ein numerisches Argument wird in die äquivalente Zeichenkettenform umgewandelt:

    mysql> select CONCAT('My', 'S', 'QL');
            -> 'MySQL'
    mysql> select CONCAT('My', NULL, 'QL');
            -> NULL
    mysql> select CONCAT(14.3);
            -> '14.3'
    

  • CONCAT_WS(trennzeichen, zeichenkette1, zeichenkette2,...)

    CONCAT_WS() steht für CONCAT mit Trennzeichen und ist eine spezielle Form von CONCAT(). Das erste Argument ist das Trennzeichen für die restlichen Argumente. Das Trennzeichen kann eine Zeichenkette sein, so wie die übrigen Argumente. Wenn das Trennzeichen NULL ist, ist das Ergebnis NULL. Die Funktion überspringt jegliche NULLs und leere Zeichenketten nach dem Trennzeichen-Argument. Das Trennzeichen wird zwischen den zu verknüpfenden Zeichenketten hinzugefügt:

    mysql> select CONCAT_WS(",","Vorname","Zweiter Vorname","Nachname");
           -> 'Vorname,Zweiter Vorname,Nachname'
    mysql> select CONCAT_WS(",","Vorname",NULL,"Nachname");
           -> 'Vorname,Nachname'
    

  • LENGTH(zeichenkette) , OCTET_LENGTH(zeichenkette) , CHAR_LENGTH(zeichenkette) , CHARACTER_LENGTH(zeichenkette)

    Gibt die Länge der Zeichenkette zeichenkette an:

    mysql> select LENGTH('text');
            -> 4
    mysql> select OCTET_LENGTH('text');
            -> 4
    

    Beachten Sie, dass bei CHAR_LENGTH() Multi-Byte-Zeichen nur einmal gezählt werden.

  • LOCATE(teilzeichenfolge,zeichenkette) , POSITION(teilzeichenfolge IN zeichenkette)

    Gibt die Position des ersten Auftretens der Teilzeichenfolge teilzeichenfolge in der Zeichenkette zeichenkette an. Gibt 0 zurück, wenn teilzeichenfolge nicht in zeichenkette enthalten ist:

    mysql> select LOCATE('bar', 'foobarbar');
            -> 4
    mysql> select LOCATE('xbar', 'foobar');
            -> 0
    

    Diese Funktion ist Multi-Byte-sicher.

  • LOCATE(teilzeichenfolge,zeichenkette,position)

    Gibt die Position des ersten Auftretens der Teilzeichenfolge teilzeichenfolge in der Zeichenkette zeichenkette ab Position position an. Gibt 0 zurück, wenn teilzeichenfolge nicht in zeichenkette enthalten ist:

    mysql> select LOCATE('bar', 'foobarbar',5);
            -> 7
    

    Diese Funktion ist Multi-Byte-sicher.

  • INSTR(zeichenkette,teilzeichenfolge)

    Gibt die Position des ersten Auftretens der Teilzeichenfolge teilzeichenfolge in der Zeichenkette zeichenkette an. Das ist dasselbe wie LOCATE() mit zwei Argumenten, ausser dass die Argumente vertauscht sind:

    mysql> select INSTR('foobarbar', 'bar');
            -> 4
    mysql> select INSTR('xbar', 'foobar');
            -> 0
    

    Diese Funktion ist Multi-Byte-sicher.

  • LPAD(zeichenkette,laenge,fuellzeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, links aufgefüllt mit der Zeichenkette fuellzeichenkette, bis zeichenkette laenge Zeichen lang ist. Wenn zeichenkette länger als laenge ist, wird sie auf laenge Zeichen verkürzt.

    mysql> select LPAD('hi',4,'??');
            -> '??hi'
    

  • RPAD(zeichenkette,laenge,fuellzeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, rechts aufgefüllt mit der Zeichenkette fuellzeichenkette, bis zeichenkette laenge Zeichen lang ist. Wenn zeichenkette länger als laenge ist, wird sie auf laenge Zeichen verkürzt.

    mysql> select RPAD('hi',5,'?');
            -> 'hi???'
    

  • LEFT(zeichenkette,laenge)

    Gibt die äußersten linken laenge Zeichen der Zeichenkette zeichenkette zurück:

    mysql> select LEFT('foobarbar', 5);
            -> 'fooba'
    

    Diese Funktion ist Multi-Byte-sicher.

  • RIGHT(zeichenkette,laenge)

    Gibt die äußersten rechten laenge Zeichen der Zeichenkette zeichenkette zurück:

    mysql> select RIGHT('foobarbar', 4);
            -> 'rbar'
    

    Diese Funktion ist Multi-Byte-sicher.

  • SUBSTRING(zeichenkette,position,laenge) , SUBSTRING(zeichenkette FROM position FOR laenge) , MID(zeichenkette,position,laenge)

    Gibt eine laenge Zeichen lange Teilzeichenfolge der Zeichenkette zeichenkette ab Position position zurück. Die abweichende Form, die FROM benutzt, ist ANSI-SQL92-Syntax:

    mysql> select SUBSTRING('Heinzholger',5,6);
            -> 'zholge'
    

    Diese Funktion ist Multi-Byte-sicher.

  • SUBSTRING(zeichenkette,position) , SUBSTRING(zeichenkette FROM position)

    Gibt eine Teilzeichenfolge der Zeichenkette zeichenkette ab Position position zurück:

    mysql> select SUBSTRING('Heinzholger',5);
            -> 'zholger'
    mysql> select SUBSTRING('foobarbar' FROM 4);
            -> 'barbar'
    

    Diese Funktion ist Multi-Byte-sicher.

  • SUBSTRING_INDEX(zeichenkette,begrenzer,zaehler)

    Gibt die Teilzeichenfolge von Zeichenkette zeichenkette vor zaehler Vorkommen des Begrenzers begrenzer zurück. Wenn zaehler positiv ist, wird alle links vom letzten Begrenzer zurückgegeben (von links gezählt). Wenn zaehler negativ ist, wird alles rechts vom letzten Begrenzer (von rechts gezählt) zurückgegeben:

    mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
            -> 'www.mysql'
    mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
            -> 'mysql.com'
    

    Diese Funktion ist Multi-Byte-sicher.

  • LTRIM(zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, bei der führende Leerzeichen entfernt wurden:

    mysql> select LTRIM('  barbar');
            -> 'barbar'
    

  • RTRIM(zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, bei der Leerzeichen am Ende entfernt wurden:

    mysql> select RTRIM('barbar   ');
            -> 'barbar'
    

    Diese Funktion ist Multi-Byte-sicher.

  • TRIM([[BOTH | LEADING | TRAILING] [entfernzeichenkette] FROM] zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, bei der alle entfernzeichenkette-Präfixe und / oder -Suffixe entfernt wurden. Wenn keiner der Spezifizierer BOTH, LEADING oder TRAILING angegeben wird, wird BOTH angenommen. Wenn entfernzeichenkette nicht angegeben ist, werden Leerzeichen entfernt:

    mysql> select TRIM('  bar   ');
            -> 'bar'
    mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
            -> 'barxxx'
    mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
            -> 'bar'
    mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
            -> 'barx'
    

    Diese Funktion ist Multi-Byte-sicher.

  • SOUNDEX(zeichenkette)

    Gibt eine Soundex-Zeichenkette von zeichenkette zurück. Zwei Zeichenketten, die fast gleich klingen, sollten identische Soundex-Zeichenketten haben. Eine Standard-Soundex-Zeichenkette ist 4 Zeichen lang, aber die SOUNDEX()-Funktion gibt eine beliebig lange Zeichenkette zurück. Sie können SUBSTRING() auf das Ergebnis anwenden, um eine Standard-Soundex-Zeichenkette zu erhalten. Alle nicht alphanumerischen Zeichen in der angegebenen Zeichenkette werden ignoriert. Alle internationalen alphabetischen Zeichen ausserhalb des Wertebereichs A bis Z werden als Vokale behandelt:

    mysql> select SOUNDEX('Hello');
            -> 'H400'
    mysql> select SOUNDEX('Quadratically');
            -> 'Q36324'
    

  • SPACE(N)

    Gibt eine Zeichenkette zurück, die aus N Leerzeichen besteht:

    mysql> select SPACE(6);
            -> '      '
    

  • REPLACE(zeichenkette,von_zeichenkette,zu_zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, bei der alle Vorkommen der Zeichenkette von_zeichenkette durch die Zeichenkette zu_zeichenkette ersetzt wurden:

    mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
            -> 'WwWwWw.mysql.com'
    

    Diese Funktion ist Multi-Byte-sicher.

  • REPEAT(zeichenkette,zaehler)

    Gibt eine Zeichenkette zurück, die aus der Zeichenkette zeichenkette besteht, die zaehler mal wiederholt wurde. Wenn zaehler <= 0 ist, wird eine leere Zeichenkette zurückgegeben. Gibt NULL zurück, wenn zeichenkette oder zaehler NULL sind:

    mysql> select REPEAT('MySQL', 3);
            -> 'MySQLMySQLMySQL'
    

  • REVERSE(zeichenkette)

    Gibt die Zeichenkette zeichenkette in umgedrehter Reihenfolge der Zeichen zurück:

    mysql> select REVERSE('abc');
            -> 'cba'
    

    Diese Funktion ist Multi-Byte-sicher.

  • INSERT(zeichenkette,position,laenge,neue_zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, wobei eine Teilzeichenfolge ab Position position mit laenge Zeichen Länge durch die Zeichenkette neue_zeichenkette ersetzt wurde:

    mysql> select INSERT('Heinzholger', 6, 4, 'DIET');
            -> 'HeinzDIETer'
    

    Diese Funktion ist Multi-Byte-sicher.

  • ELT(N,zeichenkette1,zeichenkette2,zeichenkette3,...)

    Gibt zeichenkette1 zurück, wenn N = 1 ist, zeichenkette2, wenn N = 2 ist usw.. Gibt NULL zurück, wenn N kleiner als 1 oder größer als die Anzahl von Argumenten ist. ELT() ist das Komplement von FIELD():

    mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
            -> 'ej'
    mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
            -> 'foo'
    

  • FIELD(zeichenkette,zeichenkette1,zeichenkette2,zeichenkette3,...)

    Gibt den Index von zeichenkette in der Liste zeichenkette1, zeichenkette2, zeichenkette3, ... zurück. Gibt 0 zurück, wenn zeichenkette nicht gefunden wird. FIELD() ist das Komplement von ELT():

    mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
            -> 2
    mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
            -> 0
    

  • FIND_IN_SET(zeichenkette,zeichenkettenliste)

    Gibt einen Wert 1 bis N zurück, wenn die Zeichenkette zeichenkette in der Liste zeichenkettenliste ist, die aus N Teilzeichenfolgen besteht. Eine Zeichenkettenliste ist eine Zeichenkette, die aus Teilzeichenfolgen zusammen gesetzt ist, die durch ‘,’-Zeichen getrennt sind. Wenn das erste Argument eine Zeichenketten-Konstante ist und das zweite eine Spalte des Typs SET, wird die FIND_IN_SET()-Funktion optimiert, Bit-Arithmetik zu benutzen! Gibt 0 zurück, wenn zeichenkette nicht in zeichenkettenliste ist oder wenn zeichenkettenliste die leere Zeichenkette ist. Gibt NULL zurück, wenn eines oder beide Argumente NULL sind. Diese Funktion funktioniert nicht korrekt, wenn das erste Argument ein ‘,’ enthält:

    mysql> SELECT FIND_IN_SET('b','a,b,c,d');
            -> 2
    

  • MAKE_SET(bits,zeichenkette1,zeichenkette2,...)

    Gibt einen Satz (eine Zeichenkette, die Teilzeichenfolgen enthält, die durch ‘,’ getrennt sind) zurück, der aus Zeichenketten besteht, die das entsprechende Bit in bits gesetzt haben. zeichenkette1 entspricht Bit 0, zeichenkette2 Bit 1 usw. NULL-Zeichenketten in zeichenkette1, zeichenkette2 usw. werden nicht an das Ergebnis angehängt:

    mysql> SELECT MAKE_SET(1,'a','b','c');
            -> 'a'
    mysql> SELECT MAKE_SET(1 | 4,'hallo','liebe','welt');
            -> 'hallo,welt'
    mysql> SELECT MAKE_SET(0,'a','b','c');
            -> ''
    

  • EXPORT_SET(bits,an,aus,[trennzeichen,[anzahl_bits]])

    Gibt eine Zeichenkette zurück, in der Sie für jedes bit, das in 'bit' gesetzt ist, eine 'an'-Zeichenkette erhalten, und für jedes zurückgesetzte Bit eine 'aus'-Zeichenkette. Jede Zeichenkette wird mit 'trennzeichen' getrennt (vorgabemäßig ','), und nur die 'anzahl_bits' (vorgabemäßig 64) von 'bits' wird benutzt:

    mysql> select EXPORT_SET(5,'Y','N',',',4)
            -> Y,N,Y,N
    

  • LCASE(zeichenkette) , LOWER(zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, bei der alle Zeichen in Kleinschreibung gemäß dem aktuellen Zeichensatz-Mapping (Vorgabe ist ISO-8859-1 Latin1) umgewandelt wurden:

    mysql> select LCASE('HEINZholger');
            -> 'heinzholger'
    

    Diese Funktion ist Multi-Byte-sicher.

  • UCASE(zeichenkette) , UPPER(zeichenkette)

    Gibt die Zeichenkette zeichenkette zurück, bei der alle Zeichen in Großschreibung gemäß dem aktuellen Zeichensatz-Mapping (Vorgabe ist ISO-8859-1 Latin1) umgewandelt wurden:

    mysql> select UCASE('Hej');
            -> 'HEJ'
    

    Diese Funktion ist Multi-Byte-sicher.

  • LOAD_FILE(datei)

    Liest die Datei datei und gibt den Dateiinhalt als Zeichenkette zurück. Die Datei muss auf dem Server sein, Sie müssen den vollen Pfadnamen zur Datei angeben und Sie müssen die file-Berechtigung besitzen. Die Datei muss von allen lesbar sein und kleiner als max_allowed_packet.

    Wenn die Datei nicht existiert oder aus den oben genannten Gründen nicht gelesen werden kann, gibt die Funktion NULL zurück:

    mysql> UPDATE tabelle
               SET blob_spalte=LOAD_FILE("/tmp/bild")
               WHERE id=1;
    

Wenn Sie nicht MySQL-Version 3.23 benutzen, müssen Sie das Lesen der Datei innerhalb Ihrer Applikation durchführen und ein INSERT-Statement erzeugen, um die Datenbank mit der Dateiinformation zu aktualisieren. Eine Art, das zu tun, finden Sie - wenn Sie die MySQL++-Bibliothek benutzen - unter http://www.mysql.com/documentation/mysql++/mysql++-examples.html.

MySQL konvertiert Zahlen bei Bedarf automatisch in Zeichenketten, und umgekehrt:

mysql> SELECT 1+"1";
        -> 2
mysql> SELECT CONCAT(2,' test');
        -> '2 test'

Wenn Sie eine Zahl explizit in eine Zeichenkette umwandeln wollen, übergeben Sie sie als Argument an CONCAT().

Wenn in einer Zeichenketten-Funktion eine binäre Zeichenkette als Argument angegeben wird, ist die resultierende Zeichenkette ebenfalls eine binäre Zeichenkette. Eine Zahl, die in eine Zeichenkette umgewandelt wird, wird als binäre Zeichenkette behandelt. Das betrifft nur Vergleichsoperationen.

7.3.2.1. Zeichenketten-Vergleichsfunktionen

Normalerweise wird ein Vergleich unter Berücksichtigung der Groß-/Kleinschreibung durchgeführt, wenn irgend ein Ausdruck in einem Zeichenkettenvergleich abhängig von der verwendeten Groß-/Kleinschreibung ist.

  • ausdruck LIKE muster [ESCAPE 'fluchtzeichen']

    Mustervergleich, der den einfachen SQL-Vergleich mit regulären Ausdrücken benutzt. Gibt 1 (TRUE) oder 0 (FALSE) zurück. Bei LIKE können Sie die folgenden zwei Platzhalterzeichen im Muster benutzen:

    %Entspricht einer beliebigen Anzahl von Zeichen, selbst 0 Zeichen
    _Entspricht genau einem Zeichen

    mysql> select 'David!' LIKE 'David_';
            -> 1
    mysql> select 'David!' LIKE '%D%v%';
            -> 1
    

    Um auf literale Instanzen des Platzhalterzeichens zu testen, stellen Sie dem Zeichen ein Fluchtzeichen (Escape-Zeichen) voran. Wenn Sie das ESCAPE-Zeichen nicht angeben, wird ‘\’ angenommen:

    \%Entspricht einem %-Zeichen
    \_Entspricht einem _-Zeichen

    mysql> select 'David!' LIKE 'David\_';
            -> 0
    mysql> select 'David_' LIKE 'David\_';
            -> 1
    

    Um ein anderes Fluchtzeichen (Escape-Zeichen) anzugeben, benutzen Sie die ESCAPE-Klausel:

    mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
            -> 1
    

    Die folgenden beiden Statements zeigen, dass Zeichenketten-Vergleiche die Groß-/Kleinschreibung nicht berücksichtigen, solange nicht einer der Operanden eine binäre Zeichenkette ist: case insensitive unless one of the operands ist a binäre Zeichenkette:

    mysql> select 'abc' LIKE 'ABC';
            -> 1
    mysql> SELECT 'abc' LIKE BINARY 'ABC';
            -> 0
    

    LIKE ist bei numerischen Ausdrücken zulässig! (Das ist eine MySQL-Erweiterung zum ANSI-SQL-LIKE.)

    mysql> select 10 LIKE '1%';
            -> 1
    

    HINWEIS: Weil MySQL die C Escape-Syntax in Zeichenketten benutzt (beispielsweise ‘\n’), müssen Sie jedes ‘\’-Zeichen, das Sie in LIKE-Zeichenketten benutzen, verdoppeln. Um zum Beispiel nach ‘\n’ zu suchen, geben Sie ‘\\n’ ein. Um nach ‘\’ zu suchen, geben Sie ‘\\\\’ ein (die Backslashes werden einmal vom Parser entfernt und noch einmal, wenn der Mustervergleich durchgeführt wird, so dass letztlich ein einzelner Backslash übrig bleibt).

  • ausdruck NOT LIKE muster [ESCAPE 'fluchtzeichen']

    Dasselbe wie NOT (ausdruck LIKE muster [ESCAPE 'fluchtzeichen']).

  • ausdruck REGEXP muster , ausdruck RLIKE muster

    Führt einen Mustervergleich eines Zeichenkettenausdrucks ausdruck gegen ein Muster muster durch. Das Muster kann ein erweiterter regulärer Ausdruck sein. See Anhang F, Beschreibung der MySQL-Syntax für reguläre Ausdrücke. Gibt 1 zurück, wenn ausdruck mit muster übereinstimmt, ansonsten 0. RLIKE ist ein Synonym für REGEXP, was aus Gründen der mSQL-Kompatibilität zur Verfügung steht. HINWEIS: Weil MySQL die C-Escape-Syntax in Zeichenketten benutzt (beispielsweise ‘\n’), müssen Sie jeden ‘\’, den Sie in Ihren REGEXP-Zeichenketten benutzen, verdoppeln. Ab MySQL-Version 3.23.4 berücksichtigt REGEXP nicht die verwendete Groß-/Kleinschreibung für normale (nicht binäre) Zeichenketten:

    mysql> select 'Monty!' REGEXP 'm%y%%';
            -> 0
    mysql> select 'Monty!' REGEXP '.*';
            -> 1
    mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
            -> 1
    mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
            -> 1  0
    mysql> select "a" REGEXP "^[a-d]";
            -> 1
    

  • REGEXP und RLIKE benutzen den aktuellen Zeichensatz (vorgabemäßig ISO-8859-1 Latin1), wenn über den Typ eines Zeichens entschieden wird.

  • ausdruck NOT REGEXP muster , ausdruck NOT RLIKE muster

    Dasselbe wie NOT (ausdruck REGEXP muster).

  • STRCMP(ausdruck1,ausdruck2)

    STRCMP() gibt 0 zurück, wenn die Zeichenketten gleich sind, -1, wenn das erste Argument kleiner als das zweite ist (nach der aktuellen Sortierreihenfolge), und ansonsten 1:

    mysql> select STRCMP('text', 'text2');
            -> -1
    mysql> select STRCMP('text2', 'text');
            -> 1
    mysql> select STRCMP('text', 'text');
            -> 0
    

  • MATCH (spalte1,spalte2,...) AGAINST (ausdruck)

    MATCH ... AGAINST() wird für Volltextsuche benutzt und gibt die Relevanz zurück - ein Ähnlichkeitsmaß zwischen dem Text in den Spalten (spalte1,spalte2,...) und der Anfrage ausdruck. Die Relevanz ist eine positive Fließkommazahl. 0 Relevanz bedeutet keine Ähnlichkeit. Damit MATCH ... AGAINST() funktioniert, muss zuerst ein FULLTEXT-Index erzeugt werden. See Abschnitt 7.5.3, „CREATE TABLE-Syntax“. MATCH ... AGAINST() ist verfügbar ab MySQL-Version 3.23.23. Für Details und Benutzungsbeispiele siehe see Abschnitt 7.8, „MySQL-Volltextsuche“.

7.3.2.2. Groß-/Kleinschreibung

  • BINARY

    Der BINARY-Operator macht die folgende Zeichenkette zu einer binären Zeichenkette. Das ist eine einfache Möglichkeit, einen Spaltenvergleich zwangsweise in Abhängigkeit von der verwendeten Groß-/Kleinschreibung durchzuführen, selbst wenn die Spalte nicht als BINARY oder BLOB definiert ist:

    mysql> select "a" = "A";
            -> 1
    mysql> select BINARY "a" = "A";
            -> 0
    

    BINARY wurde in MySQL-Version 3.23.0 eingeführt.

    Beachten Sie, dass MySQL in manchen Fällen nicht in der Lage ist, den Index effizient zu benutzen, wenn Sie eine indizierte Spalte zu BINARY machen.

Wenn Sie ein Blob ohne Berücksichtigung der Groß-/Kleinschreibung vergleichen wollen, können Sie den Blob jederzeit in Großschreibung umwandeln, bevor Sie den Vergleich durchführen:

SELECT 'A' LIKE UPPER(blob_spalte) FROM tabelle;

Wir planen, bald Casting zwischen unterschiedlichen Zeichensätzen einzuführen, um Zeichenketten-Vergleiche noch flexibler zu machen.

7.3.3. Numerische Funktionen

7.3.3.1. Arithmetische Operationen

Es gibt die üblichen arithmetischen Operatoren. Beachten Sie, dass das Ergebnis im Falle von ‘-’, ‘+’ und ‘*’ mit BIGINT-Genauigkeit (64-Bit) berechnet wird, wenn beide Argumente Ganzzahlen sind!

  • +

    Addition:

    mysql> select 3+5;
            -> 8
    

  • -

    Subtraktion:

    mysql> select 3-5;
            -> -2
    

  • *

    Multiplication:

    mysql> select 3*5;
            -> 15
    mysql> select 18014398509481984*18014398509481984.0;
            -> 324518553658426726783156020576256.0
    mysql> select 18014398509481984*18014398509481984;
            -> 0
    

    Das Ergebnis des letzten Ausdrucks ist falsch, weil die Ganzzahl-Multiplikation den 64-Bit-Wertebereich von BIGINT-Berechnungen überschreitet.

  • /

    Division:

    mysql> select 3/5;
            -> 0.60
    

    Division durch 0 erzeugt ein NULL-Ergebnis:

    mysql> select 102/(1-1);
            -> NULL
    

    Eine Division wird nur dann mit BIGINT-Arithmetik berechnet, wenn sie in einem Zusammenhang durchgeführt wird, in dem das Ergebnis in eine Ganzzahl umgewandelt wird!

7.3.3.2. Mathematische Funktionen

Alle mathematischen Funktionen geben im Fehlerfall NULL zurück.

  • -

    Unäres Minus. Ändert das Vorzeichen des Arguments:

    mysql> select - 2;
            -> -2
    

    Wenn dieser Operator mit einer BIGINT benutzt wird, beachten Sie, dass der Rückgabewert eine BIGINT ist! Das bedeutet, dass Sie - auf Ganzzahlen, die den Wert -2^63 haben könnten, vermeiden sollten!

  • ABS(X)

    Gibt den absoluten Wert von X zurück:

    mysql> select ABS(2);
            -> 2
    mysql> select ABS(-32);
            -> 32
    

    Diese Funktion kann bei BIGINT-Werten sicher benutzt werden.

  • SIGN(X)

    Gibt das Vorzeichen des Arguments als -1, 0 oder 1 zurück, abhängig davon, ob X negativ, 0 oder positiv ist:

    mysql> select SIGN(-32);
            -> -1
    mysql> select SIGN(0);
            -> 0
    mysql> select SIGN(234);
            -> 1
    

  • MOD(N,M)

  • %

    Modulo (wie der %-Operator in C). Gibt den Rest von N dividiert durch M zurück:

    mysql> select MOD(234, 10);
            -> 4
    mysql> select 253% 7;
            -> 1
    mysql> select MOD(29,9);
            -> 2
    

    Diese Funktion kann bei BIGINT-Werten sicher benutzt werden.

  • FLOOR(X)

    Gibt den größten Ganzzahl-Wert zurück, der nicht größer als X ist:

    mysql> select FLOOR(1.23);
            -> 1
    mysql> select FLOOR(-1.23);
            -> -2
    

    Beachten Sie, dass der Rückgabewert in eine BIGINT umgewandelt wird!

  • CEILING(X)

    Gibt den kleinsten Ganzzahl-Wert zurück, der nicht kleiner als X ist:

    mysql> select CEILING(1.23);
            -> 2
    mysql> select CEILING(-1.23);
            -> -1
    

    Beachten Sie, dass der Rückgabewert in eine BIGINT umgewandelt wird!

  • ROUND(X)

    Gibt das Argument X zurück, gerundet auf die nächste Ganzzahl:

    mysql> select ROUND(-1.23);
            -> -1
    mysql> select ROUND(-1.58);
            -> -2
    mysql> select ROUND(1.58);
            -> 2
    

    Beachten Sie, dass das Verhalten von ROUND() abhängig von der C-Bibliothek-Implementation ist, wenn das Argument in der Mitte zwischen zwei Ganzzahlen liegt. Einige runden auf die nächste gerade Zahl, oder immer nach oben, immer nach unten oder immer Richtung 0. Wenn Sie eine bestimmte Art zu runden brauchen, sollten Sie statt dessen wohldefinierte Funktionen wie TRUNCATE() oder FLOOR() benutzen.

  • ROUND(X,D)

    Gibt das Argument X zurück, gerundet auf eine Zahl mit D Dezimalstellen. Wenn D 0 ist, hat das Ergebnis keinen Dezimalpunkt oder Bruchteil:

    mysql> select ROUND(1.298, 1);
            -> 1.3
    mysql> select ROUND(1.298, 0);
            -> 1
    

  • EXP(X)

    Gibt den Wert e (die Basis des natürlichen Logarithmus) hoch X zurück:

    mysql> select EXP(2);
            -> 7.389056
    mysql> select EXP(-2);
            -> 0.135335
    

  • LOG(X)

    Gibt den natürlichen Logarithmus von X zurück:

    mysql> select LOG(2);
            -> 0.693147
    mysql> select LOG(-2);
            -> NULL
    

    Wenn Sie den Logarithmus einer Zahl X zu einer beliebigen Basis B errechnen wollen, benutzen Sie die Formel LOG(X)/LOG(B).

  • LOG10(X)

    Gibt den Logarithmus zur Basis 10 von X zurück:

    mysql> select LOG10(2);
            -> 0.301030
    mysql> select LOG10(100);
            -> 2.000000
    mysql> select LOG10(-100);
            -> NULL
    

  • POW(X,Y) , POWER(X,Y)

    Gibt den Wert X hoch Y zurück:

    mysql> select POW(2,2);
            -> 4.000000
    mysql> select POW(2,-2);
            -> 0.250000
    

  • SQRT(X)

    Gibt die nicht negative Quadratwurzel von X zurück:

    mysql> select SQRT(4);
            -> 2.000000
    mysql> select SQRT(20);
            -> 4.472136
    

  • PI()

    Gibt den Wert PI zurück. Die vorgabemäßig angezeigte Anzahl von Dezimalstellen ist 5, aber MySQL benutzt intern die volle doppelte Genauigkeit für PI.

    mysql> select PI();
            -> 3.141593
    mysql> SELECT PI()+0.000000000000000000;
            -> 3.141592653589793116
    

  • COS(X)

    Gibt den Cosinus von X zurück, wobei X in Radianten angegeben wird:

    mysql> select COS(PI());
            -> -1.000000
    

  • SIN(X)

    Gibt den Sinus von X zurück, wobei X in Radianten angegeben wird:

    mysql> select SIN(PI());
            -> 0.000000
    

  • TAN(X)

    Gibt den Tangens von X zurück, wobei X in Radianten angegeben wird:

    mysql> select TAN(PI()+1);
            -> 1.557408
    

  • ACOS(X)

    Gibt den Arcuscosinus von X zurück, dass heißt den Wert, dessen Cosinus X ist. Gibt NULL zurück, wenn X nicht im Bereich von -1 bis 1 liegt:

    mysql> select ACOS(1);
            -> 0.000000
    mysql> select ACOS(1.0001);
            -> NULL
    mysql> select ACOS(0);
            -> 1.570796
    

  • ASIN(X)

    Gibt den Arcussinus von X zurück, das heißt den Wert, dessen Sinus X ist. Gibt NULL zurück, wenn X nicht im Bereich von -1 bis 1 liegt:

    mysql> select ASIN(0.2);
            -> 0.201358
    mysql> select ASIN('foo');
            -> 0.000000
    

  • ATAN(X)

    Gibt den Arcustangens von X zurück, das heißt den Wert, dessen Tangens X ist:

    mysql> select ATAN(2);
            -> 1.107149
    mysql> select ATAN(-2);
            -> -1.107149
    

  • ATAN2(Y,X)

    Gibt den Arcustangens der beiden Variablen X und Y zurück. Das ähnelt der Berechnung des Arcustangens von Y / X, ausser dass die Vorzeichen beider Argumente benutzt werden, um den Quadranten des Ergebnisses zu bestimmen:

    mysql> select ATAN(-2,2);
            -> -0.785398
    mysql> select ATAN(PI(),0);
            -> 1.570796
    

  • COT(X)

    Gibt den Cotangens von X zurück:

    mysql> select COT(12);
            -> -1.57267341
    mysql> select COT(0);
            -> NULL
    

  • RAND() , RAND(N)

    Gibt eine Zufallszahl (Fließkommawert) im Bereich von 0 bis 1.0 zurück. Wenn ein Ganzzahl-Argument N angegeben wird, wird es als Ausgangswert benutzt:

    mysql> select RAND();
            -> 0.5925
    mysql> select RAND(20);
            -> 0.1811
    mysql> select RAND(20);
            -> 0.1811
    mysql> select RAND();
            -> 0.2079
    mysql> select RAND();
            -> 0.7888
    

    Sie können eine Spalte mit RAND()-Werten nicht in einer ORDER BY-Klausel verwenden, weil ORDER BY die Spalte mehrfach auswerten würde. In MySQL-Version 3.23 können Sie jedoch folgendes tun: SELECT * FROM tabelle ORDER BY RAND()

    Das ist nützlich, um eine Zufallsstichprobe aus SELECT * FROM tabelle1,tabelle2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000 zu erhalten.

    Beachten Sie, dass ein RAND() in einer WHERE-Klausel jedes Mal von Neuem ausgewertet wird, wenn WHERE ausgeführt wird.

  • LEAST(X,Y,...)

    Mit zwei oder mehr Argumenten gibt die Funktion das kleinste Argument (das mit dem niedrigsten Wert) zurück. Die Argumente werden nach folgenden Regeln verglichen:

    • Wenn der Rückgabewert in einem INTEGER-Zusammenhang benutzt wird oder alle Argumente Ganzzahl-Werte sind, werden sie als Ganzzahlen verglichen.

    • Wenn der Rückgabewert in einem REAL-Zusammenhang benutzt wird oder alle Argumente Realzahlen sind, werden sie als Realzahlen verglichen.

    • Wenn irgend ein Argument eine von der Groß-/Kleinschreibung abhängige Zeichenkette ist, werden die Argumente als Zeichenketten, die von der Groß-/Kleinschreibung abhängen, verglichen.

    • In sonstigen Fällen werden die Argumente als Zeichenketten verglichen, die nicht von der Groß-/Kleinschreibung abhängen:

    mysql> select LEAST(2,0);
            -> 0
    mysql> select LEAST(34.0,3.0,5.0,767.0);
            -> 3.0
    mysql> select LEAST("B","A","C");
            -> "A"
    

    In MySQL-Versionen vor Version 3.22.5 können Sie MIN() statt LEAST benutzen.

  • GREATEST(X,Y,...)

    Gibt das größte Argument (das mit dem höchsten Wert) zurück. Die Argumente werden nach denselben Regeln wie bei LEAST verglichen:

    mysql> select GREATEST(2,0);
            -> 2
    mysql> select GREATEST(34.0,3.0,5.0,767.0);
            -> 767.0
    mysql> select GREATEST("B","A","C");
            -> "C"
    

    In MySQL-Versionen vor Version 3.22.5 können Sie MAX() statt GREATEST benutzen.

  • DEGREES(X)

    Gibt das Argument X zurück, von Radianten zu Grad umgewandelt:

    mysql> select DEGREES(PI());
            -> 180.000000
    

  • RADIANS(X)

    Gibt das Argument X zurück, von Grad zu Radianten umgewandelt:

    mysql> select RADIANS(90);
            -> 1.570796
    

  • TRUNCATE(X,D)

    Gibt die Zahl X zurück, auf D Dezimalstellen beschnitten. Wenn D 0 ist, hat das Ergebnis keinen Dezimalpunkt oder Bruchteil:

    mysql> select TRUNCATE(1.223,1);
            -> 1.2
    mysql> select TRUNCATE(1.999,1);
            -> 1.9
    mysql> select TRUNCATE(1.999,0);
            -> 1
    

    Beachten Sie, dass Dezimalzahlen in Computern normalerweise nicht als exakte Zahlen, sondern als Double-Werte gespeichert werden. Daher können verwirrende Ergebnisse wie im folgenden Beispiel auftreten:

    mysql> select TRUNCATE(10.28*100,0);
           -> 1027
    

    Das Obige passiert, weil 10.28 tatsächlich als etwas wie 10.2799999999999999 gespeichert wird.

7.3.4. Datums- und Zeit-Funktionen

Eine Beschreibung des Wertebereichs aller Typen und der gültigen Formate für Datums- und Zeitwerte finden Sie unter Abschnitt 7.2.2, „Datums- und Zeit-Typen“.

Hier ist ein Beispiel, das Datums-Funktionen benutzt. Die unten stehende Anfrage wählt alle Datensätze mit einem datum_spalte-Wert innerhalb der letzten 30 Tage aus:

mysql> SELECT etwas FROM tabelle
           WHERE TO_DAYS(NOW()) - TO_DAYS(datum_spalte) <= 30;
  • DAYOFWEEK(datum)

    Gibt den Wochentag-Index zurück.

    Für datum gilt: 1 = Sonntag, 2 = Montag, ... 7 = Samstag). Diese Index-Werte entsprechen dem ODBC-Standard:

    mysql> select DAYOFWEEK('1998-02-03');
            -> 3
    

  • WEEKDAY(datum)

    Gibt den Wochentag-Index für datum zurück (0 = Montag, 1 = Dienstag, ... 6 = Sonntag):

    mysql> select WEEKDAY('1997-10-04 22:23:00');
            -> 5
    mysql> select WEEKDAY('1997-11-05');
            -> 2
    

  • DAYOFMONTH(datum)

    Gibt den Tag des Monats für datum im Bereich 1 bis 31 zurück:

    mysql> select DAYOFMONTH('1998-02-03');
            -> 3
    

  • DAYOFYEAR(datum)

    Gibt den Tag des Jahres für datum im Bereich 1 bis 366 zurück:

    mysql> select DAYOFYEAR('1998-02-03');
            -> 34
    

  • MONTH(datum)

    Gibt den Monat für datum im Bereich 1 bis 12 zurück:

    mysql> select MONTH('1998-02-03');
            -> 2
    

  • DAYNAME(datum)

    Gibt den Namen des Wochentags für datum zurück (auf englisch):

    mysql> select DAYNAME("1998-02-05");
            -> 'Thursday'
    

  • MONTHNAME(datum)

    Gibt den Namen des Monats für datum zurück (auf englisch):

    mysql> select MONTHNAME("1998-02-05");
            -> 'February'
    

  • QUARTER(datum)

    Gibt das Quartal des Jahres für datum im Bereich 1 bis 4 zurück:

    mysql> select QUARTER('98-04-01');
            -> 2
    

  • WEEK(datum) , WEEK(datum,erste)

    Mit einem einzelnen Argument gibt diese Funktion die Woche für datum im Bereich 0 bis 53 zurück (ja, es kann Anfänge der Woche 53 geben), für Orte, in denen Sonntag der erste Wochentag ist. In der Form mit zwei Argumenten gestattet WEEK() es, festzulegen, ob die Woche am Sonntag oder am Montag beginnt. Die Woche beginnt am Sonntag, wenn das zweite Argument 0 ist, und am Montag, wenn das zweite Argument 1 ist:

    mysql> select WEEK('1998-02-20');
            -> 7
    mysql> select WEEK('1998-02-20',0);
            -> 7
    mysql> select WEEK('1998-02-20',1);
            -> 8
    mysql> select WEEK('1998-12-31',1);
            -> 53
    

  • YEAR(datum)

    Gibt das Jahr für datum im Bereich 1000 bis 9999 zurück:

    mysql> select YEAR('98-02-03');
            -> 1998
    

  • YEARWEEK(datum) , YEARWEEK(datum,erste)

    Gibt Jahr und Woche für ein Datum zurück. Das zweite Argument funktioniert genau wie das zweite Argument von WEEK(). Beachten Sie, dass das Jahr sich in der ersten und letzten Woche des Jahres vom Jahr im Datums-Argument unterscheiden kann:

    mysql> select YEARWEEK('1987-01-01');
            -> 198653
    

  • HOUR(zeit)

    Gibt die Stunde für zeit im Bereich 0 bis 23 zurück:

    mysql> select HOUR('10:05:03');
            -> 10
    

  • MINUTE(zeit)

    Gibt die Minute für zeit im Bereich 0 bis 59 zurück:

    mysql> select MINUTE('98-02-03 10:05:03');
            -> 5
    

  • SECOND(zeit)

    Gibt die Sekunde für zeit im Bereich 0 bis 59 zurück:

    mysql> select SECOND('10:05:03');
            -> 3
    

  • PERIOD_ADD(P,N)

    Zählt N Monate zur Periode P hinzu (im Format YYMM oder YYYYMM). Gibt einen Wert im Format YYYYMM zurück.

    Beachten Sie, dass das Perioden-Argument P kein Datums-Wert ist:

    mysql> select PERIOD_ADD(9801,2);
            -> 199803
    

  • PERIOD_DIFF(P1,P2)

    Gibt die Anzahl von Monaten zwischen den Perioden P1 und P2 zurück. P1 und P2 sollten im Format YYMM oder YYYYMM sein.

    Beachten Sie, dass die Perioden-Argumente P1 und P2 keine Datumswerte sind:

    mysql> select PERIOD_DIFF(9802,199703);
            -> 11
    

  • DATE_ADD(datum,INTERVAL ausdruck typ) , DATE_SUB(datum,INTERVAL ausdruck typ) , ADDDATE(datum,INTERVAL ausdruck typ) , SUBDATE(datum,INTERVAL ausdruck typ)

    Diese Funktionen führen Datumsberechnungen durch. Sie wurden in MySQL-Version 3.22 eingeführt. ADDDATE() und SUBDATE() sind Synonyme für DATE_ADD() und DATE_SUB().

    In MySQL-Version 3.23 können Sie + und - anstelle von DATE_ADD() und DATE_SUB() benutzen, wenn der Ausdruck auf der rechten Seite eine DATE oder DATETIME-Spalte ist (siehe Beispiel).

    datum ist ein DATETIME- oder DATE-Wert, der das Anfangsdatum festlegt. ausdruck ist ein Ausdruck, der den Intervallwert festlegt, der zum Anfangsdatum hinzugezählt oder von diesem abgezogen wird. ausdruck ist eine Zeichenkette; sie kann mit einem ‘-’ für negative Intervalle beginnen. typ ist ein Schlüsselwort, das angibt, wie der Ausdruck interpretiert werden soll.

    Die verwandte Funktion EXTRACT(typ FROM datum) gibt das 'typ'-Intervall des Datums zurück.

    Folgende Tabelle zeigt, in welchem Zusammenhang die typ- und ausdruck-Argumente stehen:

    typ werterwartet ausdruck format
    SECONDSekunden
    MINUTEMinuten
    HOURStunden
    DAYTage
    MONTHMonate
    YEARJahre
    MINUTE_SECOND"Minuten:Sekunden"
    HOUR_MINUTE"Stunden:Minuten"
    DAY_HOUR"Tage Stunden"
    YEAR_MONTH"Jahre-Monate"
    HOUR_SECOND"Stunden:Minuten:Sekunden"
    DAY_MINUTE"Tage Stunden:Minuten"
    DAY_SECOND"Tage Stunden:Minuten:Sekunden"

    MySQL erlaubt beliebige Satzzeichen-Begrenzer im ausdruck-Format. Die in der Tabelle gezeigten Begrenzer sind Vorschläge. Wenn das datum-Argument ein DATE-Wert ist und Ihre Berechnungen nur YEAR, MONTH und DAY-Anteile beinhalten (also keine Zeit-Anteile), ist das Ergebnis ein DATE-Wert. Ansonsten ist das Ergebnis ein DATETIME-Wert:

    mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
            -> 1998-01-01 00:00:00
    mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
            -> 1998-01-01
    mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
           -> 1997-12-31 23:59:59
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                           INTERVAL 1 SECOND);
            -> 1998-01-01 00:00:00
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                           INTERVAL 1 DAY);
            -> 1998-01-01 23:59:59
    mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                           INTERVAL "1:1" MINUTE_SECOND);
            -> 1998-01-01 00:01:00
    mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
                           INTERVAL "1 1:1:1" DAY_SECOND);
            -> 1997-12-30 22:58:59
    mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
                           INTERVAL "-1 10" DAY_HOUR);
            -> 1997-12-30 14:00:00
    mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
            -> 1997-12-02
    

    Wenn Sie einen Intervallwert angeben, der zu kurz ist (nicht alle Intervall-Anteile beinhaltet, die vom typ-Schlüsselwort erwartet werden), nimmt MySQL an, dass Sie den äußersten linken Teil des Intervallwerts ausgelassen haben. Wenn Sie beispielsweise einen typ DAY_SECOND angeben, wird vom Wert von ausdruck erwartet, dass dieser Tages-, Stunden-, Minuten- und Sekunden-Anteile enthält. Wenn Sie einen Wert wie "1:10" angeben, nimmt MySQL an, dass die Tages- und Stunden-Anteile fehlen und der Wert Minuten und Sekunden darstellt. Mit anderen Worten wird "1:10" DAY_SECOND so interpretiert, dass es äquivalent zu "1:10" MINUTE_SECOND ist. Das ist analog zur Weise, wie MySQL TIME-Werte interpretiert, die eher vergangene Zeit als Tageszeit darstellen.

    Beachten Sie, dass ein Datumswert automatisch in einen DATETIME-Wert umgewandelt wird, wenn Sie einen DATE-Wert zu etwas hinzuzählen oder von etwas abziehen, das einen Zeit-Anteil hat:

    mysql> select date_add("1999-01-01", interval 1 day);
           -> 1999-01-02
    mysql> select date_add("1999-01-01", interval 1 hour);
           -> 1999-01-01 01:00:00
    

    Wenn Sie wirklich falsche Datumsangaben benutzen, ist das Ergebnis NULL. Wenn Sie MONTH, YEAR_MONTH oder YEAR hinzuzählen und das Datumsergebnis einen Tag hat, der größer ist als der höchste Tag für den neuen Monat, wird der Tag auf den höchsten Tag des neuen Monats angepasst:

    mysql> select DATE_ADD('1998-01-30', Interval 1 month);
            -> 1998-02-28
    

    Beachten Sie, dass das Wort INTERVAL und das typ-Schlüsselwort in den vorstehenden Beispielen nicht von der verwendeten Groß-/Kleinschreibung abhängen.

  • EXTRACT(typ FROM datum)

    Die EXTRACT()-Funktion benutzt dieselbe Art von Intervalltyp-Spezifikatoren wie DATE_ADD() oder DATE_SUB(), extrahiert aber Anteile aus dem Datum, statt Datumsberechnungen durchzuführen:

    mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
           -> 1999
    mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
           -> 199907
    mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
           -> 20102
    

  • TO_DAYS(datum)

    Gibt für ein Datum datum eine Tagesanzahl zurück (die Anzahl von Tagen seit dem Jahr 0):

    mysql> select TO_DAYS(950501);
            -> 728779
    mysql> select TO_DAYS('1997-10-07');
            -> 729669
    

    TO_DAYS() ist nicht für die Benutzung mit Werten vor der Einführung des Gregorianischen Kalenders (1582) vorgesehen, weil es nicht die Tage berücksichtigt, die verloren gingen, als der Kalender geändert wurde.

  • FROM_DAYS(N)

    Gibt für eine Tagesanzahl N einen DATE-Wert zurück:

    mysql> select FROM_DAYS(729669);
            -> '1997-10-07'
    

    FROM_DAYS() ist nicht für die Benutzung mit Werten vor der Einführung des Gregorianischen Kalenders (1582) vorgesehen, weil es nicht die Tage berücksichtigt, die verloren gingen, als der Kalender geändert wurde.

  • DATE_FORMAT(datum,format)

    Formatiert den datum-Wert gemäß der format-Zeichenkette. Folgende Spezifikatoren können in der format-Zeichenkette benutzt werden:

    %MMonatsname auf englisch (January bis December)
    %WName des Wochentags auf englisch (Sunday bis Saturday)
    %DTag des Monats mit englischem Suffix (1st, 2nd, 3rd usw.)
    %YJahr, numerisch, 4 Ziffern
    %yJahr, numerisch, 2 Ziffern
    %XJahr der Woche, wobei Sonntag der erste Tag der Woche ist, numerisch, 4 Ziffern, benutzt mit '%V'
    %xJahr der Woche, wobei Montag der erste Tag der Woche ist, numerisch, 4 Ziffern, benutzt mit '%v'
    %aAbgekürzter Name des Wochentags auf englisch (Sun..Sat)
    %dTag des Monats, numerisch (00 bis 31)
    %eTag des Monats, numerisch (0 bis 31)
    %mMonat, numerisch (01 bis 12)
    %cMonat, numerisch (1 bis 12)
    %bAbgekürzter Monatsname auf englisch (Jan bis Dec)
    %jTag des Jahrs (001 bis 366)
    %HStunde (00 bis 23)
    %kStunde (0 bis 23)
    %hStunde (01 bis 12)
    %IStunde (01 bis 12)
    %lStunde (1 bis 12)
    %iMinuten, numerisch (00 bis 59)
    %rUhrzeit, 12-Stunden-Format (hh:mm:ss [AP]M)
    %TUhrzeit, 24-Stunden-Format (hh:mm:ss)
    %SSekunden (00 bis 59)
    %sSekunden (00 bis 59)
    %pAM oder PM
    %wWochentag (0=Sonntag bis 6=Samstag)
    %UWoche (0 bis 53), wobei Sonntag der erste Tag der Woche ist
    %uWoche (0 bis 53), wobei Montag der erste Tag der Woche ist
    %VWoche (1 bis 53), wobei Sonntag der erste Tag der Woche ist. Benutzt mit '%X'
    %vWoche (1 bis 53), wobei Montag der erste Tag der Woche ist. Benutzt mit '%x'
    %%Ein Literal ‘%’.

    Alle anderen Zeichen werden einfach ohne Interpretation ins Ergebnis kopiert:

    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W%M%Y');
            -> 'Saturday October 1997'
    mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
            -> '22:23:00'
    mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                              '%D%y%a%d%m%b%j');
            -> '4th 97 Sat 04 10 Oct 277'
    mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                              '%H%k%I%r%T%S%w');
            -> '22 22 10 10:23:00 PM 22:23:00 00 6'
    mysql> select DATE_FORMAT('1999-01-01', '%X%V');
            -> '1998 52'
    

    Ab MySQL-Version 3.23 ist das ‘%’-Zeichen vor Format-Spezifikator-Zeichen erforderlich. In früheren Versionen von MySQL war ‘%’ optional.

  • TIME_FORMAT(zeit,format)

    Dieses wird benutzt wie die obige DATE_FORMAT()-Funktion, aber die format-Zeichenkette darf nur die Spezifikatoren enthalten, die Stunden, Minuten und Sekunden handhaben. Andere Spezifikatoren erzeugen einen NULL-Wert oder 0.

  • CURDATE() , CURRENT_DATE

    Gibt das Datum von heute im 'YYYY-MM-DD'- oder YYYYMMDD-format zurück, abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

    mysql> select CURDATE();
            -> '1997-12-15'
    mysql> select CURDATE() + 0;
            -> 19971215
    

  • CURTIME() , CURRENT_TIME

    Gibt die aktuelle Zeit als einen Wert im 'HH:MM:SS'- oder HHMMSS-format zurück, abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

    mysql> select CURTIME();
            -> '23:50:26'
    mysql> select CURTIME() + 0;
            -> 235026
    

  • NOW() , SYSDATE() , CURRENT_TIMESTAMP

    Gibt das aktuelle Datum und die aktuelle Zeit als einen Wert im 'YYYY-MM-DD HH:MM:SS'- oder YYYYMMDDHHMMSS-Format zurück, abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

    mysql> select NOW();
            -> '1997-12-15 23:50:26'
    mysql> select NOW() + 0;
            -> 19971215235026
    

  • UNIX_TIMESTAMP() , UNIX_TIMESTAMP(datum)

    Ohne Argument aufgerufen gibt die Funktion einen Unix-Zeitstempel zurück (Sekunden seit '1970-01-01 00:00:00' GMT). Wenn UNIX_TIMESTAMP() mit einem datum-Argument aufgerufen wird, gibt sie den Wert des Arguments als Sekunden seit '1970-01-01 00:00:00' GMT zurück. datum kann eine DATE-Zeichenkette, eine DATETIME-Zeichenkette, ein TIMESTAMP oder eine Zahl im Format YYMMDD oder YYYYMMDD in lokaler Zeit sein:

    mysql> select UNIX_TIMESTAMP();
            -> 882226357
    mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
            -> 875996580
    

    Wenn UNIX_TIMESTAMP auf einer TIMESTAMP-Spalte benutzt wird, erhält die Funktion den Wert direkt, ohne implizite ``zeichenkette-zu-unix-zeitstempel''-Umwandlung. Wenn Sie UNIX_TIMESTAMP() einen falschen Wert oder einen Wert ausserhalb des Wertebereichs angeben, gibt sie 0 zurück.

  • FROM_UNIXTIME(unix_zeitstempel)

    Gibt das unix_timestamp-Argument als Wert im 'YYYY-MM-DD HH:MM:SS'- oder YYYYMMDDHHMMSS-Format zurück, abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

    mysql> select FROM_UNIXTIME(875996580);
            -> '1997-10-04 22:23:00'
    mysql> select FROM_UNIXTIME(875996580) + 0;
            -> 19971004222300
    

  • FROM_UNIXTIME(unix_zeitstempel,format)

    Gibt das unix_timestamp-Argument als Wert zurück, der wie mit der format-Zeichenkette angegeben formatiert ist. format kann dieselben Spezifikatoren wie die DATE_FORMAT()-Funktion enthalten:

    mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
                                '%Y%D%M%h:%i:%s%x');
            -> '1997 23rd December 03:43:30 x'
    

  • SEC_TO_TIME(sekunden)

    Gibt das sekunden-Argument, umgewandelt in Stunden, Minuten und Sekunden, als Wert im 'HH:MM:SS'- oder HHMMSS-Format zurück, abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

    mysql> select SEC_TO_TIME(2378);
            -> '00:39:38'
    mysql> select SEC_TO_TIME(2378) + 0;
            -> 3938
    

  • TIME_TO_SEC(zeit)

    Gibt das zeit-Argument, umgewandelt in Sekunden, zurück:

    mysql> select TIME_TO_SEC('22:23:00');
            -> 80580
    mysql> select TIME_TO_SEC('00:39:38');
            -> 2378
    

7.3.5. Weitere Funktionen

7.3.5.1. Bit-Funktionen

MySQL benutzt BIGINT-Berechnungen (64-Bit) für Bit-Operationen, so dass diese Operatoren einen maximalen Wertebereich von 64 Bits haben.

  • |

    Bitweises OR:

    mysql> select 29 | 15;
            -> 31
    

  • &

    Bitweises AND:

    mysql> select 29 & 15;
            -> 13
    

  • <<

    Verschiebt eine BIGINT-Zahl nach links:

    mysql> select 1 << 2;
            -> 4
    

  • >>

    Verschiebt eine BIGINT-Zahl nach rechts:

    mysql> select 4 >> 2;
            -> 1
    

  • ~

    Invertiert alle Bits:

    mysql> select 5 & ~1;
            -> 4
    

  • BIT_COUNT(N)

    Gibt die Anzahl von Bits, die im Argument N gesetzt sind, zurück:

    mysql> select BIT_COUNT(29);
            -> 4
    

7.3.5.2. Verschiedene Funktionen

  • DATABASE()

    Gibt den aktuellen Datenbanknamen zurück:

    mysql> select DATABASE();
            -> 'test'
    

    Wenn es keine aktuelle Datenbank gibt, gibt DATABASE() die leere Zeichenkette zurück.

  • USER() , SYSTEM_USER() , SESSION_USER()

    Gibt den aktuellen MySQL-Benutzernamen zurück:

    mysql> select USER();
            -> 'heinzholger@localhost'
    

    Ab MySQL-Version 3.22.11 beinhaltet dieser Wert den Client-Hostnamen sowie den Benutzernamen. Sie können nur den Benutzernamen-Anteil wie folgt extrahieren (was funktioniert, ob der Wert nun einen Hostnamen-Anteil hat oder nicht):

    mysql> select substring_index(USER(),"@",1);
            -> 'heinzholger'
    

  • PASSWORD(zeichenkette)

    Berechnet eine Passwort-Zeichenkette aus dem Klartext-Passwort zeichenkette. Diese Funktion wird benutzt, um MySQL-Passwörter zum Speichern in der Password-Spalte der user-Berechtigungstabelle zu verschlüsseln:

    mysql> select PASSWORD('schlechtespasswort');
            -> '1ccbb34b4e2b2f95'
    

    Die PASSWORD()-Verschlüsselung ist nicht umkehrbar.

    PASSWORD() führt keine Passwort-Verschlüsselung in der Art durch, wie Unix-Passwörter verschlüsselt werden. Sie sollten nicht annehmen, dass Ihr Unix-Passwort und Ihr MySQL-Passwort dasselbe sind. PASSWORD() ergibt denselben verschlüsselten Wert, wie er in der Unix-Passwortdatei gespeichert ist. Siehe ENCRYPT().

  • ENCRYPT(zeichenkette[,salt])

    Verschlüsselt zeichenkette unter Benutzung des Unix-crypt()-Systemaufrufs. Das salt-Argument sollte eine Zeichenkette mit zwei Zeichen sein (ab MySQL-Version 3.22.16 darf salt länger als zwei Zeichen sein):

    mysql> select ENCRYPT("hello");
            -> 'VxuFAJXVARROc'
    

    Wenn crypt() auf Ihrem System nicht verfügbar ist, gibt ENCRYPT() immer NULL zurück.

    ENCRYPT() ignoriert alle ausser den ersten 8 Zeichen von zeichenkette, zumindest auf einigen Systemen. Das wird durch den zugrunde liegenden crypt()-Systemaufruf festgelegt.

  • ENCODE(zeichenkette,passwort_zeichenkette)

    Verschlüsselt zeichenkette, indem passwort_zeichenkette als Passwort benutzt wird. Um das Ergebnis zu entschlüsseln, benutzen Sie DECODE().

    Das Ergebnis ist eine binäre Zeichenkette derselben Länge wie zeichenkette. Wenn Sie sie in einer Spalte speichern wollen, benutzen Sie eine BLOB-Spalte.

  • DECODE(crypt_zeichenkette,passwort_zeichenkette)

    Entschlüsselt die verschlüsselte Zeichenkette crypt_zeichenkette, indem passwort_zeichenkette als Passwort benutzt wird. crypt_zeichenkette sollte eine Zeichenkette sein, die von ENCODE() zurückgegeben wird.

  • MD5(zeichenkette)

    Berechnet eine MD5-Prüfsumme für die Zeichenkette. Der Wert wird als eine 32 Stellen lange hexadezimale Zahl zurückgegeben, die zum Beispiel als Hash-Schlüssel benutzt werden kann:

    mysql> select MD5("testing");
            -> 'ae2b1fca515949e5d54fb22b8ed95575'
    

    Das ist ein "RSA Data Sicherheit, Inc. MD5 Message-Digest Algorithm".

  • LAST_INSERT_ID([ausdruck])

    Gibt den letzten automatisch erzeugten Wert zurück, der in eine AUTO_INCREMENT-Spalte eingefügt wurde. See Abschnitt 9.4.3.30, „mysql_insert_id().

    mysql> select LAST_INSERT_ID();
            -> 195
    

    Die letzte ID, die erzeugt wurde, wird im Server für jede Verbindung separat gespeichert. Sie wird nicht durch andere Clients geändert. Sie wird nicht einmal geändert, wenn Sie eine andere AUTO_INCREMENT-Spalte mit einem nicht 'magischen' Wert aktualisieren (also einem Wert, der nicht NULL und nicht 0 ist).

    Wenn Sie viele Zeilen zugleich mit einem Insert-Statement einfügen, gibt LAST_INSERT_ID() den Wert für die erste eingefügte Zeile zurück. Der Grund dafür liegt darin, dass es Ihnen dadurch ermöglicht wird, dasselbe INSERT-Statement auf einfache Weise auf einem anderen Server zu reproduzieren.

    Wenn ausdruck als Argument zu LAST_INSERT_ID() angegeben wird, wird der Wert des Arguments von der Funktion zurückgegeben, als nächster Wert gesetzt, der von LAST_INSERT_ID() zurückgegeben wird und als nächster auto_increment-Wert benutzt. Damit können Sie Zahlenfolgen emulieren:

    Erzeugen Sie zuerst die Tabelle:

    mysql> create table sequenz (id int not null);
    mysql> insert into sequenz values (0);
    

    Danach kann die Tabelle benutzt werden, um wie folgt Zahlenfolgen zu erzeugen:

    mysql> update sequenz set id=LAST_INSERT_ID(id+1);
    

    Sie können Zahlenfolgen erzeugen, ohne LAST_INSERT_ID() aufzurufen, aber der Nutzen, die Funktion auf diese Art zu benutzen, liegt darin, dass der ID-Wert im Server als letzter automatisch erzeugter Wert gehalten wird. Sie können die neue ID auf dieselbe Art abrufen, wie Sie jeden anderen normalen AUTO_INCREMENT-Wert in MySQL lesen würden. LAST_INSERT_ID() (ohne Argument) zum Beispiel gibt die neue ID zurück. Die C-API-Funktion mysql_insert_id() kann ebenfalls benutzt werden, um den Wert zu erhalten.

    Beachten Sie, dass Sie diese Funktion nicht benutzen können, um den Wert von LAST_INSERT_ID(ausdruck) abzurufen, nachdem Sie andere SQL-Statements wie SELECT oder SET ausgeführt haben, weil mysql_insert_id() nur nach INSERT- und UPDATE-Statements aktualisiert wird.

  • FORMAT(X,D)

    Formatiert die Zahl X in ein Format wie '#,###,###.##', gerundet auf D Dezimalstellen. Wenn D 0 ist, hat das Ergebnis keinen Dezimalpunkt oder Bruchteil:

    mysql> select FORMAT(12332.123456, 4);
            -> '12,332.1235'
    mysql> select FORMAT(12332.1,4);
            -> '12,332.1000'
    mysql> select FORMAT(12332.2,0);
            -> '12,332'
    

  • VERSION()

    Gibt eine Zeichenkette zurück, die die MySQL-Serverversion anzeigt:

    mysql> select VERSION();
            -> '3.23.13-log'
    

    Wenn Ihre Versionsnummer mit -log endet, bedeutet das, dass Loggen angeschaltet ist.

  • CONNECTION_ID()

    Gibt die Verbindungskennnummer (Thread_id) für die Verbindung zurück. Jede Verbindung hat ihre eigene eindeutige Kennnummer:

    mysql> select CONNECTION_ID();
            -> 1
    

  • GET_LOCK(zeichenkette,zeitueberschreitung)

    Versucht, eine Sperre mit dem Namen, der durch die Zeichenkette zeichenkette angegeben wird, zu erlangen, mit einem Timeout von zeitueberschreitung Sekunden. Gibt 1 zurück, wenn die Sperre erfolgreich erlangt wurde, und 0, wenn der Versuch wegen Zeitüberschreitung abgebrochen wurde, oder NULL, wenn ein Fehler auftrat (wenn zum Beispiel kein Arbeitsspeicher mehr frei ist oder der Thread mit mysqladmin kill gekillt wurde). Eine Sperre wird aufgehoben, wenn Sie RELEASE_LOCK() ausführen, einen neuen GET_LOCK() ausführen oder der Thread beendet wird. Diese Funktion kann benutzt werden, um Applikations-Sperren zu implementieren oder um Datensatz-Sperren zu simulieren. Sie blockiert Anfragen von anderen Clients nach Sperren mit demselben Namen; Clients, die sich auf einen angegebenen Namen für die Sperr-Zeichenkette einigen, können die Zeichenkette benutzen, um kooperatives beratendes Sperren (advisory locking) auszuführen:

    mysql> select GET_LOCK("lock1",10);
            -> 1
    mysql> select GET_LOCK("lock2",10);
            -> 1
    mysql> select RELEASE_LOCK("lock2");
            -> 1
    mysql> select RELEASE_LOCK("lock1");
            -> NULL
    

    Beachten Sie, dass der zweite RELEASE_LOCK()-Aufruf NULL zurückgibt, weil die Sperre "lock1" automatisch durch den zweiten GET_LOCK()-Aufruf aufgehoben wurde.

  • RELEASE_LOCK(zeichenkette)

    Hebt die Sperre auf, die durch die Zeichenkette zeichenkette benannt ist, die mit GET_LOCK() erlangt wurde. Gibt 1 zurück, wenn die Sperre aufgehoben wurde, und 0, wenn die Sperre nicht durch diesen Thread gemacht wurde (in diesem Fall wird die Sperre nicht aufgehoben), oder NULL, wenn die benannte Sperre nicht existiert. Die Sperre existiert nicht, wenn sie nie durch einen Aufruf von GET_LOCK() erlangt wurde oder wenn sie bereits aufgehoben wurde.

  • BENCHMARK(zaehler,ausdruck)

    Die BENCHMARK()-Funktion den Ausdruck ausdruck wiederholt zaehler mal aus. Sie kann benutzt werden, um die Zeit zu ermitteln, die MySQL benötigt, um den Ausdruck zu verarbeiten. Der Ergebniswert ist immer 0. Die Funktion ist für die Benutzung im mysql-Client gedacht, der die Ausführungszeiten von Anfragen zum Beispiel wie folgt darstellt:

    mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
    +----------------------------------------------+
    | BENCHMARK(1000000,encode("hello","goodbye")) |
    +----------------------------------------------+
    |                                            0 |
    +----------------------------------------------+
    1 row in set (4.74 sec)
    

    Die berichtete Zeit ist die am Client-Ende verstrichene Zeit, nicht die Prozessorzeit am Server-Ende. Es ist ratsam, BENCHMARK() mehrere Male auszuführen und das Ergebnis unter Berücksichtigung der Last, unter der die Server-Maschine fährt, zu interpretieren.

  • INET_NTOA(ausdruck)

    Gibt die Netzwerk-Adresse (4 oder 8 Bytes) für den numerischen Ausdruck zurück:

    mysql> select INET_NTOA(3520061480);
           ->  "209.207.224.40"
    

  • INET_ATON(ausdruck)

    Gibt eine Ganzzahl zurück, die den numerischen Wert einer Netzwerk-Adresse darstellt. Adressen können 4-Byte- oder 8-Byte-Adressen sein:

    mysql> select INET_ATON("209.207.224.40");
           ->  3520061480
    

    Die erzeugte Zahl ist immer in Netzwerk-Byte-Reihenfolge; die obige Zahl wird zum Beispiel errechnet als 209*255^3 + 207*255^2 + 224*255 +40.

  • MASTER_POS_WAIT(log_name, log_position)

    Blockiert, bis der Slave während der Replikation die festgelegte Position in der Master-Log-Datei erreicht. Wenn die Master-Information nicht initialisiert wird, wird NULL zurückgegeben. Wenn der Slave nicht läuft, blockiert die Funktion und wartet, bis er gestartet wurde, und geht dann hinter die angegebene Position. Wenn der Slave bereits hinter der angegebenen Position ist, kehrt die Funktion sofort zurück. Der Rückgabewert ist die Anzahl von Log-Events, die sie warten muss, um bis zur angegebenen Position zu kommen, oder NULL in Fehlerfällen. Nützlich für die Steuerung der Master-Slave-Synchronisation, aber ursprünglich geschrieben, um das Testen der Replikation zu erleichtern.

7.3.6. Funktionen zur Benutzung bei GROUP BY-Klauseln

Wenn Sie in einem Statement eine Gruppierungsfunktion benutzen, die keine GROUP BY-Klausel enthält, ist das gleichbedeutend mit der Gruppierung aller Zeilen.

  • COUNT(ausdruck)

    Gibt die Anzahl der Zeilen mit Nicht-NULL-Werten zurück, die durch ein SELECT-Statement abgerufen werden:

    mysql> select student.student_name,COUNT(*)
               from student,kurs
               where student.student_id=kurs.student_id
               GROUP BY student_name;
    
    

    COUNT(*) ist insofern anders, als es die Anzahl der abgerufenen Zeilen zurückgibt, egal ob sie NULL-Werte enthalten oder nicht.

    COUNT(*) ist darauf optimiert, das Ergebnis sehr schnell zurückzugeben, wenn es mittels eines SELECT von einer Tabelle abruft, wenn keine weiteren Spalten abgerufen werden und es keine WHERE-Klausel gibt. Beispiel:

    mysql> select COUNT(*) from student;
    

  • COUNT(DISTINCT ausdruck,[ausdruck...])

    Gibt die Anzahl unterschiedlicher Nich-NULL-Werte zurück:

    mysql> select COUNT(DISTINCT ergebnisse) from student;
    

    Bei MySQL erhalten Sie die Anzahl unterschiedlicher Ausdruckskombinationen, die nicht NULL enthalten, indem Sie eine Liste von Ausdrücken angeben. In ANSI-SQL müssten Sie eine Verkettung aller Ausdrücke innerhalb von CODE(DISTINCT ..) angeben.

  • AVG(ausdruck)

    Gibt den Durchschnittswert von ausdruck zurück:

    mysql> select student_name, AVG(test_ergebnis)
               from student
               GROUP BY student_name;
    

  • MIN(ausdruck) , MAX(ausdruck)

    Gibt den kleinsten oder größten Wert von ausdruck zurück. MIN() und MAX() können Zeichenketten-Argumente aufnehmen und geben in solchen Fällen den kleinsten oder größten Zeichenketten- Wert zurück. See Abschnitt 6.4.3, „Wie MySQL Indexe benutzt“.

    mysql> select student_name, MIN(test_ergebnis), MAX(test_ergebnis)
               from student
               GROUP BY student_name;
    

  • SUM(ausdruck)

    Gibt die Summe von ausdruck zurück. Beachten Sie, dass der Rückgabewert NULL ist, wenn die Ergebnismenge keine Zeilen hat!

  • STD(ausdruck) , STDDEV(ausdruck)

    Gibt die Standardabweichung von ausdruck zurück. Das ist eine Erweiterung zu ANSI-SQL. Die STDDEV()-Form dieser Funktion wird aus Gründen der Oracle-Kompatibilität zur Verfügung gestellt.

  • BIT_OR(ausdruck)

    Gibt das bitweise OR aller Bits in ausdruck zurück. Die Berechnung wird mit 64-Bit-(BIGINT)-Genauigkeit durchgeführt.

  • BIT_AND(ausdruck)

    Gibt das bitweise AND aller Bits in ausdruck zurück. Die Berechnung wird mit 64-Bit-(BIGINT)-Genauigkeit durchgeführt.

MySQL hat die Benutzung von GROUP BY erweitert. Sie können Spalten oder Berechnungen im SELECT-Ausdruck angeben, die nicht im GROUP BY-Teil erscheinen. Das steht für jeden möglichen Wert für diese Gruppe. Das können Sie benutzen, um bessere Performance zu erzielen, indem Sie Sortieren und Gruppieren unnötiger Bestandteile vermeiden. Zum Beispiel müssen Sie in folgender Anfrage nicht nach kunde.name gruppieren:

mysql> select bestellung.kunde_id,kunde.name,max(zahlungen)
       from bestellung,kunde
       where bestellung.kunde_id = kunde.kunde_id
       GROUP BY bestellung.kunde_id;

In ANSI-SQL müssten Sie der GROUP BY-Klausel kunde.name hinzufügen. In MySQL ist der Name überflüßig, solange Sie nicht im ANSI-Modus fahren.

Benutzen Sie dieses Feature nicht, wenn die Spalten, die Sie im GROUP BY-Teil auslassen, in der Gruppe nicht eindeutig sind! Sonst erhalten Sie unvorhersagbare Ergebnisse.

In einigen Fällen können Sie MIN() und MAX() benutzen, um einen bestimmten Spaltenwert zu erhalten, selbst wenn er nicht eindeutig ist. Folgendes gibt den Wert von spalte aus der Zeile zurück, die den kleinsten Wert in der sortierung-Spalte enthält:

substr(MIN(concat(rpad(sortierung,6,' '),spalte)),7)

7.4. Datenmanipulation: SELECT, INSERT, UPDATE, DELETE

7.4.1. SELECT-Syntax

SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
       [HIGH_PRIORITY]
       [DISTINCT | DISTINCTROW | ALL]
    select_ausdruck,...
    [INTO {OUTFILE | DUMPFILE} 'datei' export_optionen]
    [FROM tabellenreferenz
        [WHERE where_definition]
        [GROUP BY {positive_ganzzahl | spalten_name | formel} [ASC | DESC], ...]
        [HAVING where_definition]
        [ORDER BY {positive_ganzzahl | spalten_name | formel} [ASC | DESC] ,...]
        [LIMIT [offset,] zeilen]
        [PROCEDURE prozedur_name]
        [FOR UPDATE | LOCK IN SHARE MODE]]

SELECT wird benutzt, um ausgewählte Zeilen aus einer oder mehreren Tabellen abzurufen. select_ausdruck gibt die Spalten an, die Sie abrufen wollen. SELECT kann auch benutzt werden, um Zeilen ohne Bezug zu irgend einer Tabelle abzurufen. Beispiel:

mysql> SELECT 1 + 1;
         -> 2

Alle benutzten Schlüsselwörter müssen genau in der oben angegebenen Reihenfolge genannt werden. Beispielsweise muss eine HAVING-Klausel nach jeglicher GROUP BY-Klausel und vor jeglicher ORDER BY-Klausel kommen.

  • Einem SELECT-Ausdruck kann mit AS ein Alias zugewiesen werden. Der Alias wird als Spaltenname verwendet und kann bei ORDER BY- oder HAVING-Klauseln benutzt werden. Beispiel:

    mysql> select concat(nachname,', ',vorname) AS voller_name
        from tabelle ORDER BY voller_name;
    
  • The FROM tabellenreferenz-Klausel gibt die Tabellen an, aus denen Zeilen abgerufen werden sollen. Wenn Sie mehr als eine Tabelle aufführen, führen Sie einen Join durch. Informationen über die Join-Syntax finden Sie unter Abschnitt 7.4.1.1, „JOIN-Syntax“.

  • Sie können auf eine Spalte als spalten_name verweisen, als tabelle.spalten_name oder als datenbank.tabelle.spalten_name. Sie müssen das tabelle- oder datenbank.tabelle-Präfix für einen Spaltenverweis in einem SELECT-Statement nicht angeben, es sei denn, der Verweis wäre ansonsten mehrdeutig. Sie Abschnitt 7.1.2, „Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen“; hier finden sich Beispiele von Mehrdeutigkeit, die erfordern, dass Sie ausführlichere Spaltenverweis-Formen benutzen.

  • Einem Tabellenverweis kann mit tabelle [AS] alias_name ein Tabellen-Alias zugewiesen werden:

    mysql> select t1.name, t2.gehalt from angestellte AS t1, info AS t2
               where t1.name = t2.name;
    mysql> select t1.name, t2.gehalt from angestellte t1, info t2
               where t1.name = t2.name;
    
  • Auf Spalten, die für die Ausgabe ausgewählt wurden, kann in ORDER BY- und GROUP BY-Klauseln mit Spaltennamen, Spalten-Aliasen oder Spaltenpositionen verwiesen werden. Spaltenpositionen fangen mit 1 an:

    mysql> select hochschule, region, seed von tournament
               ORDER BY region, seed;
    mysql> select hochschule, region AS r, seed AS s from turnier
               ORDER BY r, s;
    mysql> select hochschule, region, seed from turnier
               ORDER BY 2, 3;
    

    Um in absteigender Reihenfolge zu sortieren, fügen Sie dem Namen der Spalte das DESC-Schlüsselwort in the ORDER BY-Klausel hinzu (descending, absteigend), nach der Sie sortieren. Die Vorgabe ist aufsteigende Reihenfolge. Das können Sie auch explizit angeben, indem Sie das ASC-Schlüsselwort verwenden.

  • In der WHERE-Klausel können Sie beliebige Funktionen verwenden, die MySQL unterstützt. See Abschnitt 7.3, „Funktionen für die Benutzung in SELECT- und WHERE-Klauseln“.

  • Die HAVING-Klausel kann auf jede Spalte oder jeden Alias verweisen, die bzw. der im select_ausdruck genannt wurde. Die Klausel wird zuletzt angewandt, direkt bevor Ergebnisse an den Client geschickt werden, ohne jede Optimierung. Benutzen Sie kein HAVING für Dinge, die in der WHERE-Klausel stehen sollten. Schreiben Sie beispielsweise nicht folgendes:

    mysql> select spalten_name from tabelle HAVING spalten_name > 0;
    

    Sondern statt dessen:

    mysql> select spalten_name from tabelle WHERE spalten_name > 0;
    

    Ab MySQL-Version 3.22.5 können Sie Anfragen auch wie folgt schreiben:

    mysql> select user,max(gehalt) from benutzer
               group by benutzer HAVING max(gehalt)>10;
    

    In älteren MySQL-Versionen schreiben Sie statt dessen:

    mysql> select benutzer,max(gehalt) AS summe from benutzer
               group by benutzer HAVING summe>10;
    
  • SQL_SMALL_RESULT, SQL_BIG_RESULT, SQL_BUFFER_RESULT, STRAIGHT_JOIN und HIGH_PRIORITY sind MySQL Erweiterungen zu ANSI-SQL92.

  • HIGH_PRIORITY gibt dem SELECT höhere Priorität als einem Statement, das eine Tabelle aktualisiert. Sie sollten das nur für Anfragen benutzen, die sehr schnell sind und sofort durchgeführt werden müssen. Eine SELECT HIGH_PRIORITY-Anfrage läuft, wenn die Tabelle eine Lese-Sperre hat, selbst wenn es ein Update-Statement gibt, das darauf wartet, dass die Tabelle freigegeben wird.

  • SQL_BIG_RESULT kann bei GROUP BY oder DISTINCT benutzt werden, um dem Optimierer mitzuteilen, dass das Ergebnis sehr viele Zeilen haben wird. In diesem Fall benutzt MySQL bei Bedarf direkt Festplatten-basierende temporäre Tabellen. Ausserdem bevorzugt MySQL in diesem Fall Sortieren vor dem Anlegen einer temporären Tabelle mit einem Schlüssel auf den GROUP BY-Elementen.

  • Wenn Sie GROUP BY benutzen, werden die Ausgabe-Zeilen gemäß dem GROUP BY sortiert, als hätten Sie ein ORDER BY für alle Felder im GROUP BY angegeben. MySQL hat GROUP BY erweitert, so dass Sie dafür auch ASC und DESC angeben können:

    SELECT a,COUNT(b) FROM tabelle GROUP BY a DESC
    
  • MySQL hat die Benutzung von GROUP BY erweitert, um es Ihnen zu gestatten, auch Felder auszuwählen, die nicht in der GROUP BY-Klausel erwähnt wurden. Wenn Sie nicht die Ergebnisse erhalten, die Sie von Ihrer Anfrage erwarten, lesen Sie bitte die GROUP BY-Beschreibung.

  • SQL_BUFFER_RESULT erzwingt, dass das Ergebnis in eine temporäre Tabelle geschrieben wird. Das hilft MySQL, frühzeitig Tabellensperren aufzuheben, und hilft in Fällen, in denen es lange dauert, das Ergebnis an den Client zu senden.

  • SQL_SMALL_RESULT, eine MySQL-spezifische Option, kann bei GROUP BY oder DISTINCT benutzt werden, um dem Optimierer mitzuteilen, dass der Ergebnissatz klein sein wird. In diesem Fall benutzt MySQL schnelle temporäre Tabellen, um die Ergebnistabelle zu speichern, anstatt Sortieren zu benutzen. In MySQL-Version 3.23 sollte das normalerweise nicht benötigt werden.

  • STRAIGHT_JOIN zwingt den Optimierer, Tabellen in der Reihenfolge zu verknüpfen, in der sie in der FROM-Klausel aufgelistet sind. Sie können das benutzen, um die Geschwindigkeit einer Anfrage zu erhöhen, wenn der Optimierer Tabellen in nicht optimaler Reihenfolge verknüpft. See Abschnitt 6.2.1, „EXPLAIN-Syntax (Informationen über ein SELECT erhalten)“.

  • Die LIMIT-Klausel wird benutzt, um die Anzahl von Zeilen, die vom SELECT-Statement zurückgegeben werden, zu beschränken. LIMIT erwartet ein oder zwei numerische Argumente.

    Wenn zwei Argumente angegeben sind, legt das erste den Offset der ersten Zeile fest, die zurückgegeben wird, und das zweite gibt die maximale Anzahl von Zeilen an, die zurückgegeben werden. Der Offset der anfänglichen Zeile ist 0 (nicht 1):

    mysql> select * from tabelle LIMIT 5,10;  # Zeilen 6 bis 15 zurückgeben
    

    Wenn ein Argument angegeben wird, stellt es die maximale Anzahl von Zeilen dar, die zurückgegeben werden:

    mysql> select * from tabelle LIMIT 5;     # Die ersten 5 Zeilen zurückgeben
    

    Mit anderen Worten ist LIMIT n äquivalent zu LIMIT 0,n.

  • Die SELECT ... INTO OUTFILE 'datei'-Form von SELECT schreibt die ausgewählten Zeilen in eine Datei. Die Datei wird auf dem Server-Host erzeugt und darf nicht bereits bestehen (das verhindert unter anderem, dass Datenbanktabellen und Dateien wie /etc/passwd zerstört werden). Sie benötigen die file-Berechtigung auf dem Server-Host, um diese Form von SELECT auszuführen.

    SELECT ... INTO OUTFILE ist hauptsächlich dafür vorgesehen, um eine Tabelle auf der Server-Maschine schnell zu dumpen. Wenn Sie die resultierende Datei auf einem anderen Host als dem Server-Host haben wollen, können Sie SELECT ... INTO OUTFILE nicht benutzen. In diesem Fall sollten Sie statt dessen ein Client-Programm wie mysqldump --tab oder mysql -e "SELECT ..." > outfile benutzen, um die Datei zu erzeugen.

    SELECT ... INTO OUTFILE ist das Komplement von LOAD DATA INFILE; die Syntax für den export_optionen-Teil des Statements besteht aus denselben FIELDS- und LINES-Klauseln, die beim LOAD DATA INFILE-Statement benutzt werden. See Abschnitt 7.4.9, „LOAD DATA INFILE-Syntax“.

    In der resultierenden Textdatei werden nur folgende Zeichen durch das ESCAPED BY-Zeichen escapet:

    • Das ESCAPED BY-Zeichen

    • Das erste Zeichen in FIELDS TERMINATED BY

    • Das erste Zeichen in LINES TERMINATED BY

    Zusätzlich wird ASCII 0 in ESCAPED BY, gefolgt von 0 (ASCII 48), umgewandelt.

    Der Grund hierfür ist, dass Sie jegliche FIELDS TERMINATED BY-, ESCAPED BY- oder LINES TERMINATED BY-Zeichen escapen MÜSSEN, um die Datei zuverlässig wieder einlesen zu können. ASCII 0 wird escapet, um das Lesen mit einigen Pagern zu erleichtern.

    Weil sich die resultierende Datei nicht nach der SQL-Syntax richten muss, muss nicht weiter escapet werden.

    Im Folgenden ein Beispiel, wie man eine Datei in einem Format erhält, das von vielen alten Programmen benutzt wird:

    SELECT a,b,a+b INTO OUTFILE "/tmp/resultat.text"
    FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
    LINES TERMINATED BY "\n"
    FROM tabelle;
    
  • Wenn Sie INTO DUMPFILE anstelle von INTO OUTFILE benutzen, schreibt MySQL nur eine Zeile in die Datei, ohne jede Spalten- oder Zeilen-Begrenzer und ohne jedes Escapen. Das ist nützlich, wenn Sie ein Blob in eine Datei speichern wollen.

  • Beachten Sie, dass jede Datei, die von INTO OUTFILE und INTO DUMPFILE erzeugt wird, für alle Benutzer lesbar ist! Der Grund liegt darin, dass der MySQL-Server keine Datei erzeugen kann, die jemandem anderen gehört als dem Benutzer, unter dem er läuft (Sie sollten mysqld nie als Root laufen lassen), daher muss die Datei für jedermann lesbar sein, damit Sie die Zeilen abrufen können.

  • Wenn Sie FOR UPDATE bei einem Tabellen-Handler mit Seiten-/Zeilen-Sperren benutzen, werden die untersuchten Zeilen schreib-gesperrt.

7.4.1.1. JOIN-Syntax

MySQL unterstützt folgende JOIN-Syntaxen für SELECT-Statements:

tabellen_verweis, tabellen_verweis
tabellen_verweis [CROSS] JOIN tabellen_verweis
tabellen_verweis INNER JOIN tabellen_verweis join_bedingung
tabellen_verweis STRAIGHT_JOIN tabellen_verweis
tabellen_verweis LEFT [OUTER] JOIN tabellen_verweis join_bedingung
tabellen_verweis LEFT [OUTER] JOIN tabellen_verweis
tabellen_verweis NATURAL [LEFT [OUTER]] JOIN tabellen_verweis
{ oder tabellen_verweis LEFT OUTER JOIN tabellen_verweis ON bedingungs_ausdruck }
tabellen_verweis RIGHT [OUTER] JOIN tabellen_verweis join_bedingung
tabellen_verweis RIGHT [OUTER] JOIN tabellen_verweis
tabellen_verweis NATURAL [RIGHT [OUTER]] JOIN tabellen_verweis

Wobei tabellen_verweis definiert ist als:

tabelle [[AS] alias] [USE INDEX (schluessel_liste)] [IGNORE INDEX (schluessel_liste)]

Und join_bedingung definiert ist als:

ON bedingungs_ausdruck |
USING (spalten_liste)

Sie sollten nie irgend welche Bedingungen im ON-Teil haben, die dazu benutzt werden, um die Zeilen, die im Ergebnissatz auftauchen, zu beschränken. Wenn Sie so etwas tun wollen, müssen Sie das in der WHERE-Klausel tun.

Beachten Sie, dass vor Version 3.23.17 INNER JOIN keine join_bedingung aufnahm!

Die letzte oben dargestellte LEFT OUTER JOIN-Syntax gibt es nur aus Gründen der Kompatibilität mit ODBC:

  • Einem Tabellenverweis kann mit tabelle AS alias_name oder tabelle alias_name ein Alias zugewiesen werden:

    mysql> select t1.name, t2.gehalt from angestellte AS t1, info AS t2
               where t1.name = t2.name;
    
  • Der ON-Bedingungscode ist jeglicher Bedingungscode der Form, wie er auch in einer WHERE-Klausel benutzt werden kann.

  • Wenn es für die rechte Tabelle keinen übereinstimmenden Datensatz im ON- oder USING-Teil eines LEFT JOIN gibt, wird für die rechte Tabelle eine Zeile benutzt, in der alle Spalten auf NULL gesetzt sind. Das können Sie benutzen, um Datensätze in einer Tabelle herauszusuchen, die in einer anderen Tabelle kein Gegenstück haben:

    mysql> select tabelle1.* from tabelle1
               LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id
               where tabelle2.id is NULL;
    

    Dieses Beispiel findet alle Zeilen in tabelle1 mit einem id-Wert, der in tabelle2 nicht vorhanden ist (also alle Zeilen in tabelle1 ohne entsprechende Zeile in tabelle2). Hierbei wird natürlich angenommen, dass tabelle2.id als NOT NULL deklariert ist. See Abschnitt 6.2.6, „Wie MySQL LEFT JOIN optimiert“.

  • Die USING-(spalten_liste)-Klausel nennt eine Auflistung von Spalten, die in beiden Tabellen existieren müssen. Eine USING-Klausel wie:

    A LEFT JOIN B USING (C1,C2,C3,...)
    

    Ist definiert als semantisch identisch mit einem ON-Ausdruck wie diesem:

    A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
    
  • Der NATURAL [LEFT] JOIN zweier Tabellen ist definiert als semantisch identisch äquivalent zu einem INNER JOIN oder einem LEFT JOIN mit einer USING-Klausel, die alle Spalten nennt, die in beiden Tabellen existieren.

  • RIGHT JOIN funktioniert analog wie LEFT JOIN. Um Code zwischen Datenbanken portabel zu halten, wird empfohlen, LEFT JOIN anstelle von RIGHT JOIN zu benutzen.

  • STRAIGHT_JOIN ist identisch mit JOIN, ausser dass die linke Tabelle immer vor der rechten Tabelle gelesen wird. Das kann in den (wenigen) Fällen benutzt werden, wo der Optimierer die Tabellen in die falsche Reihenfolge bringt.

  • Ab MySQL-Version 3.23.12 können Sie Hinweise darüber geben, welchen Index MySQL benutzen sollte, wenn Informationen aus einer Tabelle abgerufen werden. Das ist nützlich, wenn EXPLAIN zeigt, dass MySQL den falschen Index benutzt. Indem Sie USE INDEX (schluessel_liste) angeben, können Sie MySQL anweisen, nur einen der angegebenen Indexe zu benutzen, um Zeilen in der Tabelle zu finden. Die alternative Syntax IGNORE INDEX (schluessel_liste) kann benutzt werden, um MySQL anzuweisen, einen bestimmten Index nicht zu benutzen.

Einige Beispiele:

mysql> select * from tabelle1,tabelle2 where tabelle1.id=tabelle2.id;
mysql> select * from tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id;
mysql> select * from tabelle1 LEFT JOIN tabelle2 USING (id);
mysql> select * from tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id
           LEFT JOIN table3 ON tabelle2.id=table3.id;
mysql> select * from tabelle1 USE INDEX (schluessel1,schluessel2) WHERE schluessel1=1 und schluessel2=2 AND
       schluessel3=3;
mysql> select * from tabelle1 IGNORE INDEX (schluessel3) WHERE schluessel1=1 und schluessel2=2 AND
       schluessel3=3;

See Abschnitt 6.2.6, „Wie MySQL LEFT JOIN optimiert“.

7.4.1.2. UNION-Syntax

SELECT ....
UNION [ALL]
SELECT ....
  [UNION 
   SELECT ...]

UNION ist implementiert in MySQL 4.0.0.

UNION wird benutzt, um das Ergebnis vieler SELECT-Statements in einem Ergebnissatz zu kombinieren.

Die SELECT-Befehle sind normale SELECT-Befehle, aber mit folgenden Einschränkungen:

  • Nur der letzte SELECT-Befehl darf INTO OUTFILE enthalten.

  • Nur der letzte SELECT-Befehl darf ORDER BY enthalten.

Wenn Sie das Schlüsselwort ALL für UNION nicht benutzen, sind alle zurückgegebenen Zeilen eindeutig (unique), als hätten Sie ein DISTINCT für den gesamten Ergebnissatz gemacht. Wenn Sie ALL angeben, erhalten Sie alle übereinstimmenden Zeilen von allen benutzten SELECT-Statements.

7.4.2. INSERT-Syntax

    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tabelle [(spalten_name,...)]
        VALUES (ausdruck,...),(...),...
oder  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tabelle [(spalten_name,...)]
        SELECT ...
oder  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tabelle
        SET spalten_name=ausdruck, spalten_name=ausdruck, ...

INSERT fügt neue Zeilen in eine bestehende Tabelle ein. Die INSERT ... VALUES-Form des Statements fügt Zeilen basierend auf explizit angegebenen Werten ein. Die INSERT ... SELECT-Form fügt Zeilen ein, die aus einer oder mehreren anderen Tabellen ausgewählt wurden. Die INSERT ... VALUES-Form mit mehrfachen Wertelisten wird ab MySQL-Version 3.22.5 unterstützt. Die spalten_name=expression-Syntax wird ab MySQL-Version 3.22.10 unterstützt.

tabelle ist die Tabelle, in die Zeilen eingefügt werden sollen. Die Spaltennamenliste oder die SET-Klausel geben an, für welche Spalten das Statement Werte angibt:

  • Wenn Sie keine Spaltenliste für INSERT ... VALUES oder INSERT ... SELECT angeben, müssen für alle Spalten Werte in der VALUES()-Liste oder vom SELECT bereit stehen. Wenn Sie die Reihenfolge der Tabellenspalten nicht kennen, benutzen Sie DESCRIBE tabelle, um sie herauszufinden.

  • Jede Spalte, die nicht explizit in einer Werteliste angegeben wird, wird auf ihren Vorgabewert gesetzt. Wenn Sie beispielsweise eine Spaltenliste angeben, die nicht alle Tabellenspalten nennt, werden unbenannte Spalten auf ihre Vorgabewerte gesetzt. Die Zuweisung von Vorgabewerten ist in Abschnitt 7.5.3, „CREATE TABLE-Syntax“ beschrieben.

  • Ein ausdruck kann sich auf jede Spalte beziehen, die vorher in einer Werteliste angegeben wurde. Beispielsweise können Sie folgendes eingeben:

    mysql> INSERT INTO tabelle (spalte1,spalte2) VALUES(15,spalte1*2);
    

    Aber nicht das hier:

    mysql> INSERT INTO tabelle (spalte1,spalte2) VALUES(spalte2*2,15);
    
  • Wenn Sie das Schlüsselwort LOW_PRIORITY angeben, wird die Ausführung von INSERT verzögert, bis kein anderer Client mehr aus der Tabelle liest. In diesem Fall muss der Client warten, bis das INSERT-Statement fertig ist, was lange Zeit dauern kann, wenn die Tabelle stark benutzt wird. Das ist im Gegensatz zu INSERT DELAYED, was den Client sofort weitermachen läßt. See Abschnitt 7.4.4, „INSERT DELAYED-Syntax“. Beachten Sie, dass LOW_PRIORITY normalerweise nicht bei MyISAM-Tabellen benutzt werden sollte, weil dadurch gleichzeitige Einfügeoperationen verhindert werden. See Abschnitt 8.1, „MyISAM-Tabellen“.

  • Wenn Sie das Schlüsselwort IGNORE in einem INSERT mit vielen Wertezeilen angeben, werden alle Zeilen, die einen bestehenden PRIMARY- oder UNIQUE-Schlüssel duplizieren würden, ignoriert und nicht eingefügt. Wenn Sie IGNORE nicht angeben, wird die Einfügeoperation abgebrochen, wenn es eine Zeile gibt, die einen bestehenden Schlüsselwert duplizieren würde. Mit der C-API-Funktion mysql_info() können Sie feststellen, wie viele Zeilen in die Tabelle eingefügt wurden.

  • Wenn MySQL mit der DONT_USE_DEFAULT_FIELDS-Option konfiguriert wurde, erzeugen INSERT-Statements einen Fehler, wenn Sie nicht explizit Werte für alle Spalten angeben, die einen Nicht-NULL-Wert erfordern. See Abschnitt 3.3.3, „Typische configure-Optionen“.

  • Den Wert, der für eine AUTO_INCREMENT-Spalte benutzt wurde, finden Sie mit der mysql_insert_id-Funktion heraus. See Abschnitt 9.4.3.30, „mysql_insert_id().

Wenn Sie ein INSERT ... SELECT- oder ein INSERT ... VALUES-Statement mit mehrfachen Wertlisten benutzen, können Sie die C-API-Funktion mysql_info() benutzen, um Informationen über die Anfrage zu erhalten. Das Format der Informationszeichenkette ist unten dargestellt:

Records: 100 Duplicates: 0 Warnings: 0

Duplicates zeigt die Anzahl von Zeilen, die nicht eingefügt werden konnten, weil sie einen bestehenden eindeutigen Indexwert dupliziert hätten. Warnings zeigen die Anzahl von Versuchen, Spaltenwerte einzufügen, die in irgend einer Weise problematisch waren. Warnungen erfolgen unter folgenden Umständen:

  • Wenn NULL in eine Spalte eingefügt wird, die als NOT NULL deklariert ist. Die Spalte wird auf ihren Vorgabewert gesetzt.

  • Wenn eine numerische Spalte auf einen Wert ausserhalb des Wertebereichs der Spalte gesetzt wird. Der Wert wird auf den entsprechenden Endpunkt des Bereichs abgeschnitten.

  • Wenn eine numerische Spalte auf einen Wert wie '10.34 a' gesetzt wird. Die unsinnigen Zeichen am Ende werden entfernt und der verbleibende numerische Anteil eingefügt. Wenn der Wert als Zahl überhaupt keinen Sinn ergibt, wird die Spalte auf 0 gesetzt.

  • Wenn eine Zeichenkette in eine CHAR-, VARCHAR-, TEXT- oder BLOB-Spalte eingefügt wird, die die maximale Länge der Spalte überschreitet. Der Wert wird auf die maximale Spaltenlänge beschnitten.

  • Wenn ein Wert in eine DATE- oder TIME-Spalte eingefügt wird, der für den Spaltentyp nicht zulässig ist. Die Spalte wird auf den entsprechenden 0-Wert für diesen Typ gesetzt.

7.4.3. HANDLER-Syntax

HANDLER tabelle OPEN [ AS alias ]
HANDLER tabelle READ index { = | >= | <= | < } (wert1, wert2, ... )  [ WHERE ... ] [LIMIT ... ]
HANDLER tabelle READ index { FIRST | NEXT | PREV | LAST } [ WHERE ... ] [LIMIT ... ]
HANDLER tabelle READ { FIRST | NEXT }  [ WHERE ... ] [LIMIT ... ]
HANDLER tabelle CLOSE

Das HANDLER-Statement ermöglicht direkten Zugriff auf die MySQL-Tabellenschnittstelle unter Umgehung des SQL-Optimierers. Daher ist es schneller als SELECT.

Die erste Form des HANDLER-Statements öffnet eine Tabelle und macht sie über die folgenden HANDLER ... READ-Routinen zugänglich. Dieses Tabellenobjekt wird nicht mit anderen Threads geteilt und wird nicht geschlossen, bis der Thread HANDLER tabelle CLOSE aufruft oder stirbt.

Die zweite Form holt eine (oder mehrere, festgelegt durch die LIMIT-Klausel) Zeile, bei der der angegebene Index mit der Bedingung übereinstimmt und die WHERE-Bedingung erfüllt ist. Wenn der Index aus mehreren Teilen besteht (also mehrere Spalten überspannt), werden die Werte in einer Komma-getrennten Liste angegeben, wobei es möglich ist, nur Werte für einige erste Spalten anzugeben.

Die dritte Form holt eine (oder mehrere, festgelegt durch die LIMIT-Klausel) Zeile in Index-Reihenfolge aus der Tabelle, bei der die WHERE-Bedingung erfüllt ist.

Die vierte Form (ohne Index-Angabe) holt eine (oder mehrere, festgelegt durch die LIMIT-Klausel) Zeile in natürlicher Zeilenreihenfolge aus der Tabelle (wie in der Daten-Datei gespeichert), bei der die WHERE-Bedingung erfüllt ist. Das ist schneller als HANDLER tabelle READ index, wenn ein kompletter Tabellen-Scan erwünscht ist.

Die letzte Form schließt eine mit HANDLER ... OPEN geöffnete Tabelle.

HANDLER ist in gewisser Hinsicht ein Statement auf niedriger Ebene (Low-Level), dass zum Beispiel keine Konsistenz gewährleistet. Das heißt, HANDLER ... OPEN nimmt KEINEN Schnappschuss der Tabelle auf und sperrt die Tabelle NICHT. Das bedeutet, dass nach HANDLER ... OPEN Tabellendaten verändert werden können (durch diesen oder einen anderen Thread) und dass diese Veränderungen nur teilweise in HANDLER ... NEXT- oder HANDLER ... PREV-Scans erscheinen.

7.4.3.1. INSERT ... SELECT-Syntax

INSERT [LOW_PRIORITY] [IGNORE] [INTO] tabelle [(spalten_liste)] SELECT ...

Mit dem INSERT ... SELECT-Statement können Sie schnell viele Zeilen aus einer oder mehreren anderen Tabellen einfügen.

INSERT INTO temporaere_tabelle2 (fldID) SELECT temporaere_tabelle1.fldOrder_ID FROM temporaere_tabelle1 WHERE
temporaere_tabelle1.fldOrder_ID > 100;

Folgende Bedingungen gelten für ein INSERT ... SELECT-Statement:

  • Die Ziel-Tabelle des INSERT-Statements darf nicht in der FROM-Klausel des SELECT-Teils der Anfrage erscheinen, weil es in ANSI-SQL verboten ist, aus derselben Tabelle auszuwählen (SELECT), in die eingefügt wird. (Das Problem liegt darin, dass das SELECT möglicherweise Datensätze finden würde, die früher während desselben Laufs eingefügt wurden. Wenn man Sub-Select-Klauseln verwendet, könnte die Situation schnell sehr verwirrend werden!)

  • AUTO_INCREMENT-Spalten funktionieren wie gehabt.

  • Sie können die C-API-Funktion mysql_info() benutzen, um Informationen über die Anfrage zu erhalten. See Abschnitt 7.4.3, „HANDLER-Syntax“.

  • Um sicherzustellen, dass die Update-Log-Datei/Binär-Log-Datei benutzt werden kann, um die Original-Tabellenlänge neu zu erzeugen, läßt MySQL während INSERT .... SELECT keine gleichzeitigen Einfügeoperationen zu.

Sie können natürlich REPLACE anstelle von INSERT benutzen, um alte Zeilen zu überschreiben.

7.4.4. INSERT DELAYED-Syntax

INSERT DELAYED ...

Die DELAYED-Option für das INSERT-Statement ist eine MySQL-spezifische Option, die sehr nützlich ist, wenn Sie Clients haben, die nicht warten können, bis das INSERT fertig ist. Die ist ein häufiges Problem, wenn Sie MySQL zum Loggen benutzen und gelegentlich SELECT- und UPDATE-Statements laufen lassen, die lange Zeit benötigen. DELAYED wurde in MySQL-Version 3.22.15 eingeführt. Es ist eine MySQL Erweiterung zu ANSI-SQL92.

INSERT DELAYED funktioniert nur bei ISAM- und MyISAM-Tabellen. Beachten Sie: Weil MyISAM-Tabellen gleichzeitige SELECT und INSERT unterstützen, wenn es keine freien Blöcke mitten in der Daten-Datei gibt, müssen Sie INSERT DELAYED bei MyISAM nur sehr selten benutzen. See Abschnitt 8.1, „MyISAM-Tabellen“.

Wenn Sie INSERT DELAYED benutzen, erhält der Client sofort ein Okay, und die Zeile wird eingefügt, wenn die Tabelle nicht mehr durch einen anderen Thread in Benutzung ist.

Ein weiterer großer Vorteil von INSERT DELAYED ist, dass Einfügeoperationen vieler Clients gebündelt und in einem Block geschrieben werden. Das ist viel schneller als viele separate Inserts durchzuführen.

Beachten Sie, dass momentan die Zeilen in der Warteschlange solange nur im Arbeitsspeicher gehalten werden, bis sie in die Tabelle eingefügt sind. Das heißt, wenn Sie mysqld auf die harte Tour killen (kill -9) oder wenn mysqld unerwartet stirbt, sind Zeilen in der Warteschlange, die noch nicht auf Festplatte geschrieben wurden, verloren!

Im Folgenden ist detailliert beschrieben, was geschieht, wenn Sie die DELAYED-Option für INSERT oder REPLACE benutzen. In dieser Beschreibung ist der ``Thread'' der Thread, der einen INSERT DELAYED-Befehl empfängt. ``Handler'' ist der Thread, der alle INSERT DELAYED-Statements für ein bestimmte Tabelle handhabt.

  • When ein Thread ein DELAYED-Statement für eine Tabelle ausführt, wird ein Handler-Thread erzeugt, um alle DELAYED-Statements für die Tabelle auszuführen, wenn ein solcher Handler nicht schon existiert.

  • Der Thread prüft, ob der Handler bereit eine DELAYED-Sperre erhalten hat oder nicht. Wenn nicht, weist es den Handler-Thread an, das zu tun. Die DELAYED-Sperre kann selbst dann erlangt werden, wenn ein anderer Thread eine READ- oder WRITE-Sperre auf der Tabelle hat. Der Handler wartet jedoch auf alle ALTER TABLE-Sperren oder FLUSH TABLES, um sicherzustellen, dass die Tabellenstruktur aktuell ist.

  • Der Thread führt das INSERT-Statement aus, aber statt die Zeile in die Tabelle zu schreiben stellt er eine Kopie der endgültigen Zeile in eine Warteschlange, die vom Handler-Thread verwaltet wird. Alle Syntaxfehler werden vom Thread erkannt und dem Client-Programm mitgeteilt.

  • Der Client kann die Anzahl von Duplikaten oder den AUTO_INCREMENT-Wert für die resultierende Zeile nicht mitteilen. Er kann Sie vom Server nicht erhalten, weil das INSERT zurückkehrt, bevor die Einfügeoperation fertig ist. Wenn Sie die C-API benutzen, gibt die mysql_info()-Funktion aus demselben Grund nichts Sinnvolles zurück.

  • Die Update-Log-Datei wird vom Handler-Thread aktualisiert, wenn die Zeile in die Tabelle eingefügt wird. Im Falle des Einfügens mehrerer Zeilen wird die Update-Log-Datei aktualisiert, wenn die erste Zeile eingefügt wird.

  • Nachdem alle delayed_insert_limit Zeilen geschrieben wurden, prüft der Handler, ob noch irgend welche SELECT-Statements anhängig sind oder nicht. Falls ja, gestattet er diesen, ausgeführt zu werden, bevor weiter gemacht wird.

  • Wenn der Handler keine Zeilen mehr in seiner Warteschlange hat, wird die Tabellensperre aufgehoben. Wenn innerhalb von delayed_insert_timeout Sekunden keine neuen INSERT DELAYED-Befehle mehr empfangen werden, beendet sich der Handler.

  • Wenn mehr als delayed_queue_size Zeilen bereits in einer bestimmten Handler-Warteschlange anhängig sind, wartet der Thread, der nach INSERT DELAYED anfragt, bis es wieder Platz in der Warteschlange gibt. Damit wird sichergestellt, dass der mysqld-Server nicht den gesamten Arbeitsspeicher für die DELAYED-Warteschlange verbraucht.

  • Der Handler-Thread zeigt sich in der MySQL-Prozessliste mit delayed_insert in der Command-Spalte. Er wird gekillt, wenn Sie einen FLUSH TABLES-Befehl ausführen oder ihn mit KILL Thread_id killen. Er wird jedoch zuerst alle Zeilen in der Warteschlange in die Tabelle schreiben, bevor er sich beendet. Während dieser Zeit akzeptiert er keine neuen INSERT-Befehle von anderen Threads mehr. Wenn Sie danach einen INSERT DELAYED-Befehl ausführen, wird ein neuer Handler-Thread erzeugt.

  • Beachten Sie, dass oben Gesagtes bedeutet, dass INSERT DELAYED-Befehle höhere Priorität haben als normale INSERT-Befehle, wenn es einen INSERT DELAYED-Handler gibt, der bereits läuft! Andere Aktualisierungsbefehle müssen warten, bis die INSERT DELAYED-Warteschlange leer ist, jemand den Handler-Thread killt (mit KILL Thread_id) oder jemand FLUSH TABLES ausführt.

  • Die folgenden Status-Variablen stellen Informationen über INSERT DELAYED-Befehle bereits:

    VariableBedeutung
    Delayed_insert_threadNummer des Handler-Threads
    Delayed_writesAnzahl der Zeilen, die mit INSERT DELAYED geschrieben wurden
    Not_flushed_delayed_rowsAnzahl der Zeilen, die darauf warten, geschrieben zu werden

    Sie können diese Variablen betrachten, wenn Sie ein SHOW STATUS-Statement oder einen mysqladmin extended-status-Befehl ausführen.

Beachten Sie, dass INSERT DELAYED langsamer ist als ein normales INSERT, wenn die Tabelle nicht in Benutzung ist. Ausserdem gibt es einen zusätzlichen Overhead für den Server, um einen separaten Thread für jede Tabelle zu handhaben, für die Sie INSERT DELAYED benutzen. Das heißt, Sie sollten INSERT DELAYED nur benutzen, wenn Sie es wirklich benötigen!

7.4.5. UPDATE-Syntax

UPDATE [LOW_PRIORITY] [IGNORE] tabelle
    SET spalten_name1=ausdruck1, [spalten_name2=ausdruck2, ...]
    [WHERE where_definition]
    [LIMIT #]

UPDATE aktualisiert Spalten in bestehenden Tabellenzeilen mit neuen Werten. Die SET-Klausel gibt an, welche Spalten geändert werden sollen und welche Werte ihnen zugewiesen werden. Die WHERE-Klausel legt - falls angegeben - fest, welche Zeilen aktualisiert werden sollen. Ansonsten werden alle Zeile aktualisiert. Wenn die ORDER BY-Klausel angegeben ist, werden die Zeilen in der angegebenen Reihenfolge aktualisiert.

Wenn Sie das Schlüsselwort LOW_PRIORITY angeben, wird die Ausführung von UPDATE verzögert, bis keine anderen Clients mehr aus der Tabelle lesen.

Wenn Sie das Schlüsselwort IGNORE angeben, bricht das UPDATE-Statement nicht ab, selbst wenn während der Aktualisierung Fehler wegen doppelter Schlüsseleinträge auftreten. Zeilen, die Konflikte verursachen würden, werden nicht aktualisiert.

Wenn Sie auf eine Spalte von tabelle in einem Ausdruck zugreifen, benutzt UPDATE den momentanen Wert der Spalte. Folgendes Statement zum Beispiel setzt die age-Spalte auf ihren momentanen Wert plus 1:

mysql> UPDATE personen SET age=age+1;

UPDATE-Zuweisungen werden von links nach rechts ausgewertet. Folgendes Statement zum Beispiel verdoppelt die age-Spalte und inkrementiert sie danach:

mysql> UPDATE personen SET age=age*2, age=age+1;

Wenn Sie eine Spalte auf einen Wert setzen, den sie momentan besitzt, erkennt MySQL dies und aktualisiert sie nicht.

UPDATE gibt die Anzahl von Zeilen zurück, die tatsächlich geändert wurden. Ab MySQL-Version 3.22 gibt die C-API-Funktion mysql_info() die Anzahl von Zeilen zurück, die übereinstimmten und aktualisiert wurden, und die Anzahl von Warnungen, die während UPDATE geschahen.

In MySQL-Version 3.23 können Sie LIMIT # benutzen, um sicherzustellen, dass nur eine angegebene Anzahl von Zeilen geändert wird.

7.4.6. DELETE-Syntax

DELETE [LOW_PRIORITY | QUICK] FROM tabelle
    [WHERE where_definition]
    [ORDER BY ...]
    [LIMIT zeilen]

oder

DELETE [LOW_PRIORITY | QUICK] tabelle[.*] [tabelle[.*] ...] FROM
tabellenverweis [WHERE where_definition]

DELETE löscht Zeilen aus tabelle, die mit der in where_definition angegebenen Bedingung übereinstimmen, und gibt die Anzahl der gelöschten Datensätze zurück.

Wenn Sie DELETE ohne WHERE-Klausel angeben, werden alle Zeilen gelöscht. Wenn Sie das im AUTOCOMMIT-Modus machen, funktioniert es wie TRUNCATE. See Abschnitt 7.4.7, „TRUNCATE-Syntax“. In MySQL 3.23 gibt DELETE ohne eine WHERE-Klausel als Anzahl von betroffenen Datensätzen 0 zurück.

Wenn Sie wissen wollen, wie viele Datensätze tatsächlich gelöscht wurden, wenn Sie alle Zeilen löschen, und eine Geschwindigkeitseinbusse in Kauf nehmen, können Sie ein DELETE-Statement folgender Form eingeben:

mysql> DELETE FROM tabelle WHERE 1>0;

Beachten Sie, dass das VIEL langsamer als DELETE FROM tabelle ohne WHERE-Klausel ist, weil es Zeilen eine nach der anderen löscht.

Wenn Sie das Schlüsselwort LOW_PRIORITY angeben, wird die Ausführung von DELETE verzögert, bis kein anderer Client mehr aus der Tabelle liest.

Wenn Sie das Wort QUICK angeben, fasst der Tabellen-Handler während des Löschvorgangs keine Index-Blätter (Index Leafs) zusammen, was bestimmte Arten von Löschvorgängen beschleunigen kann.

In MyISAM-Tabellen werden gelöschte Datensätze in einer verknüpften Liste verwaltet und nachfolgende INSERT-Operationen benutzen alte Datensatzpositionen neu. Um unbenutzten Platz freizugeben und Dateigrößen zu verringern, benutzen Sie das OPTIMIZE TABLE-Statement oder das myisamchk-Dienstprogramm, um die Tabellen neu zu organisieren. OPTIMIZE TABLE ist einfacher, aber myisamchk ist schneller. Siehe Abschnitt 5.5.1, „OPTIMIZE TABLE-Syntax“ und Abschnitt 5.4.6.10, „Tabellenoptimierung“.

Das Multi-Tabellen-Löschformat wird ab MySQL 4.0.0 unterstützt.

Die Idee ist, dass nur übereinstimmende Zeilen aus den Tabellen, die VOR der FROM-Klausel stehen, gelöscht werden. Die Auswirkung ist, dass Sie Zeilen aus vielen Tabellen zugleich löschen können, sowie dass zusätzliche Tabellen zum Suchen benutzt werden.

Das .*-Zeichen nach den Tabellennamen ist nur aus Gründen der Kompatibilität mit Access vorhanden:

DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id

In diesem Fall werden übereinstimmende Zeilen nur aus den Tabellen t1 und t2 gelöscht.

ORDER BY und Benutzung mehrfacher Tabellen bei DELETE wird in MySQL 4.0 unterstützt.

Wenn eine ORDER BY-Klausel benutzt wird, werden die Zeilen in dieser Reihenfolge gelöscht. Das ist nur in Verbindung mit LIMIT wirklich sinnvoll. Beispiel:

DELETE FROM logdatei
WHERE user = 'jcole'
ORDER BY zeitstempel
LIMIT 1

Das löscht den ältesten Eintrag (von zeitstempel), wo die Zeile mit der WHERE-Klausel übereinstimmt.

Die MySQL-spezifische LIMIT rows-Option für DELETE weist den Server an, welche maximale Anzahl von Zeilen gelöscht wird, bevor die Kontrolle an den Client zurück gegeben wird. Das kann benutzt werden um sicherzustellen, dass ein bestimmter DELETE-Befehl nicht zu viel Zeit beansprucht. Sie können den DELETE-Befehl einfach wiederholen, bis die Anzahl betroffener Zeilen kleiner ist als der LIMIT-Wert.

7.4.7. TRUNCATE-Syntax

TRUNCATE TABLE tabelle

In Version 3.23 wird TRUNCATE TABLE auf COMMIT ; DELETE FROM tabelle gemappt. See Abschnitt 7.4.6, „DELETE-Syntax“.

Die Unterschiede zwischen TRUNCATE TABLE und DELETE FROM .. sind:

  • TRUNCATE führt ein Löschen und Neuerzeugen der Tabelle durch, was viel schneller sit, als Zeilen eine nach der anderen zu löschen.

  • Nicht transaktionssicher. Sie erhalten einen Fehler, wenn Sie eine aktive Transaktion haben oder eine aktive Tabellensperre.

  • Gibt die Anzahl gelöschter Zeilen nicht zurück.

  • Solange die Tabellendefinitionsdatei tabelle.frm gültig ist, kann die Tabelle auf diese Weise neu erzeugt werden, selbst wenn die Daten- oder Index-Dateien beschädigt wurden.

TRUNCATE ist eine Oracle-SQL-Erweiterung.

7.4.8. REPLACE-Syntax

    REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tabelle [(spalten_name,...)]
        VALUES (ausdruck,...),(...),...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tabelle [(spalten_name,...)]
        SELECT ...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tabelle
        SET spalten_name=ausdruck, spalten_name=ausdruck,...

REPLACE funktioniert genau wie INSERT, ausser dass der alte Datensatz gelöscht wird, bevor ein neuer eingefügt wird, wenn ein alter Datensatz in der Tabelle denselben Wert wie der neue auf einem eindeutigen Index hat. See Abschnitt 7.4.3, „HANDLER-Syntax“.

Mit anderen Worten können Sie auf die Werte einer alten Zeile nicht mit einem REPLACE-Statement zugreifen. In einigen alten MySQL-Versionen sah es so aus, als könnten Sie das tun, aber das war ein Bug und wurde korrigiert.

Wenn man einen REPLACE-Befehl benutzt, gibt mysql_affected_rows() 2 zurück, wenn die neue Zeile eine alte ersetzte. Das liegt daran, dass in diesem Fall eine Zeile eingefügt wurde und dann das Duplikat gelöscht wurde.

Das macht es einfach zu überprüfen, ob REPLACE eine Zeile hinzugefügt oder eine ersetzt hat.

7.4.9. LOAD DATA INFILE-Syntax

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'datei.txt'
    [REPLACE | IGNORE]
    INTO TABLE tabelle
    [FIELDS
        [TERMINATED BY '\t']
        [[OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '\\' ]
    ]
    [LINES TERMINATED BY '\n']
    [IGNORE Anzahl LINES]
    [(spalten_name,...)]

Das LOAD DATA INFILE-Statement liest Zeilen aus einer Textdatei in eine Tabelle mit sehr hoher Geschwindigkeit. Wenn das LOCAL-Schlüsselwort angegeben wird, wird die Datei vom Client-Host gelesen. Wenn LOCAL nicht angegeben wird, muss die Datei auf dem Server liegen. (LOCAL ist verfügbar ab MySQL-Version 3.22.6.)

Aus Sicherheitsgründen müssen Dateien, die als auf dem Server liegende Textdateien eingelesen werden, entweder im Datenbank-Verzeichnis liegen oder von allen lesbar sein. Darüber hinaus brauchen Sie, wenn Sie LOAD DATA INFILE mit Server-Dateien benutzen, die file-Berechtigung auf dem Server-Host. See Abschnitt 5.2.5, „Wie das Berechtigungssystem funktioniert“.

Wenn Sie das Schlüsselwort LOW_PRIORITY angeben, wird das LOAD DATA-Statement verzögert, bis keine anderen Clients mehr aus der Tabelle lesen.

Wenn Sie das Schlüsselwort CONCURRENT bei einer MyISAM-Tabelle angeben, können andere Threads Daten aus der Tabelle abrufen, während LOAD DATA ausgeführt wird. Die Benutzung dieser Option beeinflusst natürlich die Performance von LOAD DATA ein bisschen, selbst wenn kein anderer Thread die Tabelle zur gleichen Zeit benutzt.

LOCAL ist etwas langsamer, als wenn der Server direkt auf die Dateien zugreifen kann, weil die Inhalte der Datei vom Client-Host auf den Server-Host übertragen werden müssen. Auf der anderen Seite benötigen Sie keine file-Berechtigung, um lokale Dateien zu laden.

Wenn Sie MySQL vor Version 3.23.24 benutzen, können Sie nicht aus einer FIFO lesen, wenn Sie LOAD DATA INFILE benutzen. Wenn Sie aus einer FIFO lesen müssen (zum Beispiel aus der Ausgabe von gunzip), benutzen Sie statt dessen LOAD DATA LOCAL INFILE.

Sie können Daten-Dateien auch mit dem mysqlimport-Dienstprogramm laden; es arbeitet, indem es einen LOAD DATA INFILE-Befehl an den Server schickt. Die --local-Option veranlasst mysqlimport, Daten-Dateien vom Client-Host zu lesen. Sie können die --compress-Option angeben, um bessere Performance über langsame Netzwerke zu erzielen, wenn der Client und der Server das komprimierte Protokoll unterstützen.

Bei der Suche nach Dateien auf dem Server-Host geht der Server nach folgenden Regeln vor:

  • Wenn ein absoluter Pfadname angegeben wird, benutzt der Server den Pfadnamen so, wie er ist.

  • Wenn ein relativer Pfadname mit einer oder mehreren führenden Bestandteilen angegeben wird, sucht der Server die Datei relativ zum Daten-Verzeichnis des Servers.

  • Wenn ein Dateiname ohne führende Bestandteile angegeben wird, sucht der Server die Datei im Datenbank-Verzeichnis der aktuellen Datenbank.

Beachten Sie, dass diese Regeln bedeuten, dass eine Datei, die als ./meinedatei.txt angegeben wird, aus dem Daten-Verzeichnis des Servers gelesen wird, wohingegen eine Datei, die als meinedatei.txt angegeben wird, aus dem Datenbank-Verzeichnis der aktuellen Datenbank gelesen wird. Das folgende LOAD DATA-Statement beispielsweise liest die Datei daten.txt aus dem Datenbank-Verzeichnis von datenbank1, weil datenbank1 die aktuelle Datenbank ist, obwohl das Statement die Datei explizit in eine Tabelle in der datenbank2-Datenbank lädt:

mysql> USE datenbank1;
mysql> LOAD DATA INFILE "daten.txt" INTO TABLE datenbank2.meine_tabelle;

Die REPLACE- und IGNORE-Schlüsselwörter steuern die Handhabung von Eingabe-Datensätzen, die bestehende Datensätze auf eindeutigen Schlüsselwerten duplizieren. Wenn Sie REPLACE angeben, ersetzen neue Zeilen bestehende Zeilen, die denselben eindeutigen Schlüsselwert besitzen. Wenn Sie IGNORE angeben, werden Eingabe-Zeilen, die eine bestehende Zeile auf einem Schlüsselwert duplizieren, übersprungen. Wenn Sie keine der beiden Optionen angeben, tritt ein Fehler auf, wenn ein doppelter Schlüsselwert gefunden wird, und der Rest der Textdatei wird ignoriert.

Wenn Sie Daten aus einer lokalen Datei mit dem LOCAL-Schlüsselwort laden, hat der Server keine Möglichkeit, die Übertragung der Datei mitten in einer Operation zu beenden. Daher ist das vorgabemäßige Verhalten dasselbe, als wenn IGNORE angegeben wäre.

Wenn Sie LOAD DATA INFILE auf einer leeren MyISAM-Tabelle benutzen, werden alle nicht eindeutigen Indexe in einem separaten Stapel erzeugt (wie bei REPAIR). Das macht LOAD DATA INFILE normalerweise viel schneller, wenn Sie viele Indexe haben.

LOAD DATA INFILE ist das Komplement von SELECT ... INTO OUTFILE. See Abschnitt 7.4.1, „SELECT-Syntax“. Um Daten aus einer Datenbank in eine Datei zu schreiben, benutzen Sie SELECT ... INTO OUTFILE. Um die Datei zurück in die Datenbank zu lesen, benutzen Sie LOAD DATA INFILE. Die Syntax der FIELDS- und LINES-Klauseln ist für beide Befehle dieselbe. Beide Klauseln sind optional, aber FIELDS muss LINES vorangehen, wenn beide angegeben werden.

Wenn Sie eine FIELDS-Klausel angeben, ist jede ihrer Unterklauseln (TERMINATED BY, [OPTIONALLY] ENCLOSED BY und ESCAPED BY) ebenfalls optional, ausser dass Sie zumindest eine von ihnen angeben müssen.

Wenn Sie keine FIELDS-Klausel benutzen, sind die Vorgabewerte dieselben, als wenn Sie folgendes geschrieben hätten:

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'

Wenn Sie keine LINES-Klausel angeben, sind die Vorgabewerte dieselben, als wenn Sie folgendes geschrieben hätten:

LINES TERMINATED BY '\n'

Mit anderen Worten veranlassen die Vorgabewerte LOAD DATA INFILE, beim Lesen von Eingaben wie folgt zu arbeiten:

  • Zeilenbegrenzungen werden an Neue-Zeile-Zeichen gesucht (\n).

  • Zeilen werden an Tabulatoren (\t) in Felder aufgeteilt.

  • Es wird nicht davon ausgegangen, dass Felder in Anführungszeichen eingeschlossen sind.

  • Tabulatoren, Neue-Zeile-Zeichen oder ‘\’, denen ein ‘\’-Zeichen voran gestellt ist, werden als Literale interpretiert, die Teil des Feldwerts sind.

Im Vergleich dazu veranlassen die Vorgabewerte von SELECT ... INTO OUTFILE dieses, wie folgt zu arbeiten:

  • Zwischen Felder werden Tabulatoren (\t) geschrieben.

  • Felder werden nicht in Anführungsstriche geschrieben.

  • \’ wird benutzt, um Tabulator, Neue-Zeile-Zeichen oder ‘\’ innerhalb von Feldwerten zu escapen.

  • Am Ende von Zeilen werden Neue-Zeile-Zeichen (\n) geschrieben.

Beachten Sie, dass Sie FIELDS ESCAPED BY '\\' (mit zwei Backslashes) schreiben müssen, damit der Wert als ein einzelner Backslash gelesen wird.

Die IGNORE anzahl LINES-Option kann benutzt werden, um eine Kopfzeile aus Spaltennamen am Anfang der Datei zu ignorieren:

mysql> LOAD DATA INFILE "/tmp/datei.txt" into Tabelle test IGNORE 1 LINES;

Wenn Sie SELECT ... INTO OUTFILE zusammen mit LOAD DATA INFILE benutzen, um Daten aus einer Datenbank in eine Datei zu schreiben und dann die Datei später zurück in die Datenbank zu lesen, müssen die Optionen für die Behandlung von Feldern und Zeilen für beide Befehle übereinstimmen. Ansonsten interpretiert LOAD DATA INFILE die Inhalte der Datei nicht korrekt. Angenommen, Sie benutzen SELECT ... INTO OUTFILE, um eine Datei zu schreiben, deren Feldern durch Kommas begrenzt sind:

mysql> SELECT * INTO OUTFILE 'daten.txt'
           FIELDS TERMINATED BY ','
           FROM ...;

Um die Komma-begrenzte Datei wieder einzulesen, lautet das korrekte Statement:

mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle2
           FIELDS TERMINATED BY ',';

Wenn Sie statt dessen versuchen, die Datei mit dem unten stehenden Statement einzulesen, funktioniert das nicht, weil es LOAD DATA INFILE anweist, nach Tabulatoren zwischen Feldern zu suchen:

mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle2
           FIELDS TERMINATED BY '\t';

Das wahrscheinliche Ergebnis ist, dass jede Eingabezeile als ein einzelnes Feld interpretiert wird.

LOAD DATA INFILE kann auch benutzt werden, um Dateien aus externen Quellen einzulesen. Eine Datei im dBASE-Format zum Beispiel hat Felder, die durch Kommas getrennt und in Anführungszeichens eingeschlossen sind. Wenn Zeilen in der Datei von Neue-Zeile-Zeichen begrenzt sind, zeigt der unten stehende Befehl die Feld- und Zeilen-Handhabungsoptionen, die für das Laden der Datei benutzt werden:

mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle
           FIELDS TERMINATED BY ',' ENCLOSED BY '"'
           LINES TERMINATED BY '\n';

Jede der Feld- oder Zeilen-Handhabungsoptionen kann eine leere Zeichenkette angeben (''). Wenn nicht leer, müssen die FIELDS [OPTIONALLY] ENCLOSED BY- und FIELDS ESCAPED BY-Werte ein einzelnes Zeichen sein. Die FIELDS TERMINATED BY- und LINES TERMINATED BY-Werte können aus mehr als einem Zeichen bestehen. Um zum Beispiel Zeilen zu schreiben, die durch Wagenrücklauf-Neue-Zeile-Paare getrennt sind, oder um eine Datei einzulesen, die solche Zeilen enthält, geben Sie eine LINES TERMINATED BY '\r\n'-Klausel an.

Um beispielsweise eine Datei mit Witzen einzulesen, die durch %% getrennt sind, können Sie folgendes eingeben:

create table witze (a int not null auto_increment primary key, witz text not null);
load data infile "/tmp/witze.txt" into table witze fields terminated by "" lines terminated by "\n%%\n" (witz);

FIELDS [OPTIONALLY] ENCLOSED BY steuert die Art von Anführungszeichen von Feldern. Wenn Sie bei der Ausgabe (SELECT ... INTO OUTFILE) das Wort OPTIONALLY auslassen, sind alle Felder vom ENCLOSED BY-Zeichen eingeschlossen. Ein Beispiel einer solchen Ausgabe (mit Kommas als Feldbegrenzern) ist unten dargestellt:

"1","eine Zeichenkette","100.20"
"2","eine Zeichenkette, die ein Komma (,) enthält","102.20"
"3","eine Zeichenkette, die ein \" Anführungszeichen enthält","102.20"
"4","eine Zeichenkette, die ein \", Anführungszeichen und Komma (,) enthält","102.20"

Wenn Sie OPTIONALLY angeben, wird das ENCLOSED BY-Zeichen nur benutzt, um CHAR- und VARCHAR-Felder zu umschließen:

1,"eine Zeichenkette",100.20
2,"eine Zeichenkette mit einem , Komma",102.20
3,"eine Zeichenkette mit einem \" Anführungszeichen",102.20
4,"eine Zeichenkette mit \", Anführungszeichen und Komma",102.20

Beachten Sie, dass ENCLOSED BY-Zeichen innerhalb eines Feldwerts escapet werden, indem ihnen das ESCAPED BY-Zeichen vorangestellt wird. Beachten Sie auch, dass es bei der Angabe eines leeren empty ESCAPED BY-Werts möglich ist, Ausgaben zu erzeugen, die nicht korrekt von LOAD DATA INFILE eingelesen werden können. Die oben dargestellte Ausgabe zum Beispiel würde wie im Folgenden gezeigt erscheinen, wenn das Fluchtzeichen (Escape-Zeichen) leer ist. Beachten Sie, dass das zweite Feld der vierten Zeile nach dem Anführungszeichen ein Komma enthält, was (irrtümlich) als Feldbegrenzer interpretiert wird:

1,"eine Zeichenkette",100.20
2,"eine Zeichenkette mit einem , Komma",102.20
3,"eine Zeichenkette mit einem " Anführungszeichen",102.20
4,"eine Zeichenkette mit ", Anführungszeichen und Komma",102.20

Für die Eingabe wird das ENCLOSED BY-Zeichen - falls vorhanden - vom Ende von Feldwerten entfernt. (Das gilt, egal ob OPTIONALLY angegeben ist oder nicht; OPTIONALLY hat keine Auswirkung auf die Interpretation der Eingabe.) ENCLOSED BY-Zeichen, denen das ESCAPED BY-Zeichen vorangestellt ist, werden als Teil des aktuellen Feldwerts interpretiert. Zusätzlich werden verdoppelte ENCLOSED BY-Zeichen innerhalb von Feldern als ein einzelnes ENCLOSED BY-Zeichen interpretiert, falls das Feld selbst mit diesem Zeichen anfängt. Wenn beispielsweise ENCLOSED BY '"' angegeben wird, werden Anführungszeichen wie folgt behandelt:

"Der ""BIG"" Boss"  -> Der "BIG" Boss
Der "BIG" Boss      -> Der "BIG" Boss
Der ""BIG"" Boss    -> Der ""BIG"" Boss

FIELDS ESCAPED BY steuert, wie Sonderzeichen geschrieben oder gelesen werden. Wenn das FIELDS ESCAPED BY-Zeichen nicht leer ist, wird es benutzt, um es bei der Ausgabe folgenden Zeichen voranzustellen:

  • Dem FIELDS ESCAPED BY-Zeichen

  • Dem FIELDS [OPTIONALLY] ENCLOSED BY-Zeichen

  • Dem ersten Zeichen von FIELDS TERMINATED BY- und LINES TERMINATED BY-Werten

  • ASCII 0 (was tatsächlich nach dem Fluchtzeichen (Escape-Zeichen) als ASCII '0' geschrieben wird, nicht ein Byte mit Wert 0)

Wenn das FIELDS ESCAPED BY-Zeichen leer ist, werden keine Zeichen escapet. Es ist wahrscheinlich keine gute Idee, ein leeres Fluchtzeichen (Escape-Zeichen) anzugeben, insbesondere, wenn Feldwerte in Ihren Daten irgend welche der Zeichen enthalten, die gerade aufgelistet wurden.

Für die Eingabe werden, falls das FIELDS ESCAPED BY-Zeichen nicht leer ist, Vorkommen dieses Zeichens entfernt, und die folgenden Zeichen werden buchstäblich als Teil des Feldwerts genommen. Die Ausnahmen sind ein escapetes ‘0’ oder ‘N’ (beispielsweise \0 oder \N, wenn das Fluchtzeichen (Escape-Zeichen) ‘\’ ist). Diese Folgen werden als ASCII-0 interpretiert (ein Byte mit Wert 0) und NULL. Siehe unten zu den Regeln der NULL-Handhabung.

Weitere Informationen über die ‘\’-Escape-Syntax finden Sie unter Abschnitt 7.1.1, „Literale: Wie Zeichenketten und Zahlen geschrieben werden“.

In bestimmten Fällen beeinflussen sich die Handhabungsoptionen für Felder und Zeilen gegenseitig:

  • Wenn LINES TERMINATED BY eine leere Zeichenkette ist und FIELDS TERMINATED BY nicht leer ist, werden Zeile auch durch FIELDS TERMINATED BY begrenzt.

  • Wenn die FIELDS TERMINATED BY- und FIELDS ENCLOSED BY-Werte beide leer sind (''), wird ein Festzeilen- (nicht begrenztes) Format benutzt. Beim Festzeilenformat werden keine Begrenzer zwischen Feldern benutzt. Statt dessen werden Spaltenwerte geschrieben und gelesen, indem die Anzeigebreite der Spalten benutzt wird. Wenn eine Spalte zum Beispiel als INT(7) deklariert ist, werden Werte für die Spalte mit 7-Zeichen-Feldern geschrieben. Bei der Eingabe werden Werte für die Spalte mit 7-Zeichen-Feldern bezogen. Festzeilenformate beeinflussen auch die Handhabung von NULL-Werten (siehe unten). Beachten Sie, dass Festgrößenformate nicht funktionieren, wenn Sie einen Multi-Byte-Zeichensatz benutzen.

Die Handhabung von NULL-Werten variiert in Abhängigkeit von den FIELDS- und LINES-Optionen, die Sie benutzen:

  • Bei den vorgabemäßigen FIELDS- und LINES-Werten wird NULL für die Ausgabe als \N geschrieben und \N als NULL für die Eingabe gelesen (unter der Annahme, dass das ESCAPED BY-Zeichen ‘\’ ist).

  • Wenn FIELDS ENCLOSED BY nicht leer ist, wird ein Feld, das das Literalwort NULL als seinen Wert enthält, als NULL-Wert gelesen (das weicht ab vom Wort NULL, begrenzt durch FIELDS ENCLOSED BY-Zeichen, was als die Zeichenkette 'NULL' gelesen wird).

  • Wenn FIELDS ESCAPED BY leer ist, wird NULL als das Wort NULL gelesen.

  • Beim Festzeilenformat (was auftritt, wenn sowohl FIELDS TERMINATED BY als auch FIELDS ENCLOSED BY leer sind), wird NULL als leere Zeichenkette geschrieben. Beachten Sie, dass das dazu führt, dass NULL-Werte und leere Zeichenketten in der Tabelle nicht mehr unterscheidbar sind, wenn in die Datei geschrieben wird, weil sie beide als leere Zeichenketten geschrieben werden. Wenn Sie in der Lage sein müssen, diese zu unterscheiden, wenn Sie die Datei wieder einlesen, sollten Sie kein Festzeilenformat benutzen.

Einige Fälle werden von LOAD DATA INFILE nicht unterstützt:

  • Festgrößenzeilen (FIELDS TERMINATED BY und FIELDS ENCLOSED BY sind beide leer) und BLOB- oder TEXT-Spalten.

  • Wenn Sie ein Trennzeichen angeben, das dasselbe wie ein anderes ist oder einem anderen vorangestellt ist. LOAD DATA INFILE kann in diesem Fall die Eingabe nicht korrekt interpretieren. Folgende FIELDS-Klausel zum Beispiel würde Probleme bereiten:

    FIELDS TERMINATED BY '"' ENCLOSED BY '"'
    
  • Wenn FIELDS ESCAPED BY leer ist, führt ein Feldwert, der ein Vorkommen von FIELDS ENCLOSED BY oder LINES TERMINATED BY gefolgt vom FIELDS TERMINATED BY-Wert enthält, dazu, dass LOAD DATA INFILE mit dem Einlesen eines Feldes oder einer Zeile zu früh aufhört. Das passiert, weil LOAD DATA INFILE nicht korrekt festlegen kann, wo der Feld- oder Zeilenwert endet.

Das folgende Beispiel lädt alle Spalten der personen-Tabelle:

mysql> LOAD DATA INFILE 'personen.txt' INTO TABLE personen;

Es ist keine Felderliste angegeben, daher erwartet LOAD DATA INFILE, dass die Eingabefelder ein Feld für jede Tabellenspalte enthalten. Die Vorgabewerte für FIELDS und LINES-Werte werden benutzt.

Wenn Sie Daten nur in einige Tabellenspalten einladen wollen, geben Sie eine Felderliste an:

mysql> LOAD DATA INFILE 'personen.txt'
           INTO TABLE personen (spalte1,spalte2,...);

Eine Felderliste müssen Sie ausserdem angeben, wenn die Reihenfolge der Felder in der Eingabedatei von der Reihenfolge der Tabellenspalten abweicht. Ansonsten kann MySQL nicht feststellen, wie er Eingabefelder Tabellenspalten zuordnen soll.

Wenn eine Zeile zu wenige Felder hat, werden die Spalten, für die es kein Eingabefeld gibt, auf ihre Vorgabewerte gesetzt. Die Zuweisung von Vorgabewerten ist unter Abschnitt 7.5.3, „CREATE TABLE-Syntax“ beschrieben.

Ein leerer Feldwert wird anders interpretiert als ein fehlender Feldwert:

  • Bei Zeichenketten-Typen wird die Spalte auf die leere Zeichenkette gesetzt.

  • Bei numerischen Typen wird die Spalte auf 0 gesetzt.

  • Bei Datums- und Zeit-Typen wird die Spalte auf den entsprechenden ``0''-Wert für den Typ gesetzt. See Abschnitt 7.2.2, „Datums- und Zeit-Typen“.

Beachten Sie, dass das dieselben Werte sind, die sich ergeben, wenn Sie einer Zeichenkette explizit eine leere Zeichenkette zuweisen oder solches für einen DATE- oder TIME-Type in einem INSERT- oder UPDATE-Statement tun.

TIMESTAMP-Spalten werden nur dann auf das aktuelle Datum und die aktuelle Zeit gesetzt, wenn es einen NULL-Wert für die Spalte gibt oder (nur für die erste TIMESTAMP-Spalte) die TIMESTAMP-Spalte in der Felderliste ausgelassen ist, wenn eine Felderliste angegeben wird.

Wenn eine Eingabezeile zu viele Felder hat, werden die zusätzlichen Felder ignoriert und die Anzahl von Warnungen herauf gezählt.

LOAD DATA INFILE betrachtet alle Eingaben als Zeichenketten, daher können Sie für ENUM oder SET-Spalten keine numerischen Werte benutzen, wie Sie das bei INSERT-Statements tun können. Alle ENUM- und SET-Werte müssen als Zeichenketten angegeben werden!

Wenn Sie die C-API benutzen, können Sie Informationen über die Anfrage durch den Aufruf der API-Funktion mysql_info() erhalten, wenn die LOAD DATA INFILE-Anfrage beendet ist. Das Format der Informationszeichenkette sieht wie folgt aus:

Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

Warnungen erfolgen unter denselben Umständen, als wenn Werte über das INSERT-Statement (see Abschnitt 7.4.3, „HANDLER-Syntax“) eingefügt werden, ausser dass LOAD DATA INFILE zusätzlich Warnungen erzeugt, wenn es zu wenige oder zu viele Felder in der Eingabezeile gibt. Die Warnungen werden nirgendwo gespeichert; die Anzahl von Warnungen kann daher nur als Anhaltspunkt dafür benutzt werden, ob alles gut ging. Wenn Sie Warnungen erhalten und genau wissen wollen, warum Sie diese erhalten, besteht eine Möglichkeit dafür darin, SELECT ... INTO OUTFILE in eine andere Datei zu benutzen und diese mit der Original-Eingabedatei zu vergleichen.

Wenn Sie wollen, dass LOAD DATA aus einer Pipe liest, können Sie folgenden Trick benutzen:

mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x
mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x

Wenn Sie eine MySQL-Version vor 3.23.25 benutzen, können Sie das nur mit LOAD DATA LOCAL INFILE durchführen.

Weitere Informationen über die Effizienz von INSERT versus LOAD DATA INFILE und Möglichkeiten, die Geschwindigkeit zu steigern, finden Sie unter LOAD DATA INFILE, See Abschnitt 6.2.8, „Geschwindigkeit von INSERT-Anfragen“.

7.5. Datendefinition: CREATE, DROP, ALTER

7.5.1. CREATE DATABASE-Syntax

CREATE DATABASE [IF NOT EXISTS] datenbank

CREATE DATABASE erzeugt eine Datenbank mit dem angegebenen Namen. Die Regeln für erlaubte Datenbanknamen finden Sie unter Abschnitt 7.1.2, „Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen“. Ein Fehler tritt auf, wenn die Datenbank bereits existiert und Sie IF NOT EXISTS nicht angeben.

Datenbanken sind in MySQL als Verzeichnisse implementiert, die Dateien enthalten, die den Tabellen in der Datenbank entsprechen. Weil es keine Tabellen in einer Datenbank gibt, wenn diese erstmalig erzeugt wird, erzeugt das CREATE DATABASE-Statement nur ein Verzeichnis unter dem MySQL-Daten-Verzeichnis.

Sie können auch mit mysqladmin Datenbanken erzeugen. See Abschnitt 5.8, „Clientseitige Skripte und Hilfsprogramme von MySQL“.

7.5.2. DROP DATABASE-Syntax

DROP DATABASE [IF EXISTS] datenbank

DROP DATABASE löscht alle Tabellen in der Datenbank und löscht die Datenbank. Wenn Sie ein DROP DATABASE auf eine symbolisch verknüpfte Datenbank ausführen, werden sowohl der Link als auch die Original-Datenbank gelöscht. Seien Sie mit diesem Befehl sehr vorsichtig!

DROP DATABASE gibt die Anzahl von Dateien zurück, die aus dem Datenbank-Verzeichnis entfernt wurden. Normalerweise ist das dreimal die Anzahl der Tabellen, weil normalerweise jede Tabelle einer .MYD-Datei, einer .MYI-Datei und einer .frm-Datei entspricht.

Der DROP DATABASE-Befehl entfernt aus dem angegebenen Datenbank-Verzeichnis alle Dateien mit folgenden Erweiterungen:

.BAK.DAT.HSH.ISD
.ISM.ISM.MRG.MYD
.MYI.db.frm 

Alle Unterverzeichnisse, die aus 2 Ziffern bestehen (RAID-Verzeichnisse), werden ebenfalls gelöscht.

Ab MySQL-Version 3.22 können Sie die Schlüsselwörter IF EXISTS benutzen, um eine Fehlermeldung zu vermeiden, die erscheint, wenn die Datenbank nicht existiert.

Sie können Datenbanken auch mit mysqladmin löschen. See Abschnitt 5.8, „Clientseitige Skripte und Hilfsprogramme von MySQL“.

7.5.3. CREATE TABLE-Syntax

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tabelle [(create_definition,...)]
[tabellen_optionen] [select_statement]

create_definition:
  spalten_name typ [NOT NULL | NULL] [DEFAULT vorgabe_wert] [AUTO_INCREMENT]
            [PRIMARY KEY] [referenz_definition]
  oder    PRIMARY KEY (index_spalten_name,...)
  oder    KEY [index_name] (index_spalten_name,...)
  oder    INDEX [index_name] (index_spalten_name,...)
  oder    UNIQUE [INDEX] [index_name] (index_spalten_name,...)
  oder    FULLTEXT [INDEX] [index_name] (index_spalten_name,...)
  oder    [CONSTRAINT symbol] FOREIGN KEY index_name (index_spalten_name,...)
            [referenz_definition]
  oder    CHECK (ausdruck)

typ:
        TINYINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    SMALLINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    MEDIUMINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    INT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    INTEGER[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    BIGINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    REAL[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
  oder    DOUBLE[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
  oder    FLOAT[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
  oder    DECIMAL(laenge,dezimalstellen) [UNSIGNED] [ZEROFILL]
  oder    NUMERIC(laenge,dezimalstellen) [UNSIGNED] [ZEROFILL]
  oder    CHAR(laenge) [BINARY]
  oder    VARCHAR(laenge) [BINARY]
  oder    DATE
  oder    TIME
  oder    TIMESTAMP
  oder    DATETIME
  oder    TINYBLOB
  oder    BLOB
  oder    MEDIUMBLOB
  oder    LONGBLOB
  oder    TINYTEXT
  oder    TEXT
  oder    MEDIUMTEXT
  oder    LONGTEXT
  oder    ENUM(wert1,wert2,wert3,...)
  oder    SET(wert1,wert2,wert3,...)

index_spalten_name:
        spalten_name [(laenge)]

referenz_definition:
        REFERENCES tabelle [(index_spalten_name,...)]
                   [MATCH FULL | MATCH PARTIAL]
                   [ON DELETE referenz_option]
                   [ON UPDATE referenz_option]

referenz_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

tabellen_optionen:
	TYPE = {BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM }
or	AUTO_INCREMENT = #
or	AVG_ROW_LENGTH = #
or	CHECKSUM = {0 | 1}
or	COMMENT = "string"
or	MAX_ROWS = #
or	MIN_ROWS = #
or	PACK_KEYS = {0 | 1 | DEFAULT}
or	PASSWORD = "string"
or	DELAY_KEY_WRITE = {0 | 1}
or      ROW_FORMAT= { default | dynamic | fixed | compressed }
or	RAID_TYPE= {1 | STRIPED | RAID0 } RAID_CHUNKS=#  RAID_CHUNKSIZE=#
or	UNION = (tabelle,[tabelle...])
or	INSERT_METHOD= {NO | FIRST | LAST }
or      DATA directory="verzeichnis"
or      INDEX directory="verzeichnis"

select_statement:
	[IGNORE | REPLACE] SELECT ...  (jedes zulässige SELECT-Statement)

CREATE TABLE erzeugt eine Tabelle mit dem angegebenen Namen in der aktuellen Datenbank. Die Regeln für erlaubte Tabellennamen finden Sie unter Abschnitt 7.1.2, „Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen“. Ein Fehler tritt auf, wenn es keine aktuelle Datenbank gibt oder wenn die Tabelle bereits existiert.

Ab MySQL-Version 3.22 kann der Tabellenname als datenbank.tabelle angegeben werden. Das funktioniert unabhängig davon, ob es eine aktuelle Datenbank gibt oder nicht.

In MySQL-Version 3.23 können Sie das TEMPORARY-Schlüsselwort benutzen, wenn Sie eine Tabelle erzeugen. Eine temporäre Tabelle wird automatisch gelöscht, wenn eine Verbindung stirbt und der Name sich auf die Verbindung bezieht. Das bedeutet, dass zwei verschiedene Verbindungen beide denselben temporären Tabellenname benutzen können, oder miteinander oder einer bestehenden Tabelle gleichen Namens in Konflikt zu geraten. (Die bestehende Tabelle ist versteckt, bis die temporäre Tabelle gelöscht wird.)

Ab MySQL-Version 3.23 können Sie die Schlüsselwörter IF NOT EXISTS benutzen, so dass kein Fehler auftritt, wenn die Tabelle bereits besteht. Beachten Sie, dass keine Überprüfung erfolgt, dass die Tabellenstrukturen identisch sind.

Jede Tabelle tabelle wird durch einige Dateien im Datenbank-Verzeichnis dargestellt. Im Falle von MyISAM-Tabellen erhalten Sie:

DateiZweck
tabelle.frmTabellendefinitionsdatei (form)
tabelle.MYDDaten-Datei
tabelle.MYIIndex-Datei

Weitere Information über die Eigenschaften der verschiedenen Spaltentypen finden Sie unter Abschnitt 7.2, „Spaltentypen“:

  • Wenn weder NULL noch NOT NULL angegeben ist, wird die Spalte behandelt, als wenn NULL angegeben worden wäre.

  • Eine Ganzzahl-Spalte kann das zusätzliche Attribut AUTO_INCREMENT haben. Wenn Sie einen Wert von NULL (empfohlen) oder 0 in eine AUTO_INCREMENT-Spalte einfügen, wird die Spalte auf wert+1 gesetzt, wobei wert der größte momentan in der Tabelle vorhandene Spaltenwert ist. AUTO_INCREMENT-Folgen fangen mit 1 an. See Abschnitt 9.4.3.30, „mysql_insert_id().

    Wenn Sie eine Zeile löschen, die den höchsten Wert einer AUTO_INCREMENT-Spalte enthält, wird der Wert bei einer ISAM- oder BDB-Tabelle wieder verwendet, nicht aber bei einer MyISAM- oder InnoDB-Tabelle. Wenn Sie alle Zeilen in der Tabelle mit DELETE FROM tabelle (ohne ein WHERE) im AUTOCOMMIT-Modus löschen, fängt die Folge bei allen Tabellentypen von Neuem an.

    HINWEIS: Es darf nur eine AUTO_INCREMENT-Spalte pro Tabelle geben und diese muss indiziert sein. MySQL-Version 3.23 funktioniert darüber hinaus nur korrekt, wenn die AUTO_INCREMENT-Spalte nur positive Werte hat. Das Einfügen einer negativen Zahl wird als Einfügen einer sehr großen positiven Zahl betrachtet. Damit werden Genauigkeitsprobleme vermieden, wenn Zahlen vom positiven zum negativen Bereich übergehen. Ausserdem wird sichergestellt, dass man nicht versehentlich eine AUTO_INCREMENT-Spalte erhält, die 0 enthält.

    Um MySQL kompatibel mit einigen ODBC-Applikationen zu machen, können Sie die letzte eingefügte Zeile mit folgender Anfrage finden:

    SELECT * FROM tabelle WHERE auto_spalte IS NULL
    
  • NULL-Werte werden bei TIMESTAMP-Spalten anders als bei anderen Spaltentypen gehandhabt. Sie können NULL nicht wortgetreu in einer TIMESTAMP-Spalte speichern: Wenn Sie die Spalte auf NULL setzen, wird sie auf das aktuelle Datum und die aktuelle Zeit gesetzt. Weil TIMESTAMP-Spalten sich auf diese Art verhalten, treffen die NULL- und NOT NULL-Attribute nicht auf normale Art zu und werden ignoriert, wenn Sie sie angeben.

    Auf der anderen Seite berichtet der Server, um es für MySQL-Clients leichter zu machen, TIMESTAMP-Spalten zu benutzen, dass solchen Spalten NULL-Werte zugewiesen werden können (was stimmt), obwohl TIMESTAMP nie wirklich einen NULL-Wert enthalten wird. Sie können das sehen, wenn Sie DESCRIBE tabelle eingeben, um eine Beschreibung Ihrer Tabelle zu erhalten.

    Beachten Sie, dass das Setzen einer TIMESTAMP-Spalte auf 0 nicht dasselbe ist wie das Setzen auf NULL, weil 0 ein gültiger TIMESTAMP-Wert ist.

  • Wenn kein DEFAULT-Wert für eine Spalte angegeben wird, weist MySQL automatisch einen zu.

    Wenn die Spalte NULL als Wert aufnehmen darf, ist der Vorgabewert NULL.

    Wenn die Spalte als NOT NULL deklariert ist, hängt der Vorgabewert vom Spaltentyp ab:

    • Bei numerischen Typen ausser denen, die mit dem AUTO_INCREMENT-Attribut deklariert wurden, ist der Vorgabewert 0. Bei einer AUTO_INCREMENT-Spalte ist der Vorgabewert der nächste Wert in der Folge.

    • Bei Datums- und Zeit-Typen ausser TIMESTAMP ist der Vorgabewert der entsprechende 0-Wert für den Typ. Bei der ersten TIMESTAMP-Spalte einer Tabelle ist der Vorgabewert das aktuelle Datum und die aktuelle Zeit. See Abschnitt 7.2.2, „Datums- und Zeit-Typen“.

    • Bei Zeichenketten-Typen ausser ENUM ist der Vorgabewert die leere Zeichenkette. Bei ENUM ist der Vorgabewert der erste Aufzählungswert.

    Vorgabewerte müssen Konstanten sein. Das heißt zum Beispiel, dass Sie den Vorgabewert einer DATE-Spalte nicht als Wert einer Funktion wie NOW() oder CURRENT_DATE setzen können.

  • KEY ist ein Synonym für INDEX.

  • In MySQL darf ein UNIQUE-Schlüssel nur unterschiedliche Werte haben. Ein Fehler tritt auf, wenn Sie versuchen, eine neue Zeile hinzuzufügen, der Schlüsselwert dem einer bestehenden Zeile entspricht.

  • Ein PRIMARY KEY ist ein eindeutiger KEY mit der zusätzlichen Beschränkung, dass alle Schlüsselspalten als NOT NULL deklariert sein müssen. In MySQL wird der Schlüssel PRIMARY genannt. Eine Tabelle darf nur einen PRIMARY KEY haben. Wenn Sie keinen PRIMARY KEY haben und irgend welche Applikationen nach einem PRIMARY KEY in Ihrer Tabelle verlangen, gibt MySQL den ersten UNIQUE-Schlüssel, der keinerlei NULL-Spalten hat, als PRIMARY KEY zurück.

  • Ein PRIMARY KEY kann ein mehrspaltiger Index sein. Sie können jedoch keinen mehrspaltiger Index mit dem PRIMARY KEY-Schlüsselattribut in einer Spaltenspezifikation erzeugen. Wenn Sie das tun, wird nur die erste Spalte als PRIMARY gekennzeichnet. Sie müssen die PRIMARY KEY(index_spalten_name, ...)-Syntax benutzen.

  • Wenn der PRIMARY- oder UNIQUE-Schlüssel aus nur einer Spalte besteht und diese vom Typ Ganzzahl ist, können Sie auf sie auch als _rowid verweisen (neu ab Version 3.23.11).

  • Wenn Sie einem Index keinen Namen zuweisen, wird dem Index derselbe Name zugewiesen wie der erste index_spalten_name, mit einem optionalen Suffix (_2, _3, ...), um ihn eindeutig zu machen. Sie können die Indexnamen für eine Tabelle mit SHOW INDEX FROM tabelle anzeigen. See Abschnitt 5.5.5, „SHOW-Syntax“.

  • Nur der MyISAM-Tabellentyp unterstützt Indexe auf Spalten, die NULL-Werte enthalten können. In anderen Fällen müssen Sie solche Spalten als NOT NULL deklarieren, sonst tritt ein Fehler auf.

  • Mit der spalten_name(laenge)-Syntax können Sie einen Index festlegen, der nur einen Teil einer CHAR- oder VARCHAR-Spalte enthält. Das kann die Index-Datei viel kleiner machen. See Abschnitt 6.4.4, „Spalten-Indexe“.

  • Nur der MyISAM-Tabellentyp unterstützt Indexierung auf BLOB- und TEXT-Spalten. Wenn Sie einen Index auf eine BLOB- oder TEXT-Spalte setzen, MÜSSEN Sie immer die Länge des Indexes angeben:

    CREATE TABLE test (blob_spalte BLOB, index(blob_spalte(10)));
    

  • Wenn Sie ORDER BY oder GROUP BY bei einer TEXT- oder BLOB-Spalte benutzen, werden nur die ersten max_sort_length Bytes benutzt. See Abschnitt 7.2.3.2, „Die BLOB- und TEXT-Typen“.

  • Ab MySQL-Version 3.23.23 können Sie auch spezielle FULLTEXT-Indexe erzeugen, Diese werden für Volltextsuche benutzt. Nur der MyISAM-Tabellentyp unterstützt FULLTEXT-Indexe. Sie können auf VARCHAR- und TEXT-Spalten erzeugt werden. Die Indexierung erfolgt immer über die gesamte Spalte, teilweise Indexierung wird nicht unterstützt. Siehe Abschnitt 7.8, „MySQL-Volltextsuche“ für Details zur Funktionsweise.

  • Die FOREIGN KEY-, CHECK- und REFERENCES-Klauseln tun momentan noch nichts. Die Syntax wird nur aus Gründen der Kompatibilität bereit gestellt, um das Portieren von Code von anderen SQL-Servern zu erleichtern und um Applikationen laufen zu lassen, die Tabellen mit Referenzen erzeugen.

    See Abschnitt 2.7.4.5, „Fremdschlüssel“.

  • Jede NULL-Spalte benötigt ein zusätzliches Bit, gerundet auf das nächste Byte.

  • Die maximale Datensatzlänge in Bytes kann wie folgt berechnet werden:

    Zeilenlänge = 1
                  + (Summe Spaltenlängen)
                  + (Anzahl von NULL-Spalten + 7)/8
                  + (Anzahl von Spalten variabler Länge)
    
  • Die tabellen_optionen- und SELECT-Optionen sind implementiert ab MySQL-Version 3.23.

    Die unterschiedlichen Tabellentypen sind:

    BDB oder Berkeley_dbTransaktionssichere Tabellen mit Seitensperren (Page Locking). See Abschnitt 8.6, „BDB- oder Berkeley_db-Tabellen“.
    HEAPDie Daten dieser Tabelle werden nur im Arbeitsspeicher gehalten. See Abschnitt 8.4, „HEAP-Tabellen“.
    ISAMDer Original-Tabellen-Handler. See Abschnitt 8.3, „ISAM-Tabellen“.
    InnoDBTransaktionssichere Tabellen mit Zeilensperren. See Abschnitt 8.5, „InnoDB-Tabellen“.
    MERGEEine Sammlung von MyISAM-Tabellen, die als eine Tabelle benutzt werden. See Abschnitt 8.2, „MERGE-Tabellen“.
    MRG_MERGEEin Alias für MERGE-Tabellen.
    MyISAMDer neue binäre portable Tabellen-Handler, der ISAM ersetzt. See Abschnitt 8.1, „MyISAM-Tabellen“.

    See Kapitel 8, MySQL-Tabellentypen.

    Wenn ein Tabellentyp angegeben wird und dieser besondere Typ nicht verfügbar ist, wählt MySQL den Tabellentyp, der dem angegebenen am nächsten kommt. Wenn beispielsweise TYPE=BDB angegeben wird und die Distribution von MySQL keine BDB-Tabellen unterstützt, wird die Tabelle statt dessen als MyISAM erzeugt.

    Die anderen Tabellenoptionen werden benutzt, um das Verhalten der Tabelle zu optimieren. In den meisten Fällen müssen Sie keine davon angeben. Die Optionen funktionieren bei allen Tabellentypen, falls nicht anders angegeben:

    AUTO_INCREMENTDer nächste auto_increment-Wert, den Sie für Ihre Tabelle setzen wollen (MyISAM).
    AVG_ROW_LENGTHNäherungsweise die durchschnittliche Zeilenlänge Ihrer Tabelle. Diese Option müssen Sie nur für große Tabellen mit unterschiedlich großen Datensätzen setzen.
    CHECKSUMSetzen Sie diesen Wert auf 1, wenn Sie wollen, dass MySQL eine Prüfsumme für alle Zeilen unterhält (macht die Tabelle ein bisschen langsamer bei der Aktualisierung, aber macht es einfacher, beschädigte Tabellen zu finden) (MyISAM).
    COMMENTEin 60-Zeichen-Kommentar für Ihre Tabelle.
    MAX_ROWSMaximale Anzahl von Zeilen, die Sie in Ihrer Tabelle zu speichern planen.
    MIN_ROWSMinimale Anzahl von Zeilen, die Sie in Ihrer Tabelle zu speichern planen.
    PACK_KEYSSetzen Sie diesen Wert auf 1, wenn Sie einen kleineren Index erhalten wollen. Das macht Aktualisierungen üblicherweise langsamer und liest schneller (MyISAM, ISAM). Setzen auf 0 schaltet die Komprimierung von Schlüsseln ab. Setzen auf DEFAULT (MySQL 4.0) weist die Tabellen-Handler an, nur lange CHAR- / VARCHAR-Spalten zu packen.
    PASSWORDVerschlüsselt die .frm-Datei mit einem Passwort. Diese Option tut nichts in der Standard-MySQL-Version.
    DELAY_KEY_WRITESetzen Sie diesen Wert auf 1, wenn Sie Schlüssel-Tabellen-Aktualisierungen verzögern wollen, bis die Tabelle geschlossen wird (MyISAM).
    ROW_FORMATDefiniert, wie die Zeilen gespeichert werden sollen. Momentan funktioniert diese Option nur bei MyISAM-Tabellen, die die DYNAMIC- und FIXED-Zeilenformate unterstützen. See Abschnitt 8.1.2, „MyISAM-Tabellenformate“.

    Wenn Sie eine MyISAM-Tabelle benutzen, verwendet MySQL das Produkt aus max_rows * avg_row_length um zu entscheiden, wie Groß die resultierende Tabelle sein wird. Wenn Sie keine der obigen Optionen angeben, ist die maximale Größe für eine Tabelle 4 GB (oder 2 GB, wenn Ihr Betriebssystem nur 2 GB-Tabellen unterstützt). Das geschieht, um Zeigergrößen gering zu halten und um den Index kleiner und schneller zu machen, wenn Sie nicht wirklich große Dateien benötigen.

    Wenn Sie PACK_KEYS nicht benutzen, ist die Vorgabe, nur Zeichenketten zu komprimieren, nicht Zahlen. Wenn Sie PACK_KEYS=1 benutzen, werden auch Zahlen komprimiert.

    Wenn Sie binäre Zahlschlüssel komprimieren, benutzt MySQL die Präfix-Komprimierung. Das bedeutet, dass Sie nur dann einen Nutzen daraus ziehen, wenn Sie Zahlen haben, die sich oft wiederholen. Präfix-Kompression bedeutet, das jeder Schlüssel ein zusätzliches Byte benötigt, um darzustellen, wie viele Bytes des vorherigen Schlüssels für den nächsten Schlüssel dieselben sind (beachten Sie, dass der Zeiger auf die Zeile in der Reihenfolge 'hohes Byte zuerst' direkt nach dem Schlüssel gespeichert wird, um die Kompression zu verbessern). Das heißt, wenn Sie viele gleiche Schlüssel auf zwei Zeilen hintereinander haben, werden alle folgenden 'gleichen' Schlüssel üblicherweise nur 2 Bytes in Anspruch nehmen (inklusive dem Zeiger auf die Zeile). Vergleichen Sie das mit dem Normalfall, bei dem die folgenden Schlüssel speicher_platz_fuer_schlüssel + zeiger_groesse beanspruchen (üblicherweise 4). Auf der anderen Seite verlieren Sie 1 Byte pro Schlüssel, wenn alle Schlüssel völlig unterschiedlich sind, falls der Schlüssel kein Schlüssel ist, der NULL-Werte haben kann (in diesem Fall wird die komprimierte Schlüssellänge, die im selben Byte gespeichert ist, benutzt, um zu kennzeichnen, ob ein Schlüssel NULL ist).

  • Wenn Sie ein SELECT nach dem CREATE-Statement angeben, erzeugt MySQL neue Felder für alle Elemente im SELECT. Beispiel:

    mysql> CREATE TABLE test (a int not null auto_increment,
               primary key (a), key(b))
               TYPE=MyISAM SELECT b,c from test2;
    

    Das erzeugt eine MyISAM-Tabelle mit drei Spalten a, b und c. Beachten Sie, dass die Spalten des SELECT-Statements an die rechte Seite der Tabelle angehängt werden, nicht überlappend. Nehmen wir folgendes 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 jede Zeile in Tabelle foo wird eine Zeile in bar mit den Werten von foo und Vorgabewerten für die neuen Spalten eingefügt.

    CREATE TABLE ... SELECT erzeugt nicht automatisch irgend welche Indexe. Das wird absichtlich gemacht, um den Befehl so flexibel wie möglich zu machen. Wenn Sie Indexe in der erzeugten Tabelle haben wollen, geben Sie diese vor dem SELECT-Statement an:

    mysql> create table bar (unique (n)) select n von foo;
    

    Wenn Fehler beim Kopieren der Daten in die Tabelle auftreten, wird diese automatisch gelöscht.

    Um sicherzustellen, dass die Update-Log-Datei/Binär-Log-Datei benutzt werden kann, um die Original-Tabellen neu zu erzeugen, läßt MySQL keine gleichzeitigen Einfügeoperationen während CREATE TABLE .... SELECT zu.

  • Die RAID_TYPE-Option hilft, die 2 GB- / 4 GB-Grenze für die MyISAM-Daten-Datei zu durchbrechen (nicht für die Index-Datei), auf Betriebssystemen, die keine großen Dateien unterstützen. Sie erzielen mehr Geschwindigkeit vom I/O-Flaschenhals, wenn Sie die RAID-Verzeichnisse auf unterschiedliche physikalische Platten legen. RAID_TYPE funktioniert auf jedem Betriebssystem, solange Sie MySQL mit --with-raid konfiguriert haben. Momentan ist der einzige zulässige RAID_TYPE STRIPED (1 und RAID0 sind Aliase dafür).

    Wenn Sie RAID_TYPE=STRIPED bei einer MyISAM-Tabelle angeben, erzeugt MyISAM RAID_CHUNKS-Unterverzeichnisse namens 00, 01, 02 im Datenbank-Verzeichnis. In jedem dieser Verzeichnisse erzeugt MyISAM eine tabelle.MYD. Wenn Sie Daten in die Daten-Datei schreiben, mappt der RAID-Handler die ersten RAID_CHUNKSIZE * 1024 Bytes auf die erste Datei, die nächsten RAID_CHUNKSIZE * 1024 Bytes auf die nächste Datei usw.

  • UNION wird benutzt, wenn Sie eine Sammlung identischer Tabelle als eine benutzen wollen. Das funktioniert nur bei MERGE-Tabellen. See Abschnitt 8.2, „MERGE-Tabellen“.

    Momentan benötigen Sie SELECT-, UPDATE- und-DELETE-Berechtigungen auf die Tabellen, die Sie auf eine MERGE-Tabelle mappen. Alle gemappten Tabellen müssen sich in derselben Datenbank wie die MERGE-Tabelle befinden.

  • Wenn Sie Daten in eine MERGE-Tabelle einfügen wollen, müssen Sie mit INSERT_METHOD angeben, in welche Tabelle die Zeile eingefügt werden soll. See Abschnitt 8.2, „MERGE-Tabellen“.

  • In der erzeugten Tabelle wird der PRIMARY-Schlüssel zuerst platziert, gefolgt von allen UNIQUE-Schlüsseln und danach von den normalen Schlüsseln. Das hilft dem MySQL-Optimierer zu priorisieren, welcher Schlüssel benutzt werden soll, und auch, Duplikate von UNIQUE-Schlüsseln zu entdecken.

  • Wenn Sie DATA directory="verzeichnis" oder INDEX directory="verzeichnis" benutzen, können Sie angeben, wohin die Tabellen-Handler ihre Tabellen- und Index-Dateien legen sollen. Das funktioniert nur bei MyISAM-Tabellen in MySQL 4.0, wenn Sie die --skip-symlink-Option nicht benutzen. See Abschnitt 6.6.1.2, „Benutzung symbolischer Links für Tabellen“.

7.5.3.1. Stille Spaltentyp-Änderungen

In einigen Fällen ändert MySQL lautlos eine Spaltenspezifikation von der, die in einem CREATE TABLE-Statement angegeben wurde. (Das kann auch bei ALTER TABLE passieren.):

  • VARCHAR-Spalten mit einer Länge kleiner 4 werden in CHAR geändert.

  • Wenn irgend eine Spalte in einer Tabelle eine variable Länge hat, hat im Ergebnis jede Zeile eine variable Länge. Wenn daher eine Tabelle irgend welche Spalten variabler Länge enthält (VARCHAR, TEXT oder BLOB), werden alle CHAR-Spalten, die länger als drei Zeichen sind, in VARCHAR-Spalten umgewandelt. Das beeinflusst die Benutzung dieser Spalten in keiner Weise, denn in MySQL ist VARCHAR nur eine andere Art, Zeichen zu speichern. MySQL führt diese Umwandlung durch, weil sie Platz spart und Tabellenoperationen schneller macht. See Kapitel 8, MySQL-Tabellentypen.

  • TIMESTAMP-Anzeigebreiten müssen geradzahlig und im Bereich von 2 bis 14 sein. Wenn Sie eine Anzeigebreite von 0 oder größer als 14 angeben, wird die Größe auf 14 gesetzt. Ungerade Werte im Bereich von 1 bis 13 werden auf den nächst höheren geraden Wert gesetzt.

  • Sie können keinen echten NULL-Wert in einer TIMESTAMP-Spalte speichern. Wenn Sie sie auf NULL setzen, wird sie auf das aktuelle Datum und die aktuelle Zeit gesetzt. Weil sich TIMESTAMP-Spalten so verhalten, treffen die Attribute NULL und NOT NULL nicht auf normale Weise zu und werden ignoriert, wenn Sie sie angeben. DESCRIBE tabelle zeigt dagegen immer an, dass einer TIMESTAMP-Spalte NULL-Werte zugewiesen werden können.

  • MySQL mappt bestimmte Spaltentypen, die von anderen SQL-Datenbank-Herstellern benutzt werden, auf MySQL-Typen. See Abschnitt 7.2.5, „Spaltentypen anderer Datenbanken benutzen“.

Wenn Sie sehen wollen, ob MySQL einen anderen Spaltentyp als den, den Sie angegeben haben, benutzt hat, geben Sie nach dem Erzeugen oder Ändern Ihrer Tabelle ein DESCRIBE tabelle-Statement ein.

Bestimmte andere Spaltentyp-Änderungen können auftreten, wenn Sie eine Tabelle mit myisampack komprimieren. See Abschnitt 8.1.2.3, „Kennzeichen komprimierter Tabellen“.

7.5.4. ALTER TABLE-Syntax

ALTER [IGNORE] TABLE tabelle aenderungs_angabe [, aenderungs_angabe ...]

aenderungs_angabe:
        ADD [COLUMN] create_definition [FIRST | AFTER spalten_name]
  oder    ADD [COLUMN] (create_definition, create_definition,...)
  oder    ADD INDEX [index_name] (index_spalten_name,...)
  oder    ADD PRIMARY KEY (index_spalten_name,...)
  oder    ADD UNIQUE [index_name] (index_spalten_name,...)
  oder    ADD FULLTEXT [index_name] (index_spalten_name,...)
  or	ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_spalten_name,...)
            [referenz_definition]
  oder    ALTER [COLUMN] spalten_name {SET DEFAULT literal | DROP DEFAULT}
  oder    CHANGE [COLUMN] alter_spalten_name create_definition
  oder    MODIFY [COLUMN] create_definition
  oder    DROP [COLUMN] spalten_name
  oder    DROP PRIMARY KEY
  oder    DROP INDEX index_name
  oder    DISABLE KEYS
  oder    ENABLE KEYS
  oder    RENAME [TO] neue_tabelle
  oder    ORDER BY spalte
  oder    tabellen_optionen

Mit ALTER TABLE können Sie die Struktur einer bestehenden Tabelle ändern. Sie können beispielsweise Spalten hinzufügen oder löschen, Indexe erzeugen oder löschen, den Typ bestehender Spalten ändern oder Spalten oder die Tabelle selbst umbenennen. Sie können auch den Kommentar für die Tabelle und den Typ der Tabelle ändern. See Abschnitt 7.5.3, „CREATE TABLE-Syntax“.

Wenn Sie ALTER TABLE benutzen, um eine Spaltenspezifikation zu ändern, und DESCRIBE tabelle anzeigt, dass die Spalte nicht geändert wurde, ist es möglich, dass MySQL Ihre Änderungen aus einem der Gründe ignoriert hat, die in Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“ beschrieben sind. Wenn Sie beispielsweise versuchen, eine VARCHAR-Spalte zu CHAR zu ändern, benutzt MySQL dennoch VARCHAR, wenn die Tabelle weitere Spalten variabler Länge enthält.

ALTER TABLE funktioniert mittels Anlegen einer temporären Kopie der Original-Tabelle. Die Änderungen werden an der Kopie durchgeführt, dann wird die Original-Tabelle gelöscht und die neue umbenannt. Das wird so durchgeführt, dass alle Aktualisierungen automatisch ohne irgend welche fehlgeschlagenen Aktualisierungen an die neue Tabelle weitergeleitet werden. Während ALTER TABLE ausgeführt wird, ist die alte Tabelle durch andere Clients lesbar. Aktualisierungen und Schreibvorgänge in die Tabelle werden angehalten, bis die neue Tabelle bereit ist.

Beachten Sie, dass MySQL immer eine temporäre Tabelle anlegt, wenn Sie für ALTER TABLE irgend eine Option ausser RENAME angeben, selbst wenn die Daten eigentlich nicht kopiert werden müssten (zum Beispiel, wenn Sie einen Spaltennamen ändern). Wir planen, dass zu beheben, aber da man ALTER TABLE normalerweise nicht ausführen muss, ist das auf unserer TODO-Liste nicht sehr hoch angesetzt.

  • Um ALTER TABLE ausführen zu können, benötigen Sie ALTER-, INSERT- und CREATE-Berechtigungen für die Tabelle.

  • IGNORE ist eine MySQL-Erweiterung zu ANSI-SQL92. Es steuert, wie ALTER TABLE funktioniert, wenn es in der neuen Tabelle Duplikate auf eindeutigen Schlüsseln gibt. Wenn IGNORE nicht angegeben wird, wird das Kopieren abgebrochen und zurückgesetzt. Wenn IGNORE angegeben wird, wird bei Zeilen mit Duplikaten auf einem eindeutigen Schlüssel nur die erste Zeile benutzt, die anderen werden gelöscht.

  • Sie können mehrfache ADD-, ALTER-, DROP- und CHANGE-Klauseln in einem einzigen ALTER TABLE-Statement angeben. Das ist eine MySQL-Erweiterung zu ANSI-SQL92, welches nur eine Klausel pro ALTER TABLE-Statement zuläßt.

  • CHANGE spalten_name, DROP spalten_name und DROP INDEX sind MySQL-Erweiterungen zu ANSI-SQL92.

  • MODIFY ist eine Oracle-Erweiterung zu ALTER TABLE.

  • Das optionale Wort COLUMN kann weggelassen werden.

  • Wenn Sie ALTER TABLE tabelle RENAME TO neuer_name ohne weitere Optionen benutzen, benennt MySQL einfach die Dateien um, die der Tabelle tabelle entsprechen. Es besteht keine Notwendigkeit, die temporäre Tabelle zu erzeugen. See Abschnitt 7.5.5, „RENAME TABLE-Syntax“.

  • Ab MySQL 4.0 kann das obige Feature explizit aktiviert werden. ALTER TABLE ... DISABLE KEYS veranlasst MySQL, mit dem Aktualisieren nicht eindeutiger Indexe für die MyISAM-Tabelle aufzuhören. Dann sollte ALTER TABLE ... ENABLE KEYS benutzt werden, um fehlende Indexe wieder zu erzeugen. Weil MySQL das mit Algorithmen durchführt, die viel schneller sind als das Einfügen von Schlüsseln nacheinander, kann das Abschalten von Schlüsseln bei Masseneinfügeoperationen erheblich Geschwindigkeitsvorteile bringen.

  • create_definition-Klauseln benutzen dieselbe Syntax für ADD und CHANGE wie bei CREATE TABLE. Beachten Sie, dass diese Syntax den Spaltenname beinhaltet, nicht nur den Spaltentyp.

    See Abschnitt 7.5.3, „CREATE TABLE-Syntax“.

  • Sie können eine Spalte mit einer CHANGE alter_spalten_name create_definition-Klausel umbenennen. Um das zu tun, geben Sie den alten und den neuen Spaltennamen und den Typ an, den die Spalte momentan hat. Um beispielsweise eine INTEGER-Spalte von a nach b umzubenennen, tun Sie folgendes:

    mysql> ALTER TABLE t1 CHANGE a b INTEGER;
    

    Wenn Sie einen Spaltentyp, nicht aber den Namen ändern wollen, benötigt CHANGE dennoch zwei Spaltennamen, selbst wenn sie dieselben sind. Beispiel:

    mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
    

    Ab MySQL-Version 3.22.16a können Sie jedoch auch MODIFY benutzen, um einen Spaltentyp ohne Umbenennung zu ändern:

    mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
    
  • Wenn Sie CHANGE oder MODIFY benutzen, um eine Spalte zu kürzen, für die es einen Index auf einem Teil der Spalte gibt (wenn Sie zum Beispiel einen Index auf den ersten 10 Zeichen einer VARCHAR-Spalte haben), können Sie die Spalte nicht kürzer als die Anzahl von Zeichen machen, die indiziert sind.

  • Wenn Sie versuchen, einen Spaltentyp mit CHANGE oder MODIFY zu ändern, versucht MySQL, Daten so umzuwandeln, dass sie so gut wie möglich zum neuen Typ passen.

  • AB MySQL-Version 3.22 können Sie FIRST oder ADD ... AFTER spalten_name benutzen, um eine Spalte an einer bestimmten Position innerhalb einer Tabellenzeile einzufügen. Vorgabemäßig wird die Spalte am Ende hinzugefügt.

  • ALTER COLUMN gibt einen Vorgabewert für eine Spalte an oder entfernt den alten Vorgabewert. Wenn der alte Vorgabewert entfernt wird und die Spalte NULL sein darf, ist der neue Vorgabewert NULL. Wenn die Spalte nicht NULL sein darf, weist MySQL einen Vorgabewert zu, wie in Abschnitt 7.5.3, „CREATE TABLE-Syntax“ beschrieben.

  • DROP INDEX entfernt einen Index. Das ist eine MySQL-Erweiterung zu ANSI-SQL92. See Abschnitt 7.5.8, „DROP INDEX-Syntax“.

  • Wenn Spalten aus einer Tabelle gelöscht werden, werden sie auch aus jeglichen Indexen entfernt, deren Teil sie sind. Wenn alle Spalten, aus denen ein Index besteht, gelöscht werden, wird der Index ebenfalls gelöscht.

  • Wenn eine Tabelle nur eine Spalte enthält, kann die Spalte nicht gelöscht werden. Wenn Sie beabsichtigen, die Tabelle zu entfernen, benutzen Sie statt dessen DROP TABLE.

  • DROP PRIMARY KEY löscht den Primärschlüssel. Wenn es keinen solchen gibt, löscht es den ersten UNIQUE-Index in der Tabelle. (MySQL kennzeichnet den ersten UNIQUE-Schlüssel als PRIMARY KEY, wenn PRIMARY KEY nicht explizit angegeben wurde.)

    Wenn Sie einen UNIQUE INDEX oder PRIMARY KEY zu einer Tabelle hinzufügen, wird dieser vor jedem Nicht-UNIQUE-Index gespeichert, so dass MySQL doppelte Schlüsseleinträge so früh wie möglich feststellen kann.

  • ORDER BY gestattet Ihnen, eine Tabelle mit Zeilen in einer bestimmten Reihenfolge zu erzeugen. Beachten Sie, dass die Tabelle nach INSERTs und DELETEs nicht in dieser Reihenfolge verbleibt. In einigen Fällen kann es das Sortieren für MySQL erleichtern, wenn die Tabelle nach der Spalte geordnet ist, nach der Sie sie später ordnen wollen. Diese Option ist hauptsächlich nützlich, wenn Sie wissen, dass Sie die Zeilen meistens in einer bestimmten Reihenfolge abfragen werden. Wenn Sie diese Option nach großen Änderungen in der Tabelle benutzen, können Sie möglicherweise eine höhere Performance erzielen.

  • Wenn Sie ALTER TABLE auf einer MyISAM-Tabelle benutzen, werden alle nicht eindeutigen Indexe in einem separaten Stapellauf erzeugt (wie bei REPAIR). Das sollte ALTER TABLE viel schneller machen, wenn Sie viele Indexe haben.

  • Ab MySQL 4.0 kann dies explizit aktiviert werden. ALTER TABLE ... DISABLE KEYS veranlasst MySQL, mit der Aktualisierung nicht eindeutiger Indexe für MyISAM-Tabellen aufzuhören. ALTER TABLE ... ENABLE KEYS sollte dann benutzt werden, um fehlende Indexe wieder zu erzeugen. Weil MySQL das mit Algorithmen durchführt, die viel schneller sind als das Einfügen von Schlüsseln nacheinander, kann das Abschalten von Schlüsseln bei Masseneinfügeoperationen erheblich Geschwindigkeitsvorteile bringen.

  • Mit der C-API-Funktion mysql_info() können Sie herausfinden, wie viele Datensätze kopiert wurden und (wenn IGNORE benutzt wird) wie viele Datensätze aufgrund der Duplizierung eindeutiger Schlüsselwerte gelöscht wurden.

  • Die FOREIGN KEY-, CHECK- und REFERENCES-Klauseln machen nichts. Die Syntax für sie steht nur aus Kompatibilitätsgründen bereit, um das Portieren von Code von anderen SQL-Servern zu erleichtern und um Applikationen laufen zu lassen, die Tabellen mit Referenzen erzeugen.

    See Abschnitt 2.7.4.5, „Fremdschlüssel“.

Hier ist ein Beispiel, das einige der Anwendungsfälle von ALTER TABLE zeigt. Wir fangen mit einer Tabelle t1 an, die wie folgt erzeugt wird:

mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));

Um die Tabelle von t1 nach t2 umzubenennen, geben Sie ein:

mysql> ALTER TABLE t1 RENAME t2;

Um Spalte a von INTEGER nach TINYINT NOT NULL zu ändern (der Name bleibt derselbe) und Spalte b von CHAR(10) nach CHAR(20) zu ändern und gleichzeitig von b nach c umzubenennen, geben Sie ein:

mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);

Jetzt wird eine TIMESTAMP-Spalte namens d hinzugefügt:

mysql> ALTER TABLE t2 ADD d TIMESTAMP;

Nunmehr erzeugen wir einen Index auf Spalte d und machen Spalte a zum Primärschlüssel:

mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);

Wir entfernen Spalte c:

mysql> ALTER TABLE t2 DROP COLUMN c;

Und fügen eine neue AUTO_INCREMENT-Ganzzahl-Spalte namens c hinzu:

mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
           ADD INDEX (c);

Beachten Sie, dass wir c indiziert haben, weil AUTO_INCREMENT-Spalten indiziert sein müssen, und auch, dass wir c als NOT NULL deklariert haben, weil indizierte Spalten nicht NULL sein dürfen.

Wenn Sie eine AUTO_INCREMENT-Spalte hinzufügen, werden automatisch Spaltenwerte mit Zahlenfolgen eingefügt. Sie können die erste Zahl setzen, indem Sie SET INSERT_ID=# vor ALTER TABLE ausführen oder indem Sie die AUTO_INCREMENT = #-Tabellenoption benutzen. See Abschnitt 6.5.6, „SET-Syntax“.

Wenn Sie bei MyISAM-Tabellen nicht die AUTO_INCREMENT-Spalte ändern, ist die Folgezahl davon nicht betroffen. Wenn Sie eine AUTO_INCREMENT-Spalte löschen und dann eine weitere AUTO_INCREMENT-Spalte hinzufügen, fangen die Zahlen wieder bei 1 an.

See Abschnitt A.6.1, „Probleme mit ALTER TABLE.“.

7.5.5. RENAME TABLE-Syntax

RENAME TABLE tabelle TO neue_tabelle[, tabelle2 TO neue_tabelle2,...]

Das Umbenennen wird atomisch durchgeführt, was heißt, dass kein anderer Thread auf die Tabelle(n) zugreifen kann, während umbenannt wird. Das ermöglicht, eine Tabelle durch eine leere zu ersetzen:

CREATE TABLE neue_tabelle (...);
RENAME TABLE alte_tabelle TO datensicherung_tabelle, neue_tabelle TO alte_tabelle;

Das Umbenennen wird von links nach rechts durchgeführt, was bedeutet, dass Sie beim Vertauschen zweier Tabellennamen folgendes tun können:

RENAME TABLE alte_tabelle    TO datensicherung_tabelle,
             neue_tabelle    TO alte_tabelle,
             datensicherung_tabelle TO neue_tabelle;

Solange zwei Datenbanken auf derselben Platte liegen, können Sie auch von einer Datenbank in eine andere umbenennen:

RENAME TABLE aktuelle_datenbank.tabelle TO andere_datenbank.tabelle;

Wenn Sie RENAME ausführen, dürfen Sie keine gesperrten Tabellen oder aktive Transaktionen haben. Ausserdem benötigen Sie die ALTER- und DROP-Berechtigungen für die Original-Tabelle und die CREATE- und INSERT-Berechtigungen auf die neue Tabelle.

Wenn beim Umbenennen mehrfacher Tabellen Fehler auftreten, führt MySQL ein entgegengesetztes Umbenennen aller umbenannten Tabellen durch, um alles wieder in den Ausgangszustand zu versetzen.

7.5.6. DROP TABLE-Syntax

DROP TABLE [IF EXISTS] tabelle [, tabelle,...] [RESTRICT | CASCADE]

DROP TABLE entfernt eine oder mehrere Tabellen. Alle Tabellendaten und die Tabellendefinition werden zerstört, seien Sie daher vorsichtig mit diesem Befehl!

Ab MySQL-Version 3.22 können Sie die Schlüsselwörter IF EXISTS benutzen, um Fehler zu vermeiden, die auftreten, wenn Tabellen nicht existieren.

RESTRICT und CASCADE sind wegen leichterer Portierung zugelassen. Momentan tun sie nichts.

HINWEIS: DROP TABLE ist nicht transaktionssicher und führt automatisch jegliche aktiven Transaktionen zuende.

7.5.7. CREATE INDEX-Syntax

CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tabelle (spalten_name[(laenge)],... )

Das CREATE INDEX-Statement macht vor MySQL-Version 3.22 nichts. Ab Version 3.22 ist CREATE INDEX auf ein ALTER TABLE-Statement gemappt, um Indexe zu erzeugen. See Abschnitt 7.5.4, „ALTER TABLE-Syntax“.

Normalerweise erzeugen Sie alle Indexe auf eine Tabelle zur Zeit, wo die Tabelle selbst mit CREATE TABLE erzeugt wird.

See Abschnitt 7.5.3, „CREATE TABLE-Syntax“. CREATE INDEX gestattet, bestehenden Tabellen Indexe hinzuzufügen.

A Spaltenliste der Form (spalte1,spalte2,...) erzeugt einen mehrspaltigen Index. Die Indexwerte werden durch Verkettung der Werte der angegebenen Spalten erzeugt.

Bei CHAR- und VARCHAR-Spalten können Indexe, die nur einen Teil einer Spalte benutzen, mit der spalten_name(laenge)-Syntax erzeugt werden. (Bei BLOB- und TEXT-Spalten ist die Längenangabe erforderlich.) Unten stehendes Statement zeigt, wie ein Index erzeugt wird, der die ersten 10 Zeichen der name-Spalte benutzt:

mysql> CREATE INDEX teil_von_name ON kunde (name(10));

Weil sich die meisten Namen üblicherweise in den ersten 10 Zeichen unterscheiden, sollte dieser Index nicht viel langsamer sein, als wenn der Index aus der gesamten name-Spalte erzeugt worden wäre. Die Benutzung von Teilspalten für Indexe kann die Index-Datei auch viel kleiner machen, was viel Speicherplatz sparen und zusätzlich INSERT-Operationen beschleunigen kann!

Beachten Sie, dass Sie einen Index auf eine Spalte, die NULL-Werte haben darf, oder auf eine BLOB/TEXT-Spalte erst ab MySQL-Version 3.23.2 und nur beim MyISAM-Tabellentyp erzeugen können.

Weitere Informationen darüber, wie MySQL Indexe benutzt, finden Sie unter Abschnitt 6.4.3, „Wie MySQL Indexe benutzt“.

FULLTEXT-Indexe können nur VARCHAR- und TEXT-Spalten indexieren und funktionieren nur bei MyISAM-Tabellen. FULLTEXT-Indexe sind ab MySQL-Version 3.23.23 verfügbar. Abschnitt 7.8, „MySQL-Volltextsuche“.

7.5.8. DROP INDEX-Syntax

DROP INDEX index_name ON tabelle

DROP INDEX löscht den Index namens index_name aus der Tabelle tabelle. DROP INDEX macht vor MySQL-Version 3.22 nichts. Ab Version 3.22 ist DROP INDEX auf ein ALTER TABLE-Statement gemappt, um den Index zu löschen. See Abschnitt 7.5.4, „ALTER TABLE-Syntax“.

7.6. Grundlegende Befehle des MySQL-Dienstprogramms für Benutzer

7.6.1. USE-Syntax

USE datenbank

Das USE datenbank-Statement weist MySQL an, datenbank als vorgabemäßige Datenbank für nachfolgende Anfragen zu benutzen. Die Datenbank bleibt die aktuelle, entweder bis zum Ende der Sitzung, oder bis ein weiteres USE-Statement abgesetzt wird:

mysql> USE datenbank1;
mysql> SELECT count(*) FROM tabelle;      # wählt aus von datenbank1.tabelle
mysql> USE datenbank2;
mysql> SELECT count(*) FROM tabelle;      # wählt aus von datenbank2.tabelle

Wenn Sie eine bestimmte Datenbank mit dem USE-Statement zu aktuellen machen, heißt das nicht, dass Sie nicht auf Tabellen in anderen Datenbanken zugreifen können. Das unten stehende Beispiel zeigt den Zugriff auf die autor-Tabelle in der datenbank1-Datenbank und auf die herausgeber-Tabelle in der datenbank2-Datenbank:

mysql> USE datenbank1;
mysql> SELECT autor_name,herausgeber_name FROM autor,datenbank2.herausgeber
           WHERE autor.herausgeber_id = datenbank2.herausgeber.herausgeber_id;

The USE-Statement wird für die Sybase-Kompatibilität zur Verfügung gestellt.

7.6.2. DESCRIBE-Syntax (Informationen über Spalten erhalten)

{DESCRIBE | DESC} tabelle {spalten_name | platzhalter}

DESCRIBE ist ein Kürzel für SHOW COLUMNS FROM. See Abschnitt 5.5.5.1, „Informationen über Datenbank, Tabellen, Spalten und Indexe abrufen“.

DESCRIBE stellt Informationen über die Spalten einer Tabelle bereit. spalten_name kann ein Spaltenname oder eine Zeichenkette sein, die die SQL-‘%’- und -‘_’-Platzhalterzeichen enthält.

Wenn die Spaltentypen sich von dem unterscheiden, was Sie auf der Grundlage eines CREATE TABLE-Statements erwartet hätten, beachten Sie, dass MySQL manchmal Spaltentypen ändert. See Abschnitt 7.5.3.1, „Stille Spaltentyp-Änderungen“.

Dieses Statement wird für die Oracle-Kompatibilität zur Verfügung gestellt.

Das SHOW-Statement stellt ähnliche Informationen bereit. See Abschnitt 5.5.5, „SHOW-Syntax“.

7.7. Transaktionale und Sperrbefehle von MySQL

7.7.1. BEGIN/COMMIT/ROLLBACK-Syntax

Vorgabemäßig läuft MySQL im autocommit-Modus. Das heißt, dass MySQL eine Aktualisierung auf Platte speichert, sobald Sie eine Aktualisierung ausführen.

Wenn Sie transaktionssichere Tabellen (wie InnoDB oder BDB ) benutzen, können Sie MySQL mit folgendem Befehl in den Nicht-autocommit-Modus setzen:

SET AUTOCOMMIT=0

Danach müssen Sie COMMIT benutzen, um Ihre Änderungen auf Platte zu sichern, oder ROLLBACK, wenn Sie die Änderungen verwerfen wollen, die Sie seit dem Beginn der Transaktion gemacht haben.

Wenn Sie für eine Reihe von Statements zum AUTOCOMMIT-Modus umschalten wollen, können Sie das BEGIN- oder BEGIN WORK-Statement benutzen:

BEGIN;
SELECT @A:=SUM(gehalt) FROM tabelle1 WHERE type=1;
UPDATE tabelle2 SET zusammenfassung=@A WHERE type=1;
COMMIT;

Beachten Sie, dass bei der Benutzung nicht transaktionssicher Tabellen die Änderungen dennoch sofort gespeichert werden, unabhängig vom Status des autocommit-Modus.

Wenn Sie ROLLBACK bei der Aktualisierung einer nicht transaktionalen Tabelle ausführen, erhalten Sie einen Fehler (ER_WARNING_NOT_COMPLETE_ROLLBACK) als Warnung. Alle transaktionssicheren Tabellen werden zurückgesetzt, aber nicht transaktionale Tabelle ändern sich nicht.

Wenn Sie BEGIN oder SET AUTOCOMMIT=0 benutzen, sollten Sie die MySQL-Binär-Log-Datei für Datensicherungen benutzen statt der älteren Update-Log-Datei. Transaktionen werden in der Binär-Log-Datei in einem Stück gespeichert, beim COMMIT, um sicherzustellen, dass Transaktionen, die zurückgesetzt werden (Rollback), nicht gespeichert werden. See Abschnitt 5.9.4, „Die binäre Update-Log-Datei“.

Folgende Befehle beenden automatisch eine Transaktion (als ob Sie ein COMMIT vor der Ausführung des Befehls ausgeführt hätten:

ALTER TABLEBEGINCREATE INDEX
DROP DATABASEDROP TABLERENAME TABLE
TRUNCATE  

Sie können die Isolationsebene (Isolation Level) für Transaktionen mit SET TRANSACTION ISOLATION LEVEL ... Abschnitt 7.7.3, „SET TRANSACTION-Syntax“ ändern.

7.7.2. LOCK TABLES/UNLOCK TABLES-Syntax

LOCK TABLES tabelle [AS alias] {READ | [READ LOCAL] | [LOW_PRIORITY] WRITE}
            [, tabelle {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES sperrt Tabellen für den aktuellen Thread. UNLOCK TABLES hebt alle Sperren auf, die vom aktuellen Thread veranlasst wurden. Alle Tabellen, die durch den aktuellen Thread gesperrt sind, werden automatisch entsperrt, wenn der Thread ein weiteres LOCK TABLES absetzt oder wenn die Verbindung zum Server geschlossen wird.

Die wichtigsten Gründe für die Benutzung von LOCK TABLES sind die Emulation von Transaktionen oder um mehr Geschwindigkeit bei der Aktualisierung von Tabellen zu erhalten. Das wird später detaillierter erläutert.

Wenn ein Thread eine READ-Sperre auf eine Tabelle erlangt, kann dieser Thread (und alle anderen Threads) nur aus der Tabelle lesen. Wenn ein Thread eine WRITE-Sperre auf eine Tabelle erlangt, kann nur der Thread, der die Sperre veranlasst hat, READ oder WRITE auf der Tabelle durchführen. Andere Threads werden blockiert.

Der Unterschied zwischen READ LOCAL und READ ist, dass READ LOCAL nicht kollidierende INSERT-Statements während der Dauer der Sperre zuläßt. Das kann jedoch nicht benutzt werden, wenn Sie Datenbankdateien ausserhalb von MySQL bearbeiten, während die Sperre aktiv ist.

Wenn Sie LOCK TABLES benutzen, müssen Sie alle Tabellen sperren, die Sie benutzen werden, und Sie müssen denselben Alias benutzen, den Sie in Ihren Anfragen benutzen werden! Wenn Sie eine Tabelle in einer Anfrage mehrfach (mit Aliasen) benutzen, müssen Sie für jeden Alias eine Sperre machen!

WRITE-Sperren haben normalerweise höhere Priorität als READ-Sperren, um sicherzustellen, dass Aktualisierungen so früh wie möglich bearbeitet werden. Dass heißt, wenn ein Thread eine READ-Sperre erlangt und dann ein anderer Thread eine WRITE-Sperre verlangt, dass nachfolgende READ-Sperrenanfragen warten, bis der WRITE-Thread die Sperre erhalten und freigegeben hat. Sie können LOW_PRIORITY WRITE-Sperren benutzen, um anderen Threads zu gestatten, READ-Sperren zu erlangen, während der Thread auf die WRITE-Sperre wartet. Sie sollten nur dann LOW_PRIORITY WRITE-Sperren benutzen, wenn Sie sicher sind, dass es irgendwann eine Zeit gibt, in der kein anderer Thread eine READ-Sperre haben wird.

LOCK TABLES funktioniert wie folgt:

  1. Sortiert alle Tabellen, die gesperrt werden sollen, in einer intern definierten Reihenfolge (aus Benutzersicht ist die Reihenfolge undefiniert).

  2. Wenn eine Tabelle mit einer Lese- und einer Schreibsperre gesperrt ist, wird die Schreibsperre vor die Lesesperre platziert.

  3. Sperrt eine Tabelle nach der anderen, bis der Thread alle Sperren erhalten hat.

Diese Methode stellt sicher, dass Tabellensperren blockierungsfrei ist. Bei diesem Schema gibt es jedoch ein paar weitere Dinge, derer man sich bewusst sein muss:

Wenn Sie eine LOW_PRIORITY_WRITE-Sperre für eine Tabelle benutzen, heißt das, dass MySQL auf diese bestimmte Sperre wartet, bis es keinen Thread gibt, der eine READ-Sperre will. Wenn der Thread die WRITE-Sperre erhalten hat und darauf wartet, die Sperre für die nächste Tabelle in der Tabellensperrliste zu erhalten, warten alle anderen Threads darauf, dass die WRITE-Sperre aufgehoben wird. Wenn das bei Ihrer Applikation zu ernsthaften Problemen führt, sollten Sie in Betracht ziehen, einige Ihrer Tabelle in transaktionssichere Tabelle umzuwandeln.

Es ist sicher, einen Thread mit KILL zu killen, der auf eine Tabellensperre wartet. See Abschnitt 5.5.4, „KILL-Syntax“.

Beachten Sie, dass Sie NICHT irgend welche Tabellen sperren sollten, die Sie mit INSERT DELAYED benutzen. Das liegt darin, dass in diesem Fall das INSERT von einem separaten Thread durchgeführt wird.

Normalerweise müssen Sie Tabellen nicht sperren, weil alle einzelnen UPDATE-Statements atomisch sind. Kein anderer Thread kann mit einem aktuell ausgeführten SQL-Statement in die Quere kommen. Es gibt dennoch einige Fällen, in denen es wünschenswert sein kann, Tabellen zu sperren:

  • Wenn Sie viele Operationen auf einer großen Zahl von Tabellen laufen lassen wollen, ist es viel schneller, die Tabellen zu sperren, die Sie benutzen werden. Der Nachteil besteht natürlich darin, dass kein anderer Thread eine READ-gesperrte Tabelle aktualisieren und kein anderer Thread eine WRITE-gesperrte Tabelle lesen kann.

    Der Grund, dass einiges mit LOCK TABLES schneller geht, liegt darin, dass MySQL den Schlüssel-Cache für die gesperrten Tabellen nicht auf Platte zurückschreibt (flush), bis UNLOCK TABLES aufgerufen wird (normalerweise wird der Schlüssel-Cache nach jedem SQL-Statement auf Platte zurückgeschrieben). Das erhöht die Geschwindigkeit bei den Operationen INSERT / UPDATE / DELETE bei MyISAM-Tabellen.

  • Wenn Sie einen Tabellen-Handler in MySQL benutzen, der keine Transaktionen unterstützt, müssen Sie LOCK TABLES benutzen, wenn Sie sicherstellen wollen, dass kann anderer Thread zwischen einem SELECT und einem UPDATE dazwischen kommen kann. Das unten stehende Beispiel erfordert LOCK TABLES, um sicher ausgeführt zu werden:

    mysql> LOCK TABLES trans READ, kunde WRITE;
    mysql> select sum(wert) from trans where kunde_id=irgendeine_id;
    mysql> update kunde set gesamt_wert=summe_aus_vorherigem_statement
               where kunde_id=irgendeine_id;
    mysql> UNLOCK TABLES;
    

    Ohne LOCK TABLES besteht die Möglichkeit, dass ein anderer Thread eine neue Zeile in die trans-Tabelle einfügt, zwischen der Ausführung des SELECT- und des UPDATE-Statements.

Wenn Sie inkrementelle Updates (UPDATE kunde SET wert=wert+neuer_wert) oder die LAST_INSERT_ID()-Funktion benutzen, können Sie LOCK TABLES in vielen Fällen vermeiden.

Einige Problemfälle können Sie auch lösen, indem Sie die Sperrfunktionen auf Benutzerebene GET_LOCK() und RELEASE_LOCK() benutzen. Diese Sperren werden in einer Hash-Tabelle im Server gespeichert und sind mit pThread_mutex_lock() und pThread_mutex_unlock() für die Erzielung höherer Geschwindigkeit implementiert. See Abschnitt 7.3.5.2, „Verschiedene Funktionen“.

Siehe Abschnitt 6.3.1, „Wie MySQL Tabellen sperrt“ wegen weiterer Informationen über Sperrmethoden.

Sie können alle Tabellen in allen Datenbanken mit Lesesperren sperren, und zwar mit dem FLUSH TABLES WITH READ LOCK-Befehl. See Abschnitt 5.5.3, „FLUSH-Syntax“. Das ist eine sehr bequeme Möglichkeit, Datensicherungen zu erhalten, wenn Sie ein Dateisystem wie Veritas haben, dass Schnappschüsse im Zeitverlauf aufnehmen kann.

HINWEIS: LOCK TABLES ist nicht transaktionssicher und schickt automatisch jegliche aktiven Transaktionen ab (Commit), bevor es versucht, die Tabellen zu sperren.

7.7.3. SET TRANSACTION-Syntax

SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]

Setzt die Transaktionsisolationsebene für die globale, gesamte Sitzung oder für die nächste Transaktion.

Das vorgabemäßige Verhalten ist das Setzen der Isolationsebene für die nächste (nicht angefangene) Transaktion.

Wenn Sie die GLOBAL-Berechtigung setzen, betrifft das alle neu erzeugten Threads. Sie benötigen dafür die PROCESS-Berechtigung.

Wenn Sie die SESSION-Berechtigung setzen, betrifft das die folgenden und alle zukünftigen Transaktionen.

Sie können die vorgabemäßige Isolationsebene für mysqld mit --transaction-isolation=... setzen. See Abschnitt 5.1.1, „mysqld-Kommandozeilenoptionen“.

7.8. MySQL-Volltextsuche

Ab Version 3.23.23 bietet MySQL Unterstützung für Volltext-Indexierung und -Suche. Volltext-Indexe sind in MySQL Indexe vom Typ FULLTEXT. FULLTEXT-Indexe können von VARCHAR- und TEXT-Spalten zur Zeit von CREATE TABLE erzeugt werden oder später mit ALTER TABLE oder CREATE INDEX hinzugefügt werden. Bei großen Datenmengen ist es viel schneller, einen FULLTEXT-Index mit ALTER TABLE (oder CREATE INDEX) hinzuzufügen, als Zeilen in eine leere Tabelle mit einem FULLTEXT-Index einzufügen.

Die Volltextsuche wird mit der MATCH-Funktion durchgeführt.

mysql> CREATE TABLE artikel (
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    ->   titel VARCHAR(200),
    ->   artikeltext TEXT,
    ->   FULLTEXT (titel,artikeltext)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO artikel VALUES
    -> (0,'MySQL-Tutorial', 'DBMS steht für DataBase-Management ...'),
    -> (0,'Wie man MySQL effizient einsetzt', 'Nachdem Sie ...'),
    -> (0,'MySQL optimieren','In diesem Tutorial wird gezeigt, wie ...'),
    -> (0,'1001 MySQL-Tricks','1. Lassen Sie mysqld nie als root laufen. 2. Normalisieren ...'),
    -> (0,'MySQL vs. YourSQL', 'Im folgenden Vergleich von Datenbank ...'),
    -> (0,'MySQL-Sicherheitsaspekte', 'Wenn er korrekt konfiguriert ist, ist MySQL ...');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM artikel WHERE MATCH (titel,artikeltext) AGAINST ('Datenbank');
+----+-------------------+---------------------------------------------+
| id | titel             | artikeltext                                 |
+----+-------------------+---------------------------------------------+
|  5 | MySQL vs. YourSQL | Im folgenden Vergleich von Datenbank ...    |
|  1 | MySQL-Tutorial    | DBMS steht für DataBase-Management ...      |
+----+-------------------+---------------------------------------------+
2 rows in set (0.00 sec)

Die Funktion MATCH prüft eine natürlichsprachige Anfrage gegen (AGAINST) eine Textsammlung (einfach ein Satz von Spalten, der vom FULLTEXT-Index abgedeckt wird). Für jede Zeile in einer Tabelle gibt sie eine Relevanz zurück - ein Ähnlichkeitsmaß zwischen dem Text in dieser Zeile (in den Spalten, die Teil der Textsammlung sind) und der Anfrage. Wenn sie in einer WHERE-Klausel benutzt wird (siehe Beispiel oben), werden die zurückgegebenen Zeilen automatisch nach absteigender Relevanz sortiert. Die Relevanz ist eine nicht negative Fließkommazahl. 0 Relevanz bedeutet keine Ähnlichkeit. Die Relevanz wird auf der Grundlage der Anzahl von Wörtern in der Zeile, der Anzahl eindeutiger Wörter in dieser Zeile, der Gesamtzahl von Wörtern in der Textsammlung und der Anzahl von Dokumenten (Zeilen) berechnet, die ein bestimmtes Wort enthalten.

Das obige Beispiel ist ein grundlegendes Beispiel der Benutzung der MATCH-Funktion. Die Zeilen werden nach absteigender Relevanz zurückgegeben.

mysql> SELECT id,MATCH (titel,artikeltext) AGAINST ('Tutorial') FROM artikel;
+----+------------------------------------------------+
| id | MATCH (titel,artikeltext) AGAINST ('Tutorial') |
+----+------------------------------------------------+
|  1 |                               0.64840710366884 |
|  2 |                                              0 |
|  3 |                               0.66266459031789 |
|  4 |                                              0 |
|  5 |                                              0 |
|  6 |                                              0 |
+----+------------------------------------------------+
5 rows in set (0.00 sec)

Dieses Beispiel zeigt, wie man Relevanzen abruft. Weil weder die WHERE- noch die ORDER BY-Klausel vorhanden sind, werden die Zeilen unsortiert zurückgegeben.

mysql> SELECT id, artikeltext, MATCH (titel,artikeltext) AGAINST (
    -> 'Sicherheits-Implikationen, wenn Sie MySQL als root laufen lassen') AS rang
    -> FROM artikel WHERE MATCH (titel,artikeltext) AGAINST
    -> ('Sicherheits-Implikationen, wenn Sie MySQL als root laufen lassen');
+----+----------------------------------------------------------------+-----------------+
| id | artikeltext                                                    | rang            |
+----+----------------------------------------------------------------+-----------------+
|  4 | 1. Lassen Sie mysqld nie als root laufen. 2. Normalisieren ... | 1.5055546709332 |
|  6 | Wenn er korrekt konfiguriert ist, ist MySQL ...                |   1.31140957288 |
+----+----------------------------------------------------------------+-----------------+
2 rows in set (0.00 sec)

Das ist ein komplexeres Beispiel - die Anfrage gibt die Relevanz zurück und sortiert die Zeilen auch noch nach absteigender Relevanz. Um das zu erzielen, müssen Sie MATCH zweimal angeben. Beachten Sie, dass das keinen zusätzlichen Overhead verursacht, weil der MySQL-Optimierer bemerkt, dass diese zwei MATCH-Aufrufe identisch sind und daher den Code für die Volltextsuche nur einmal aufruft.

MySQL benutzt einen sehr einfachen Parser, um Text in Wörter zu zerlegen. Ein ``Wort'' ist jede Folge von Buchstaben, Zahlen, ‘'’ und ‘_’. Jedes ``Wort'', das in der Liste der Stopwords vorkommt oder einfach nur zu kurz ist (3 Zeichen oder weniger), wird ignoriert.

Jedes korrekte Wort in der Textsammlung und in der Anfrage wird nach seiner Signifikanz in der Anfrage oder der Textsammlung gewichtet. Daher hat ein Wort, dass in vielen Dokumenten vorkommt, ein geringeres Gewicht (und kann sogar 0 Gewicht haben), weil es in dieser bestimmten Textsammlung einen geringen semantischen Wert hat. Ansonsten, wenn das Wort selten vorkommt, erhält es ein höheres Gewicht. Die Gewichte der Wörter werden anschließend kombiniert, um die Relevanz der Zeile zu berechnen.

Solch eine Technik funktioniert am besten bei großen Textsammlungen (in der Tat wurde sie sorgfältig darauf optimiert). Bei sehr kleinen Tabellen spiegelt die Wortverteilung nicht adäquat seinen semantischen Wert wider, so dass dieses Modell manchmal bizarre Ergebnisse ergeben kann:

mysql> SELECT * FROM artikel WHERE MATCH (titel,artikeltext) AGAINST ('MySQL');
Empty set (0.00 sec)

Die Suche nach dem Wort MySQL erzeugt im obigen Beispiel keine Ergebnisse. Das Wort MySQL ist in mehr als der Hälfte der Zeilen vorhanden und wird deshalb als Stopword betrachtet (eins mit dem semantischen Wert 0). Das ist in der Tat das gewünschte Verhalten - eine natürlichsprachige Anfrage sollte bei einer 1 GB großen Tabelle nicht jede zweite Zeile zurückgeben.

Bei einem Wort, dass in der Hälfte der Zeilen in einer Tabelle übereinstimmt, ist es nicht sehr wahrscheinlich, dass relevante Dokumente gefunden werden, sondern statt dessen viele irrelevante Dokumente. Das kennen wir alle aus Recherchen über Suchmaschinen auf dem Internet. Das ist die Überlegung, die dahinter steht, dass solchen Wörtern ein niedriger semantischer Wert in diesem bestimmten Satz von Daten gegeben wird.

7.8.1. Volltext-Einschränkungen

  • Alle Parameter der MATCH-Funktion müssen Spalten derselben Tabelle sein, die Teil desselben Volltext-Indexes ist.

  • Das Argument für AGAINST muss eine Konstanten-Zeichenkette sein.

7.8.2. MySQL-Volltextsuche fein einstellen

Leider hat die Volltextsuche noch keine durch den Benutzer einstellbare Parameter, doch diese stehen sehr weit oben auf der TODO-Liste. Wenn Sie jedoch eine MySQL-Quelldistribution (see Abschnitt 3.3, „Installation der Quelldistribution“) haben, können Sie das Verhalten der Volltextsuche in einiger Hinsicht ändern.

Beachten Sie, dass die Volltextsuche sorgfältig auf beste Sucheffektivität eingestellt wurde. Wenn Sie dieses vorgabemäßige Verhalten ändern, wird das die Suchergebnisse in den meisten Fällen verschlechtern. Ändern Sie die MySQL-Quelltexte deshalb nur, wenn Sie genau wissen, was Sie tun!

  • Die minimale zu indexierende Wortlänge wird in der myisam/ftdefs.h-Datei in folgender Zeile festgelegt:

    #define MIN_WORD_LEN 4
    

    Ändern Sie diesen Wert nach Belieben, kompilieren Sie MySQL neu und bauen Sie Ihre FULLTEXT-Indexe neu auf.

  • Die Stopword-Liste wird in myisam/ft_static.c definiert. Ändern Sie sie nach Ihrem Geschmack, kompilieren Sie MySQL neu und bauen Sie Ihre FULLTEXT-Indexe neu auf.

  • Die 50%-Schwelle wird durch das spezielle, ausgewählte Gewichtungsschema festgelegt. Um dieses abzuschalten, ändern Sie folgende Zeile in myisam/ftdefs.h:

    #define GWS_IN_USE GWS_PROB
    

    zu

    #define GWS_IN_USE GWS_FREQ
    

    und kompilieren Sie MySQL neu. In diesem Fall brauchen Sie die Indexe nicht neu aufzubauen.

7.8.3. Neue Features der Volltextsuche in MySQL 4.0

Dieser Abschnitt enthält eine Auflistung der Volltext-Features, die bereits im MySQL-4.0-Baum implementiert sind. Er erläutert den More Funktionen für Volltextsuche-Eintrag in Abschnitt 2.8, „MySQL und die Zukunft (das TODO)“.

  • REPAIR TABLE mit FULLTEXT-Indexen, ALTER TABLE mit FULLTEXT-Indexen und OPTIMIZE TABLE mit FULLTEXT-Indexen läuft jetzt bis zu 100 mal schneller.

  • MATCH ... AGAINST wird folgende Boolesch Operatoren unterstützen:

    • +wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile enthalten sein muss.

    • -wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile nicht enthalten sein darf.

    • < und > können benutzt werden, um die Wortgewichtung in der Anfrage herab- und heraufzusetzen.

    • ~ kann benutzt werden, um einem 'Rausch-Wort' ein negatives Gewicht zuzuweisen.

    • * ist ein Trunkierungsoperator.

    Die Boole'sche Suche benutzt eine vereinfachte Art, die Relevanz zu berechnen, die keine 50%-Schwelle hat.

  • Suchen sind jetzt wegen optimierter Suchalgorithmen bis zu 2 mal schneller.

  • Das Dienstprogramm ft_dump wurde für Low-Level-FULLTEXT-Index-Operationen hinzugefügt (Anfragen / Dumps / Statistiken).

7.8.4. Volltextsuche TODO-Liste

  • Alle Operationen mit FULLTEXT-Index schneller machen.

  • Unterstützung für Klammern () in Boole'scher Volltextsuche.

  • Phrasensuche, Näherungsoperatoren

  • Boole'sche Suche funktioniert ohne FULLTEXT-Index (ja, sehr langsam).

  • Unterstützung für "immer indizierte Wörter". Das könnten beliebige Zeichenketten sein, die der Benutzer wie Wörter behandeln will. Beispiele sind "C++", "AS/400", "TCP/IP" usw.

  • Unterstützung für Volltextsuche in MERGE-Tabellen.

  • Unterstützung für Multi-Byte-Zeichensätze.

  • Die Stopword-Liste von der Sprache der Daten abhängig machen.

  • Eindämmen (Stemming, natürlich abhängig von der Sprache der Daten).

  • Generischer Benutzer-unterstützbarer UDF- (?) Preparser.

  • Das Modell flexibler machen (durch Hinzufügen einiger regulierbarer Parameter für FULLTEXT in CREATE/ALTER TABLE).

7.9. MySQL-Anfragen-Cache

Ab Version 4.0.1 besitzt der MySQL-Server einen Anfragen-Cache. Wenn er benutzt wird, speichert er den Text einer SELECT-Anfrage zusammen mit dem entsprechenden Ergebnis, das an den Client gesendet wird. Wenn eine weitere identische Anfrage empfangen wird, kann der Server die Ergebnisse aus dem Cache beziehen, statt dieselbe Anfrage zu parsen und noch einmal auszuführen.

Der Anfragen-Cache ist extrem nützlich in Umgebungen, in denen sich (einige) Tabellen nicht häufig ändern und in denen Sie viele identische Anfragen haben. Das ist eine typische Situation für viele Web-Server, die viele dynamische Inhalte benutzen.

Im folgenden finden Sie einige Performance-Daten für den Anfragen-Cache (die wir mit der MySQL-Benchmark-Suite auf einer Linux Alpha 2 x 500 MHz mit 2 GB RAM und einem 64-MB-Anfragen-Cache gewonnen haben):

  • Wenn Sie den Anfragen-Cache-Code abschalten wollen, setzen Sie query_cache_size=0. Wenn Sie den Anfragen-Cache-Code abschalten, gibt es keinen bemerkbaren Overhead.

  • Wenn alle Anfragen, die Sie ausführen, einfach sind (wie das Auswählen einer Zeile aus einer Tabelle mit einer Zeile), sich aber dennoch unterscheiden, so dass die Anfragen nicht gecachet werden können, ist der Overhead bei einem aktiven Anfragen-Cache 13%. Das sollte als Szenario für den schlechtesten Fall angesehen werden. Im echten Leben sind Anfragen jedoch meist viel komplizierter, so dass der Overhead normalerweise beträchtlich geringer ist.

  • Die Suche nach einer Zeile in einer Einzeilen-Tabelle ist 238% schneller. Das kann als minimale Geschwindigkeitssteigerung für eine gecachete Anfrage betrachtet werden.

7.9.1. Wie der Anfragen-Cache funktioniert

Anfragen werden vor dem Parsen verglichen, daher werden

SELECT * FROM TABELLE

und

Select * from tabelle

als unterschiedliche Anfragen für den Anfragen-Cache betrachtet. Anfragen müssen also exakt gleich sein (Byte für Byte), um als identisch erkannt zu werden. Zusätzlich kann eine Anfrage als unterschiedlich betrachtet werden, wenn ein Client zum Beispiel ein neues Kommunikationsprotokollformat benutzt oder einen anderen Zeichensatz als ein anderer Client.

Anfragen, die unterschiedliche Datenbanken, Protokollversionen oder unterschiedliche vorgabemäßige Zeichensätze benutzen, werden als unterschiedliche Anfragen angesehen und separat gecachet.

Der Cache funktioniert auch bei Anfragen der Art SELECT CALC_ROWS ... und SELECT FOUND_ROWS() ..., weil die Anzahl der gefundenen Zeilen ebenfalls im Cache gespeichert wird.

Wenn sich eine Tabelle ändert (INSERT, UPDATE, DELETE, TRUNCATE, ALTER oder DROP TABLE|DATABASE), werden alle gecacheten Anfragen, die diese Tabelle benutzten (möglicherweise über eine MRG_MyISAM-Tabelle!) ungültig und werden aus dem Cache entfernt.

Momentan werden alle InnoDB-Tabellen beim COMMIT als für den Cache ungültig gekennzeichnet. In Zukunft wird das geändert, so dass nur Tabellen, die in der Transaktion geändert wurden, für die entsprechenden Cache-Einträge als ungültig markiert werden.

Eine Anfrage kann nicht gecachet werden, wenn sie eine der folgenden Funktionen enthält:

FunktionFunktionFunktionFunktion
Benutzerdefinierte FunktionenCONNECTION_IDFOUND_ROWSGET_LOCK
RELEASE_LOCKLOAD_FILEMASTER_POS_WAITNOW
SYSDATECURRENT_TIMESTAMPCURDATECURRENT_DATE
CURTIMECURRENT_TIMEDATABASEENCRYPT (mit einem Parameter)
LAST_INSERT_IDRANDUNIX_TIMESTAMP (ohne Parameter)USER
BENCHMARK   

Eine Anfrage kann ebenfalls nicht gecachet werden, wenn sie Benutzer-Variablen enthält oder wenn sie in der Form SELECT ... IN SHARE MODE oder der Form SELECT * FROM AUTOINCREMENT_FIELD IS NULL (um als ODBC-Workaround die letzte eingefügte ID abzurufen) ist.

FOUND ROWS() gibt jedoch den korrekten Werte zurück, selbst wenn eine vorhergehende Anfrage aus dem Cache geholt wurde.

Anfragen, die keinerlei Tabellen benutzen oder solche, bei denen der Benutzer eine Spaltenberechtigung für irgend eine der beteiligten Tabellen hat, werden nicht gecachet.

Bevor eine Anfrage aus dem Anfragen-Cache geholt wird, prüft MySQL, ob der Benutzer die SELECT-Berechtigung für alle beteiligten Datenbanken und Tabellen hat. Wenn nicht, wird das Cache-Ergebnis nicht benutzt.

7.9.2. Anfragen-Cache-Konfiguration

Aufgrund des Anfragen-Caches gibt es ein paar neue MySQL Systemvariablen für mysqld, die in einer Konfigurationsdatei oder auf der Kommandozeile beim Starten von mysqld gesetzt werden können:

  • query_cache_limit Keine Ergebnisse cachen, die größer als dieser Wert sind (Vorgabe 1 MB).

  • query_cache_size Der zugewiesene Arbeitsspeicher, um Ergebnisse aus alten Anfragen zu speichern. Wenn er 0 ist, ist der Anfragen-Cache abgeschaltet (Vorgabe).

  • query_cache_startup_type Dieser Wert (nur Zahlen) kann wie folgt gesetzt werden:

    OptionBeschreibung
    0(OFF - AUS, Ergebnisse nicht cachen oder abrufen)
    1(ON - AN, alle Ergebnisse ausser SELECT SQL_NO_CACHE ...-Anfragen cachen)
    2(DEMAND - AUF VERLANGEN, nur SELECT SQL_CACHE ...-Anfragen cachen)

Innerhalb eines Threads (Verbindung) kann das Verhalten des Anfragen-Caches abweichend von der Vorgabe verändert werden. Die Syntax ist wie folgt:

SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND SQL_QUERY_CACHE_TYPE = 0 | 1 | 2

OptionBeschreibung
0 oder OFFKeine Ergebnisse cachen oder abrufen.
1 oder ONAlle Ergebnisse ausser SELECT SQL_NO_CACHE ...-Anfragen cachen.
2 oder DEMANDNur SELECT SQL_CACHE ...-Anfragen cachen.

Vorgabemäßig hängt SQL_QUERY_CACHE_TYPE vom Wert von query_cache_startup_type ab, als der Thread erzeugt wurde.

7.9.3. Anfragen-Cache-Optionen in SELECT

Es gibt zwei mögliche Anfragen-Cache-bezogene Parameter, die in einer SELECT-Anfrage angegeben werden können:

OptionBeschreibung
SQL_CACHEWenn SQL_QUERY_CACHE_TYPE DEMAND ist, darf die Anfrage gecachet werden. Wenn SQL_QUERY_CACHE_TYPE ON ist, ist das die Vorgabe. Wenn SQL_QUERY_CACHE_TYPE OFF ist, nichts tun.
SQL_NO_CACHEDiese Anfrage wird nicht gecachet.

7.9.4. Anfragen-Cache-Status und -Wartung

Mit dem FLUSH QUERY CACHE-Befehl können Sie den Anfragen-Cache defragmentieren, um den Speicher besser zu benutzen. Dieser Befehl entfernt keinerlei Anfragen aus dem Cache. FLUSH TABLES schreibt auch den Anfragen-Cache zurück auf Platte.

Der RESET QUERY CACHE-Befehl entfernt alle Anfragenergebnisse aus dem Anfragen-Cache.

Sie können die Anfragen-Cache-Performance in SHOW STATUS beobachten:

VariableBeschreibung
Qcache_queries_in_cacheAnzahl von Anfragen, die im Cache registriert sind.
Qcache_insertsAnzahl von Anfragen, die zum Cache hinzugefügt wurden.
Qcache_hitsAnzahl von Cache-Hits.
Qcache_not_cachedAnzahl von nicht gecacheten Anfragen (nicht cachebar oder wegen SQL_QUERY_CACHE_TYPE).
Qcache_free_memoryMenge des freien Speichers für den Anfragen-Cache.
Qcache_total_blocksGesamtzahl von Blöcken im Anfragen-Cache.
Qcache_free_blocksAnzahl freier Speicherblöcke im Anfragen-Cache.

Gesamtzahl von Anfragen = Qcache_inserts + Qcache_hits + Qcache_not_cached.

Der Anfragen-Cache benutzt variable Blocklängen, so dass Qcache_total_blocks und Qcache_free_blocks eine Speicherfragmentierung des Anfragen-Caches anzeigen können. Nach FLUSH QUERY CACHE verbleibt nur ein einzelner (großer) freier Block.

Hinweis: Jede Anfrage benötigt minimal zwei Blöcke (einen für den Anfragentext und einen weiteren für das Anfragenergebnis). Ausserdem benötigt jede Tabelle, die in einer Anfrage benutzt wurde, einen Block. Wenn allerdings zwei oder mehr Anfragen dieselbe Tabelle benutzen, muss nur ein Block zugewiesen werden.


This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.