Kapitel 11. Datentypen
Zurück |  | Weiter

## Kapitel 11. Datentypen

MySQL unterstützt eine Vielzahl von Datentypen verschiedener Kategorien: numerische Typen, Typen für Datum und Uhrzeit und auch String-Typen (zeichenbasierte Typen). In diesem Kapitel erhalten Sie zunächst eine Übersicht über diese Datentypen. Nachfolgend finden Sie eine detaillierte Beschreibung der Eigenschaften von Typen der jeweiligen Kategorien und eine Zusammenfassung der Speicheranforderungen dieser Datentypen. Die einführende Übersicht ist bewusst kurz gehalten. Detailinformationen zu bestimmten Datentypen – z. B. zu den zur Werteangabe zulässigen Formaten – entnehmen Sie am besten den ausführlicheren Beschreibungen im Verlauf des Kapitels.

MySQL unterstützt auch Erweiterungen zur Verarbeitung raumbezogener Daten. Kapitel 18, Raumbezogene Erweiterungen in MySQL, enthält Informationen zu diesen Datentypen.

Die folgenden Konventionen gelten für eine Reihe der nachfolgenden Datentypbeschreibungen:

- ``M`` gibt die maximale Anzeigebreite für Integer-Typen an. Bei Fließkomma- und Festkommatypen beschreibt `M` die maximale Anzahl der Stellen. Bei String-Typen schließlich ist `M` die maximale Länge. Der maximal zulässige Wert für `M` hängt vom jeweiligen Datentyp ab.

- ``D`` gibt bei Fließkomma- und Festkommatypen die Anzahl der Stellen nach dem Dezimalpunkt an. Der maximale Wert ist 30. Allerdings sollte er nie größer gewählt werden als `M` – 2.

- Eckige Klammern (‘`[`’ und ‘`]`’) zeigen optionale Bestandteile der Typendefinition an.

## 11.1. Überblick über Datentypen

### 11.1.1. Überblick über numerische Datentypen

Es folgt eine Übersicht zu den numerischen Datentypen. Weitere Informationen finden Sie unter Abschnitt 11.2, „Numerische Datentypen“. Die Speicheranforderungen für die Typen sind in Abschnitt 11.5, „Speicherbedarf von Spaltentypen“, beschrieben.

`M` zeigt die maximale Anzeigebreite an. Der höchste zulässige Wert ist 255. Die Anzeigebreite hat keinen Bezug zur Speichergröße oder zum zulässigen Wertebereich des betreffenden Typs (siehe auch Abschnitt 11.2, „Numerische Datentypen“).

Wenn Sie `ZEROFILL` für eine numerische Spalte angeben, fügt MySQL automatisch das Attribut `UNSIGNED` für die Spalte hinzu.

`SERIAL` ist ein Alias für `BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE`.

`SERIAL DEFAULT VALUE` ist in der Definition einer Integer-Spalte ein Alias für `NOT NULL AUTO_INCREMENT UNIQUE`.

Warnung: Wenn Sie die Subtraktion für Integer-Werte verwenden, von denen einer vom Typ `UNSIGNED` ist, dann hat das Ergebnis kein Vorzeichen. Siehe auch Abschnitt 12.8, „Cast-Funktionen und Operatoren“.

- `BIT[(`M`)]`

  Bitfeldtyp. `M` gibt die Anzahl von Bits pro Wert in einem Bereich zwischen 1 und 64 an. Wenn `M` weggelassen wird, wird standardmäßig 1 verwendet.

- `TINYINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Sehr kleiner Integer. Der vorzeichenbehaftete Bereich liegt zwischen `-128` und `127`. Der vorzeichenlose Bereich liegt zwischen `0` und `255`.

- `BOOL`, `BOOLEAN`

  Diese Typen sind Synonyme für `TINYINT(1)`. Der Wert Null wird als falsch ausgewertet, Werte ungleich null als wahr.

  Die Implementierung der vollständigen Verarbeitung boolescher Typen entsprechend dem SQL-Standard ist für die Zukunft vorgesehen.

- `SMALLINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Kleiner Integer. Der vorzeichenbehaftete Bereich liegt zwischen `-32768` und `32767`. Der vorzeichenlose Bereich liegt zwischen `0` und `65535`.

- `MEDIUMINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Mittelgroßer Integer. Der vorzeichenbehaftete Bereich liegt zwischen `-8388608` und `8388607`. Der vorzeichenlose Bereich liegt zwischen `0` und `16777215`.

- `INT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Integer normaler Größe. Der vorzeichenbehaftete Bereich liegt zwischen `-2147483648` und `2147483647`. Der vorzeichenlose Bereich liegt zwischen `0` und `4294967295`.

- `INTEGER[(`M`)] [UNSIGNED] [ZEROFILL]`

  Dieser Typ ist synonym zu `INT`.

- `BIGINT[(`M`)] [UNSIGNED] [ZEROFILL]`

  Großer Integer. Der vorzeichenbehaftete Bereich liegt zwischen `-9223372036854775808` und `9223372036854775807`. Der vorzeichenlose Bereich liegt zwischen `0` und `18446744073709551615`.

  Bestimmte Aspekte sollten Sie in Bezug auf `BIGINT`-Spalten beachten:

  - Alle Berechnungen werden unter Verwendung vorzeichenbehafteter `BIGINT`- oder `DOUBLE`-Werte durchgeführt. Aus diesem Grund sollten Sie – mit Ausnahme von Bitfunktionen – keine vorzeichenlosen großen Integer-Zahlen benutzen, die größer sind als `9223372036854775807` (63 Bits)! Andernfalls können, wenn Sie einen `BIGINT`- in einen `DOUBLE`-Wert konvertieren, die letzten Stellen des Ergebnisses aufgrund von Rundungsfehlern unter Umständen falsch sein.

    MySQL kann `BIGINT` in den folgenden Fällen verarbeiten:

    - Bei der Verwendung von Integer-Zahlen zur Speicherung großer vorzeichenloser Werte in einer `BIGINT`-Spalte.

    - In `MIN(`col_name`)` oder `MAX(`col_name`)`, wobei `col_name` eine `BIGINT`-Spalte referenziert.

    - Bei der Verwendung von Operatoren (`+`, `-`, `*` usw.), wenn beide Operanden Integers sind.

  - Sie können einen exakten Integer-Wert jederzeit in einer `BIGINT`-Spalte speichern, indem Sie zur Speicherung einen String verwenden. In diesem Fall führt MySQL eine Konvertierung des Strings in eine Zahl durch, wobei keine zwischenzeitliche Darstellung mit doppelter Genauigkeit erfolgt.

  - Die Operatoren `-`, `+` und `*` verwenden die `BIGINT`-Arithmetik, wenn beide Operanden Integers sind. Das bedeutet, dass Sie, wenn Sie zwei große Integers (oder Ergebnisse von Funktionen, die Integers zurückgeben) miteinander multiplizieren, unerwartete Ergebnisse erhalten können, wenn das Ergebnis größer als `9223372036854775807` ist.

- `FLOAT[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`

  Kleine Fließkommazahl (mit einfacher Genauigkeit). Zulässige Werte sind der Bereich zwischen `-3.402823466E+38` und `-1.175494351E-38`, `0` und der Bereich zwischen `1.175494351E-38` und `3.402823466E+38`. Dies sind theoretische Werte, die auf dem IEEE-Standard basieren. Der tatsächliche Wertebereich kann abhängig von Ihrer Hardware oder Ihrem Betriebssystem ein wenig kleiner sein.

  `M` ist die Gesamtzahl von Dezimalstellen, `D` die Anzahl der Stellen hinter dem Dezimalpunkt. Wenn `M` und `D` nicht angegeben werden, werden die Werte im Rahmen dessen gespeichert, was hardwareseitig unterstützt wird. Eine Fließkommazahl mit einfacher Genauigkeit ist auf etwa sieben Dezimalstellen genau.

  Sofern angegeben, verbietet `UNSIGNED` negative Werte.

  Durch die Verwendung von `FLOAT` können sich unerwartete Probleme ergeben, weil alle Berechnungen in MySQL mit doppelter Genauigkeit erfolgen. Siehe auch Abschnitt A.5.7, „Lösung von Problemen mit nicht übereinstimmenden Zeilen“.

- `DOUBLE[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`

  Fließkommazahl normaler Größe (mit doppelter Genauigkeit). Zulässige Werte sind der Bereich zwischen `-1.7976931348623157E+308` und `-2.2250738585072014E-308`, `0` und der Bereich zwischen `2.2250738585072014E-308` und `1.7976931348623157E+308`. Dies sind theoretische Werte, die auf dem IEEE-Standard basieren. Der tatsächliche Wertebereich kann abhängig von Ihrer Hardware oder Ihrem Betriebssystem ein wenig kleiner sein.

  `M` ist die Gesamtzahl von Dezimalstellen, `D` die Anzahl der Stellen hinter dem Dezimalpunkt. Wenn `M` und `D` nicht angegeben werden, werden die Werte im Rahmen dessen gespeichert, was hardwareseitig unterstützt wird. Eine Fließkommazahl mit doppelter Genauigkeit ist auf etwa 15 Dezimalstellen genau.

  Sofern angegeben, verbietet `UNSIGNED` negative Werte.

- `DOUBLE PRECISION[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`, `REAL[(`M`,`D`)] [UNSIGNED] [ZEROFILL]`

  Diese Typen sind Synonyme für `DOUBLE`. Ausnahme: Wenn der SQL-Modus `REAL_AS_FLOAT` aktiviert ist, ist `REAL` ein Synonym für `FLOAT` statt für `DOUBLE`.

- `FLOAT(`p`) [UNSIGNED] [ZEROFILL]`

  Fließkommazahl. `p` steht für die Genauigkeit in Bit, aber MySQL verwendet diesen Wert nur zur Bestimmung, ob als Datentyp für das Ergebnis `FLOAT` oder `DOUBLE` zugewiesen werden soll. Liegt `p` zwischen 0 und 24, dann wird `FLOAT` (ohne `M`- und `D`-Werte) als Typ gewählt. Liegt `p` zwischen 25 und 53, dann wird `DOUBLE` (ohne `M`- und `D`-Werte) als Typ gewählt. Der Bereich der Ergebnisspalte entspricht den Datentypen `FLOAT` mit einfacher Genauigkeit oder `DOUBLE` mit doppelter Genauigkeit entsprechend obiger Beschreibung.

  Die Syntax `FLOAT(`p`)` wird aus Gründen der ODBC-Kompatibilität unterstützt.

- `DECIMAL[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`

  Gepackte „exakte“ Festkommazahl. `M` ist die Gesamtzahl von Dezimalstellen (Genauigkeit), `D` die Anzahl der Stellen hinter dem Dezimalpunkt. Der Dezimalpunkt sowie das Zeichen ‘`-`’ (für negative Zahlen) werden bei der Zählung für `M` nicht berücksichtigt. Wenn `D` 0 ist, haben die Werte keinen Dezimalpunkt und keine Nachkommastellen. Die maximale Anzahl der Stellen (`M`) beträgt bei `DECIMAL` 65, die maximale Anzahl unterstützter Dezimalstellen (`D`) 30. Wird `D` weggelassen, dann wird als Vorgabe 0 verwendet; fehlt die Angabe `M`, dann ist 10 der Standardwert.

  Sofern angegeben, verbietet `UNSIGNED` negative Werte.

  Berechnungen in den Grundrechenarten (`+, -, *, /`) erfolgen bei `DECIMAL`-Spalten stets mit einer Genauigkeit von 65 Stellen.

- `DEC[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`, `NUMERIC[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`, `FIXED[(`M`[,`D`])] [UNSIGNED] [ZEROFILL]`

  Diese Typen sind Synonyme für `DECIMAL`. Das Synonym `FIXED` steht aus Gründen der Kompatibilität mit anderen Datenbanksystemen zur Verfügung.

### 11.1.2. Überblick über Datums- und Zeittypen

Es folgt eine Übersicht über die zeitbezogenen Datentypen. Weitere Informationen finden Sie unter Abschnitt 11.3, „Datums- und Zeittypen“. Die Speicheranforderungen für die Typen sind in Abschnitt 11.5, „Speicherbedarf von Spaltentypen“, beschrieben.

Die Zusammenfassungsfunktionen `SUM()` und `AVG()` funktionieren bei Zeitwerten nicht. (Sie konvertieren die Werte in Zahlen, wodurch alles, was nach dem ersten nichtnumerischen Zeichen auftaucht, verloren geht.) Um dieses Problem zu umgehen, können Sie die Werte in numerische Einheiten konvertieren, dann die Zusammenfassungsfunktion ausführen und abschließend eine Rückkonvertierung in den Zeitwert durchführen. Ein paar Beispiele:

    SELECT SEC_TO_TIME(SUM(TIME_TO_SEC(time_col))) FROM tbl_name;
    SELECT FROM_DAYS(SUM(TO_DAYS(date_col))) FROM tbl_name;

- `DATE`

  Datum. Der unterstützte Bereich liegt zwischen `'1000-01-01'` und `'9999-12-31'`. MySQL zeigt `DATE`-Werte im Format `'YYYY-MM-DD'` an, gestattet Ihnen aber, wahlweise Strings oder Zahlen in `DATE`-Spalten einzugeben.

- `DATETIME`

  Kombination aus Datum und Uhrzeit. Der unterstützte Bereich liegt zwischen `'1000-01-01 00:00:00'` und `'9999-12-31 23:59:59'`. MySQL zeigt `DATETIME`-Werte im Format `'YYYY-MM-DD HH:MM:SS'` an, gestattet Ihnen aber, wahlweise Strings oder Zahlen in `DATETIME`-Spalten einzugeben.

- `TIMESTAMP[(`M`)]`

  Zeitstempel. Der Bereich liegt zwischen `'1970-01-01 00:00:00'` und einem Zeitpunkt irgendwann im Jahr `2037`.

  Eine `TIMESTAMP`-Spalte ist nützlich, um Datum und Uhrzeit einer `INSERT`- oder `UPDATE`-Operation aufzunehmen. Standardmäßig wird die erste `TIMESTAMP`-Spalte in einer Tabelle automatisch auf das Datum und die Uhrzeit der zuletzt durchgeführten Operation gesetzt, sofern Sie nicht selbst einen Wert angeben. Sie können `TIMESTAMP`-Spalten auch auf die aktuellen Werte für Datum und Uhrzeit setzen, indem Sie einen `NULL`-Wert zuweisen. Varianten der automatischen Initialisierung und Eigenschaften von Änderungen sind in Abschnitt 11.3.1.1, „`TIMESTAMP`-Eigenschaften ab MySQL 4.1“, beschrieben.

  Ein `TIMESTAMP`-Wert wird als String im Format `'YYYY-MM-DD HH:MM:SS'` zurückgegeben, dessen Anzeigebreite auf 19 Zeichen festgelegt ist. Um den Wert als Zahl zu erhalten, sollten Sie `+0` zur Zeitstempelspalte hinzufügen.

  Hinweis: Das vor MySQL 4.1 verwendete `TIMESTAMP`-Format wird von MySQL 5.1 nicht unterstützt. Informationen zum veralteten Format finden Sie im MySQL-Referenzhandbuch für die Versionen 3.23, 4.0 und 4.1.

- `TIME`

  Eine Zeitangabe. Der Bereich liegt zwischen `'-838:59:59'` und `'838:59:59'`. MySQL zeigt `TIME`-Werte im Format `'HH:MM:SS'` an, gestattet Ihnen aber, wahlweise Strings oder Zahlen in `TIME`-Spalten einzugeben.

- `YEAR[(2|4)]`

  Ein Jahr im zwei- oder vierstelligen Format. Das vierstellige Format ist standardmäßig voreingestellt. In diesem Format sind zulässige Werte der Bereich zwischen `1901` und `2155` sowie `0000`. Im zweistelligen Format ist der Bereich `70` bis `69` zulässig; er bezeichnet die Jahre 1970 bis 2069. MySQL zeigt `YEAR`-Werte im Format `YYYY` an, gestattet Ihnen aber, wahlweise Strings oder Zahlen in `YEAR`-Spalten einzugeben.

### 11.1.3. Überblick über String-Typen

Es folgt eine Übersicht über die String-Datentypen. Weitere Informationen finden Sie unter Abschnitt 11.4, „String-Typen“. Die Speicheranforderungen für die Typen sind in Abschnitt 11.5, „Speicherbedarf von Spaltentypen“, beschrieben.

Seit MySQL 4.1 weisen die String-Typen eine Reihe von Funktionen auf, die Sie, wenn Sie bislang nur mit älteren MySQL-Versionen (vor 4.1) gearbeitet haben, unter Umständen nicht kennen:

- Spaltendefinitionen für viele String-Datentypen können ein Attribut `CHARACTER SET` enthalten, mit dem der Zeichensatz angegeben wird. (`CHARSET` ist ein Synonym für `CHARACTER SET`.) Das Attribut `COLLATE` gibt die Sortierung für den Zeichensatz an. Diese Attribute gelten für `CHAR`, `VARCHAR`, die `TEXT`-Typen, `ENUM` und `SET`. Zum Beispiel:

      CREATE TABLE t
      (
          c1 VARCHAR(20) CHARACTER SET utf8,
          c2 TEXT CHARACTER SET latin1 COLLATE latin1_general_cs
      );

  Diese Tabellendefinition erstellt zwei Spalten namens `c1` und `c2`. Für die erste Spalte sind der Zeichensatz `utf8` und die Standardsortierung für diesen Zeichensatz festgelegt, für die zweite `latin1` und eine Sortierung mit Unterscheidung der Groß-/Kleinschreibung.

- MySQL 5.1 interpretiert Längenangaben in Zeichenspaltendefinitionen als Anzahl von Zeichen. (Früher wurde als Grundlage die Einheit Byte verwendet.)

- Bei `CHAR`, `VARCHAR` und den `TEXT`-Typen wird, wenn das Attribut `BINARY` angegeben ist, der Spalte die binäre Sortierung des spaltenspezifischen Zeichensatzes zugewiesen. (In älteren Versionen konnte eine Spalte bei Angabe von `BINARY` binäre Strings speichern.)

- Sortierung und Vergleiche basieren bei Zeichenspalten auf dem Zeichensatz, der der Spalte zugewiesen ist. (Früher basierten Sortierung und Vergleich auf der Sortierung des Serverzeichensatzes.) Bei `CHAR`-und `VARCHAR`-Spalten können Sie eine binäre Sortierung oder aber das Attribut `BINARY` angeben, damit für Sortierung und Vergleiche statt der lexikalen Reihenfolge die zugrunde liegenden Zeichencodewerte benutzt werden.

Kapitel 10, Zeichensatz-Unterstützung, enthält weitere Informationen zur Verwendung von Zeichensätzen in MySQL.

- `[NATIONAL] CHAR(`M`) [BINARY | ASCII | UNICODE]`

  Ein String fester Länge, der bei der Speicherung mit Leerzeichen auf die angegebene Länge aufgefüllt wird. `M` steht für die Spaltenlänge. `M` liegt in einem Bereich zwischen 0 und 255 Zeichen.

  Hinweis: Am Ende stehende Leerzeichen werden beim Abrufen von `CHAR`-Werten entfernt.

  Wenn Sie versuchen, die Länge einer `CHAR`-Spalte auf einen Wert größer 255 zu setzen, dann schlägt die `CREATE TABLE`- oder `ALTER TABLE`-Anweisung, mit der Sie dies tun, fehl und gibt eine Fehlermeldung aus:

      mysql> CREATE TABLE c1 (col1 INT, col2 CHAR(500));
      ERROR 1074 (42000): Column length too big for column 'col' (max = 255);
      use BLOB or TEXT instead
      mysql> SHOW CREATE TABLE c1;
      ERROR 1146 (42S02): Table 'test.c1' doesn't exist

  `CHAR` ist eine Abkürzung für `CHARACTER`. `NATIONAL CHAR` (und die äquivalente Kurzform `NCHAR`) ist bei SQL die Standardmethode, um festzulegen, dass eine `CHAR`-Spalte einen bestimmten vordefinierten Zeichensatz verwendet. Seit Version 4.1 ist `utf8` bei MySQL dieser vordefinierte Zeichensatz. Siehe Abschnitt 10.3.6, „Nationaler Zeichensatz“.

  Das Attribut `BINARY` ist eine Kurzform zur Festlegung der binären Sortierung des Spaltenzeichensatzes. In diesem Fall basieren Sortierung und Vergleich auf numerischen Zeichenwerten.

  Das Attribut `ASCII` ist eine Abkürzung für `CHARACTER SET latin1`.

  Das Attribut `UNICODE` ist eine Abkürzung für `CHARACTER SET ucs2`.

  Der Datentyp `CHAR BYTE` ist ein Alias für den Typ `BINARY`. Grund hierfür sind Kompatibilitätsaspekte.

  MySQL gestattet Ihnen die Erstellung einer Spalte des Typs `CHAR(0)`. Dies ist in erster Linie praktisch, wenn eine Kompatibilität mit alten Anwendungen erforderlich ist, die auf das Vorhandensein einer Spalte angewiesen sind, aber deren Wert überhaupt nicht nutzen. `CHAR(0)` ist ferner recht praktisch, wenn Sie eine Spalte benötigen, die nur zwei Werte annehmen kann: Eine `CHAR(0)`-Spalte, die nicht als `NOT NULL` definiert ist, besetzt genau ein Bit und kann nur die Werte `NULL` und `''` (Leer-String) aufnehmen.

- `CHAR`

  Dieser Typ ist synonym zu `CHAR(1)`.

- `[NATIONAL] VARCHAR(`M`) [BINARY]`

  Ein String variabler Länge. `M` gibt die maximale Spaltenlänge an. Für `M` liegt der zulässige Bereich zwischen 0 und 65.535. (Die tatsächliche Maximallänge einer `VARCHAR`-Spalte wird durch die maximale Datensatzlänge und den von Ihnen verwendeten Zeichensatz bestimmt. Die effektive Maximallänge beträgt 65.532 Byte.)

  Hinweis: MySQL 5.1 beachtet die Spezifikation des SQL-Standards und entfernt am Anfang stehende Leerzeichen aus `VARCHAR`-Werten nicht.

  `VARCHAR` ist eine Abkürzung für `CHARACTER VARYING`.

  Das Attribut `BINARY` ist eine Kurzform zur Festlegung der binären Sortierung des Spaltenzeichensatzes. In diesem Fall basieren Sortierung und Vergleich auf numerischen Zeichenwerten.

  `VARCHAR` wird mit einem Präfix von 1 oder 2 Byte Länge und den Daten gespeichert. 2 Byte beträgt die Länge des Präfixes, wenn die `VARCHAR`-Spalte mit einer Länge größer 255 deklariert wurde.

- `BINARY(`M`)`

  Der Typ `BINARY` ähnelt `CHAR`, speichert aber Strings aus binären Bytes statt nichtbinärer Zeichen-Strings.

- `VARBINARY(`M`)`

  Der Typ `VARBINARY` ähnelt `VARCHAR`, speichert aber Strings aus binären Bytes statt nichtbinärer Zeichen-Strings.

- `TINYBLOB`

  Eine `BLOB`-Spalte mit einer Maximallänge von 255 (28 – 1) Byte.

- `TINYTEXT`

  Eine `TEXT`-Spalte mit einer Maximallänge von 255 (28 – 1) Zeichen.

- `BLOB[(`M`)]`

  Eine `BLOB`-Spalte mit einer Maximallänge von 65.535 (216 – 1) Byte.

  Für diesen Typ kann optional die Länge `M` angegeben werden. In diesem Fall erstellt MySQL die Spalte mit dem kleinsten `BLOB`-Typ, der groß genug zur Aufnahme von Werten mit einer Länge von `M` Bytes ist.

- `TEXT[(`M`)]`

  Eine `TEXT`-Spalte mit einer Maximallänge von 65.535 (216 – 1) Zeichen.

  Für diesen Typ kann optional die Länge `M` angegeben werden. In diesem Fall erstellt MySQL die Spalte mit dem kleinsten `TEXT`-Typ, der groß genug zur Aufnahme von Werten mit einer Länge von `M` Zeichen ist.

- `MEDIUMBLOB`

  Eine `BLOB`-Spalte mit einer Maximallänge von 16.777.215 (224 – 1) Byte.

- `MEDIUMTEXT`

  Eine `TEXT`-Spalte mit einer Maximallänge von 16.777.215 (224 – 1) Zeichen.

- `LONGBLOB`

  Eine `BLOB`-Spalte mit einer Maximallänge von 4.294.967.295 (232 – 1) Byte (4 Gbyte). Die maximale effektive (d. h. zulässige) Länge von `LONGBLOB`-Spalten hängt von der maximalen Paketgröße im Client/Server-Protokoll und dem verfügbaren Speicher ab.

- `LONGTEXT`

  Eine `TEXT`-Spalte mit einer Maximallänge von 4.294.967.295 (232 – 1) Zeichen. Die maximale effektive (d. h. zulässige) Länge von `LONGTEXT`-Spalten hängt von der maximalen Paketgröße im Client/Server-Protokoll und dem verfügbaren Speicher ab.

- `ENUM('`value1`','`value2`',...)`

  Eine Auflistung. Es handelt sich dabei um ein String-Objekt, das aus der Liste der Werte `'`value1`'`, `'`value2`'`, `...`, `NULL` und einem speziellen Fehlerwert `''` genau einen Wert auswählt. Eine `ENUM`-Spalte kann maximal 65.535 verschiedene Werte aufweisen. `ENUM`-Werte werden intern als Integers dargestellt.

- `SET('`value1`','`value2`',...)`

  Eine Menge. Es handelt sich um ein String-Objekt, dass null oder mehr Werte haben kann, die jeweils aus der Werteliste `'`value1`'`, `'`value2`'`, `...` stammen. Eine `SET`-Spalte kann maximal 64 Mitglieder haben. `SET`-Werte werden intern als Integers dargestellt.

### 11.1.4. Vorgabewerte von Datentypen

Die Klausel `DEFAULT `value`` in der Spezifikation eines Datentyps gibt einen Vorgabewert für eine Spalte an. Mit einer Ausnahme muss der Vorgabewert immer eine Konstante sein. Funktionen oder Ausdrücke sind als Vorgaben nicht zulässig. Das bedeutet, dass Sie beispielsweise als Vorgabewert einer Datumsspalte nicht den Wert einer Funktion wie `NOW()` oder `CURRENT_DATE` angeben dürfen. Die genannte Ausnahme besteht darin, dass Sie `CURRENT_TIMESTAMP` als Vorgabe für eine `TIMESTAMP`-Spalte festlegen können. Siehe auch Abschnitt 11.3.1.1, „`TIMESTAMP`-Eigenschaften ab MySQL 4.1“.

Für `BLOB`- und `TEXT`-Spalten können keine Vorgaben festgelegt werden.

Wenn eine Spaltendefinition keinen expliziten `DEFAULT`-Wert enthält, bestimmt MySQL diesen wie folgt:

Wenn die Spalte `NULL` als Wert annehmen kann, wird sie mit einer expliziten `DEFAULT NULL`-Klausel definiert.

Kann die Spalte `NULL` nicht als Wert annehmen, dann definiert MySQL die Spalte ohne explizite `DEFAULT`-Klausel. Wenn bei der Dateneingabe eine `INSERT`- oder `REPLACE`-Anweisung keinen Wert für die Spalte enthält, verarbeitet MySQL sie entsprechend dem zum betreffenden Zeitpunkt gültigen SQL-Modus:

- Wenn der strikte SQL-Modus nicht aktiviert ist, setzt MySQL die Spalte auf den impliziten Standardwert für den Datentyp der Spalte.

- Ist der strikte Modus hingegen aktiv, dann erscheint bei transaktionssicheren Tabellen ein Fehler, und für die Anweisung wird ein Rollback durchgeführt. Bei nichttransaktionssicheren Tabellen erscheint ebenfalls ein Fehler; allerdings bleiben, wenn dies erst beim zweiten oder einem nachfolgenden Datensatz geschieht, zuvor eingefügte Datensätze erhalten.

Nehmen wir einmal an, eine Tabelle `t` sei wie folgt definiert:

    CREATE TABLE t (i INT NOT NULL);

In diesem Fall hat `i` keinen expliziten Vorgabewert, d. h., im strikten Modus würde jede der folgenden Anweisungen einen Fehler erzeugen, und es würde kein Datensatz eingefügt. Wird der strikte Modus nicht verwendet, dann erzeugt nur die dritte Anweisung einen Fehler; bei den ersten beiden Anweisungen wird die implizite Vorgabe eingefügt, die dritte Anweisung schlägt hingegen fehl, weil `DEFAULT(i)` keinen Wert erzeugen kann:

    INSERT INTO t VALUES();
    INSERT INTO t VALUES(DEFAULT);
    INSERT INTO t VALUES(DEFAULT(i));

Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

Sie können für eine gegebene Tabelle die Anweisung `SHOW CREATE TABLE` verwenden, um anzuzeigen, welche Spalten eine explizite `DEFAULT`-Klausel aufweisen.

## 11.2. Numerische Datentypen

MySQL unterstützt alle im SQL-Standard vorgesehen numerischen Datentypen. Hierzu gehören exakte numerische Datentypen (`INTEGER`, `SMALLINT`, `DECIMAL` und `NUMERIC`) ebenso wie annähernde Typen (`FLOAT`, `REAL` und `DOUBLE PRECISION`). Das Schlüsselwort `INT` ist ein Synonym für `DECIMAL`, und das Schlüsselwort `INTEGER` ist ein Synonym für `DEC`. Informationen zu den Speicheranforderungen numerischer Typen finden Sie in Abschnitt 11.5, „Speicherbedarf von Spaltentypen“.

Der Datentyp `BIT` speichert Bitfeldwerte und wird für `MyISAM`-, `MEMORY`-, `InnoDB`- und `BDB`-Tabellen unterstützt.

In Erweiterung des SQL-Standards unterstützt MySQL auch die Integer-Typen `TINYINT`, `MEDIUMINT` und `BIGINT`. Die folgende Tabelle zeigt den erforderlichen Speicherplatz und den zulässigen Wertebereich der Integer-Typen.

Typ | Bytes | Minimum | Maximum
|  | (vorzeichenbehaftet/vorzeichenlos) | (vorzeichenbehaftet/vorzeichenlos)
`TINYINT` | 1 | `-128` | `127`
|  | `0` | `255`
`SMALLINT` | 2 | `-32768` | `32767`
|  | `0` | `65535`
`MEDIUMINT` | 3 | `-8388608` | `8388607`
|  | `0` | `16777215`
`INT` | 4 | `-2147483648` | `2147483647`
|  | `0` | `4294967295`
`BIGINT` | 8 | `-9223372036854775808` | `9223372036854775807`
|  | `0` | `18446744073709551615`

Eine andere Erweiterung wird von MySQL zur optionalen Spezifizierung der Anzeigebreite eines Integer-Werts unterstützt. Die Angabe erfolgt auf das Schlüsselwort für den Datentyp folgend in Klammern (z. B. `INT(4)`). Diese optionale Angabe der Anzeigebreite wird verwendet, um die Anzeige von Werten, die eine geringere als die für die Spalte festgelegte Breite aufweisen, nach links mit Leerzeichen aufzufüllen.

Die Anzeigebreite schränkt weder die in einer Spalte speicherbaren Wertebereiche noch die Anzahl der Stellen ein, die für Werte angezeigt werden, deren Breite die festgelegte Spaltenbreite überschreitet.

Wenn hierzu das optionale Erweiterungsattribut `ZEROFILL` verwendet wird, erfolgt ein Auffüllen nicht mehr mit Leerzeichen, sondern mit Nullen. Bei einer Spalte etwa, die als `INT(5) ZEROFILL` deklariert ist, wird der Wert `4` als `00004` abgerufen. Beachten Sie, dass, wenn Sie Werte in einer Integer-Spalte speichern, die größer sind als die Anzeigebreite, unter Umständen Probleme auftauchen, wenn MySQL Temporärtabellen für einige komplizierte Joins anlegt, denn in diesen Fällen setzt MySQL voraus, dass die Daten in die ursprüngliche Spaltenbreite passen.

Für alle Integer-Typen gibt es das (nicht standardkonforme) Attribut `UNSIGNED`. Vorzeichenlose Werte können verwendet werden, wenn in einer Spalte nur nichtnegative Zahlen zulässig sind und Sie für die Spalte einen nach oben erweiterten numerischen Wertebereich benötigen. Wenn beispielsweise eine `INT`-Spalte als `UNSIGNED` deklariert wird, ist die Spaltengröße gleich; zulässige Werte entstammen nun aber nicht mehr dem Bereich zwischen `-2147483648` und `2147483647`, sondern dem Bereich zwischen `0` und `4294967295`.

Auch Fließkommazahlen und Festkommazahlen können vorzeichenlos sein. Wie bei Integer-Typen verhindert dieses Attribut die Speicherung negativer Werte in der Spalte. Anders als bei jenen aber bleibt das Maximum für die Spaltenwerte unverändert.

Wenn Sie `ZEROFILL` für eine numerische Spalte angeben, fügt MySQL automatisch das Attribut `UNSIGNED` für die Spalte hinzu.

Bei Fließkommadatentypen verwendet MySQL 4 Byte für Werte einfacher und 8 Byte für Werte doppelter Genauigkeit.

Die Datentypen `FLOAT` und `DOUBLE` werden zur Darstellung annähernder numerischer Datenwerte verwendet. Für `FLOAT` gestattet der SQL-Standard optional die Angabe der Genauigkeit (nicht aber des Bereichs des Exponenten) in Bits, die dem Schlüsselwort `FLOAT` in Klammern folgen. Auch MySQL unterstützt diese optionale Genauigkeitsangabe, der Genauigkeitswert wird allerdings nur zur Bestimmung der Speichergröße verwendet. Eine Genauigkeit von 0 bis 23 hat eine vier Byte lange `FLOAT`-Spalte mit einfacher Genauigkeit zum Ergebnis. Bei einer Genauigkeit von 24 bis 53 entsteht eine acht Byte lange `DOUBLE`-Spalte mit doppelter Genauigkeit.

MySQL gestattet eine nicht standardkonforme Syntax: `FLOAT(`M`,`D`)` oder `REAL(`M`,`D`)` oder `DOUBLE PRECISION(`M`,`D`)`. Hierbei bedeutet „`(`M`,`D`)`“, dass Werte mit bis zu `M` Stellen insgesamt angezeigt werden, wovon `D` Nachkommastellen sind. Beispielsweise erscheint eine Spalte, die als `FLOAT(7,4)` definiert wurde, in der Anzeige als `-999.9999`. MySQL führt die Rundung beim Speichern der Werte durch, d. h. wenn Sie `999.00009` in einer `FLOAT(7,4)`-Spalte einfügen, ist das Ergebnis näherungsweise `999.0001`.

MySQL behandelt `DOUBLE` als Synonym für `DOUBLE PRECISION` (dies ist eine nicht standardkonforme Erweiterung). Ferner behandelt MySQL `REAL` als Synonym für `DOUBLE PRECISION` (nicht standardkonforme Variante), sofern der SQL-Modus `REAL_AS_FLOAT` nicht aktiviert ist.

Wenn Sie maximale Portabilität benötigen, sollten Sie in Code, in dem die Speicherung annähernder numerischer Datenwerte erforderlich ist, `FLOAT` oder `DOUBLE PRECISION` ohne Angabe der Genauigkeit oder der Stellen verwenden.

Die Datentypen `DECIMAL` und `NUMERIC` werden zur Speicherung exakter numerischer Datenwerte verwendet. In MySQL ist `NUMERIC` als `DECIMAL` implementiert. Diese Typen werden zur Speicherung von Werten benutzt, bei denen die Beibehaltung der exakten Genauigkeit entscheidend ist (z. B. bei Finanzberechnungen).

MySQL 5.1 speichert `DECIMAL`- und `NUMERIC`-Werte im binären Format. In älteren Versionen erfolgte die Speicherung als Strings. Siehe auch Kapitel 23, Präzisionsberechnungen.

Wenn Sie eine `DECIMAL`- oder `NUMERIC`-Spalte deklarieren, können (und sollten) Genauigkeit und Anzahl der Nachkommastellen angegeben werden. Zum Beispiel:

    salary DECIMAL(5,2)

In diesem Beispiel ist `5` die Genauigkeit und `2` die Anzahl der Nachkommastellen. Die Genauigkeit stellt die Anzahl der signifikanten Stellen dar, die für Werte gespeichert werden. Ist für die Nachkommastellen 0 festgelegt, dann haben `DECIMAL`- und `NUMERIC`-Werte keinen Dezimalpunkt und keine Nachkommastellen.

Der SQL-Standard erfordert, dass die Spalte `salary` jeden Wert mit fünf Stellen und zwei Nachkommastellen speichern können muss. Dies bedeutet also, dass der in der Spalte `salary` speicherbare Wertebereich zwischen `-999.99` und `999.99` liegt.

Beim SQL-Standard ist die Syntax `DECIMAL(`M`)` gleichbedeutend mit `DECIMAL(`M`,0)`. Ähnlich hat die Syntax `DECIMAL` die gleiche Bedeutung wie `DECIMAL(`M`,0)`, wobei der Implementierung die Entscheidung zum Wert von `M` überlassen bleibt. MySQL unterstützt diese beiden Varianten der `DECIMAL`- und `NUMERIC`-Syntax. Der Vorgabewert von `M` ist 10.

Die maximale Anzahl von Stellen für `DECIMAL` oder `NUMERIC` beträgt 65, der tatsächliche Bereich für eine gegebene `DECIMAL`- oder `NUMERIC`-Spalte kann jedoch durch die Angaben für Genauigkeit oder Nachkommastellen eingeschränkt werden. Wenn einer solchen Spalte ein Wert mit mehr Nachkommastellen als zulässig zugewiesen wird, dann wird der Wert der zulässigen Anzahl Nachkommastellen angepasst. (Das exakte Verhalten ist betriebssystemspezifisch, aber in der Regel werden überzählige Nachkommastellen einfach abgeschnitten.)

Der Datentyp `BIT` wird zur Speicherung von Bitfeldwerten verwendet. Der Typ `BIT(`M`)` gestattet die Speicherung von `M`-Bit-Werten. Dabei kann `M` in einem Bereich zwischen 1 und 64 liegen.

Zur Angabe von Bitwerten kann die Notation `b'`value`'` verwendet werden. `value` ist ein Binärwert, der aus Einsen und Nullen besteht. So stehen etwa `b'111'` und `b'100000000'` für die Zahlen 7 bzw. 128. Siehe auch Abschnitt 9.1.5, „Bitfeldwerte“.

Wenn Sie einer `BIT(`M`)`-Spalte einen Wert zuweisen, der weniger als `M` Bits lang ist, dann wird der Wert nach links mit Nullen aufgefüllt. So entspricht die Zuweisung des Werts `b'101'` an eine Spalte `BIT(6)` im Endeffekt der Zuweisung von `b'000101'`.

Wenn MySQL einen Wert in einer numerischen Spalte speichern soll, der außerhalb des für den Datentyp zulässigen Bereichs liegt, dann hängt das Verhalten von MySQL von dem zum betreffenden Zeitpunkt aktiven SQL-Modus ab. Wenn etwa keine restriktiven Modi aktiviert sind, setzt MySQL den Wert auf den jeweiligen Endwert des Bereichs und speichert dann diesen Wert. Wenn als Modus jedoch `TRADITIONAL` aktiviert ist, weist MySQL einen Wert außerhalb des Bereichs mit einer Fehlermeldung ab. In diesem Fall schlägt die Einfügeoperation fehl – ganz so, wie es der SQL-Standard vorsieht.

Wird im nichtstrikten Modus einer Integer-Spalte ein Wert außerhalb des zulässigen Bereichs zugewiesen, dann speichert MySQL den Wert, der dem entsprechenden Endpunkt für den Datentyp der Spalte entspricht. Speichern Sie also etwa 256 in einer `TINYINT`- oder `TINYINT UNSIGNED`-Spalte, dann speichert MySQL 255 bzw. 127. Wird einer Fließkomma- oder Festkommaspalte ein Wert außerhalb des durch die angegebene (oder vorgabeseitige) Genauigkeit und Nachkommastellenanzahl festgelegten Bereichs zugewiesen, dann speichert MySQL ebenfalls den für diesen Bereich vorgesehenen Endpunkt:

Konvertierungen, die aufgrund von Kürzungsoperationen stattfinden, wenn MySQL nicht im strikten Modus läuft, werden als Warnungen für `ALTER TABLE`-, `LOAD DATA INFILE`- und `UPDATE`-Anweisungen sowie `INSERT`-Anweisungen für mehrere Datensätze gemeldet. Wenn MySQL im strikten Modus ausgeführt wird, schlagen diese Anweisungen fehl, und einige oder alle Werte werden nicht eingefügt bzw. geändert (dies hängt davon, ob die Tabelle transaktionssicher ist, sowie von weiteren Faktoren ab). Detaillierte Informationen finden Sie in Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

## 11.3. Datums- und Zeittypen

Datentypen für Datum und Uhrzeit erlauben die Darstellung zeitlicher Werte. In diese Kategorie fallen die Typen `DATETIME`, `DATE`, `TIMESTAMP`, `TIME` und `YEAR`. Jeder zeitbezogene Typ hat einen Bereich zulässiger Werte sowie einen „Nullwert“, der verwendet werden kann, wenn Sie einen unzulässigen Wert angeben, den MySQL nicht darstellen kann. Der Typ `TIMESTAMP` unterstützt ein spezielles Verhalten der automatischen Aktualisierung, welches im weiteren Verlauf beschrieben werden wird. Informationen zu den Speicheranforderungen zeitbezogener Typen finden Sie in Abschnitt 11.5, „Speicherbedarf von Spaltentypen“.

MySQL gibt Warnungen oder Fehler aus, wenn Sie einen unzulässigen Wert einzufügen versuchen. Indem Sie den passenden SQL-Modus wählen, können Sie genauer festlegen, welche Datenarten MySQL unterstützen soll. (Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.) Wenn Sie etwa den Modus `ALLOW_INVALID_DATES` verwenden, akzeptiert MySQL auch bestimmte irreale Daten wie `'1999-11-31'`. Dies ist praktisch, wenn Sie einen „möglicherweise falschen“ Wert, den ein Benutzer eingegeben hat (z. B. in ein Webformular), für die zukünftige Verarbeitung in der Datenbank speichern wollen. In diesem Modus überprüft MySQL lediglich, ob der Monat im Bereich zwischen 0 und 12 und der Tag im Bereich zwischen 0 und 31 liegt. Diese Bereiche umfassen deswegen die Null, weil MySQL in `DATE`- oder `DATETIME`-Spalten auch die Speicherung von Datumsangaben gestattet, bei denen der Tag oder der Monat und der Tag null sind. Dies ist recht nützlich bei Anwendungen, die ein Geburtsdatum speichern sollen, das Sie nicht genau kennen. In diesem Fall speichern Sie das Datum einfach als `'1999-00-00'` oder `'1999-01-00'`. Wenn Sie Datumsangaben auf diese Weise speichern, können Sie nicht davon ausgehen, für Funktionen wie `DATE_SUB()` oder `DATE_ADD` korrekte Ergebnisse zu erhalten, denn diese erfordern vollständige Datumsangaben. (Wenn Sie Nullen in Daten nicht erlauben wollen, können Sie den SQL-Modus `NO_ZERO_IN_DATE` aktivieren.)

MySQL gestattet ferner die Speicherung von `'0000-00-00'` als „Pseudodatum“ (hierfür darf der SQL-Modus `NO_ZERO_DATE` jedoch nicht aktiv sein). Dies ist in bestimmten Fällen bequemer (und benötigt zudem weniger Speicher für Daten und Indizes) als die Verwendung von `NULL`-Werten.

Es folgen einige Gesichtspunkte, die Sie bei der Arbeit mit Datentypen für Datum und Uhrzeit beachten sollten:

- MySQL ruft Werte für einen Datentyp für Datum und Uhrzeit in einem Standardausgabeformat ab, versucht aber eine Vielzahl von Eingabewertformaten zu verarbeiten, die von Ihnen eingegeben wurden (z. B. wenn Sie einen Wert angeben, der einem zeitbezogenen Typ zugewiesen oder mit diesem verglichen werden soll). Nur die in den folgenden Abschnitten beschriebenen Formate werden unterstützt. Es wird erwartet, dass Sie zulässige Werte angeben. Wenn Sie Werte in anderen Formaten angeben, können unvorhersehbare Ergebnisse die Folge sein.

- Datumsangaben mit zwei Stellen für die Jahreszahl sind mehrdeutig, da das Jahrhundert unbekannt ist. MySQL interpretiert Werte mit zweistelligen Jahreszahlen gemäß den folgenden Regeln:

  - Jahreszahlen im Bereich zwischen 70 und 99 werden als `1970-1999` interpretiert.

  - Jahreszahlen im Bereich zwischen 00 und 69 werden als `2000-2069` interpretiert.

- Zwar versucht MySQL, Werte in verschiedenen Formaten zu interpretieren, aber Datumsangaben müssen immer in der Reihenfolge Jahr, Monat, Tag angegeben werden (z. B. `'98-09-04'`); die Reihenfolge Monat, Tag, Jahr (`'09-04-98'`) oder die im deutschsprachigen Raum verwendete Reihenfolge Tag, Monat, Jahr (`'04-09-98'`) werden nicht unterstützt.

- MySQL konvertiert Werte eines zeitbezogenen Typs automatisch in eine Zahl, wenn der Wert in einem numerischen Kontext verwendet werden soll (und umgekehrt).

- Wenn MySQL auf einen zeitbezogenen Wert trifft, der außerhalb des zulässigen Bereichs liegt oder für den betreffenden Typ anderweitig ungültig ist, wird dieser in den „Nullwert“ des betreffenden Typs umgewandelt. Eine Ausnahme liegt bei `TIME`-Werten außerhalb des gültigen Bereichs vor: Diese werden auf den entsprechenden Endpunkt des `TIME`-Bereichs gesetzt.

  Die folgende Tabelle zeigt das Format der „Nullwerte“ für die einzelnen Typen. Beachten Sie, dass die Verwendung dieser Werte Warnungen erzeugt, wenn der SQL-Modus `NO_ZERO_DATE` aktiviert ist.

  Datentyp | „Nullwert“
  `DATETIME` | `'0000-00-00 00:00:00'`
  `DATE` | `'0000-00-00'`
  `TIMESTAMP` | `'0000-00-00 00:00:00'`
  `TIME` | `'00:00:00'`
  `YEAR` | `0000`

- Die „Nullwerte“ sind zwar speziell, aber Sie können sie speichern oder explizit referenzieren, indem Sie die Werte in der Tabelle verwenden. Alternativ können Sie dies auch unter Verwendung der Werte `'0'` oder `0` tun, die einfacher zu schreiben sind.

- „Nullwerte“ für Datum und Uhrzeit, die über MyODBC verwendet werden, werden ab MyODBC 2.50.12 automatisch zu `NULL` konvertiert, da ODBC mit solchen Werten nicht umgehen kann.

### 11.3.1. Die `DATETIME`-, `DATE`- und `TIMESTAMP`-Typen

Die Typen `DATETIME`, `DATE` und `TIMESTAMP` gehören zusammen. In diesem Abschnitt werden ihre Eigenschaften sowie Gemeinsamkeiten und Unterschiede beschrieben.

Den Typ `DATETIME` verwenden Sie, wenn Sie Werte benötigen, die sowohl ein Datum als auch eine Uhrzeit enthalten. MySQL ruft `DATETIME`-Werte im Format `'YYYY-MM-DD HH:MM:SS'` ab und zeigt sie auch so an. Der unterstützte Bereich liegt zwischen `'1000-01-01 00:00:00'` und `'9999-12-31 23:59:59'`. („Unterstützt“ bedeutet hier, dass früher liegende Werte zwar funktionieren können, dies aber nicht garantiert ist.)

Der Typ `DATE` erlaubt die Benutzung eines Datums ohne Zeitangabe. MySQL ruft `DATE`-Werte im Format `'YYYY-MM-DD'` ab und zeigt sie auch so an. Der unterstützte Bereich liegt zwischen `'1000-01-01'` und `'9999-12-31'`.

Der Datentyp `TIMESTAMP` schließlich hat je nach MySQL-Version und SQL-Modus des Servers verschiedene Eigenschaften, die im Verlauf dieses Abschnitts noch beschrieben werden.

Sie können `DATETIME`-, `DATE`- und `TIMESTAMP`-Werte mit einem der folgenden gängigen Formate angeben:

- Als String im Format `'YYYY-MM-DD HH:MM:SS'` oder `'YY-MM-DD HH:MM:SS'`. Eine weniger strikte Syntax ist ebenfalls erlaubt: Ein beliebiges Interpunktionszeichen darf als Trennzeichen zwischen Datums- oder Zeiteinheiten benutzt 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'` gleichwertig.

- Als String im Format `'YYYY-MM-DD'` oder `'YY-MM-DD'`. Eine weniger strikte Syntax ist auch hier erlaubt. Beispielsweise sind `'98-12-31'`, `'98.12.31'`, `'98/12/31'` und `'98@12@31'` gleichwertig.

- Als String ohne Trennzeichen in den Formaten `'YYYYMMDDHHMMSS'` oder `'YYMMDDHHMMSS'`, sofern der String als Datum sinngebend ist. Zum Beispiel werden `'19970523091528'` und `'970523091528'` als `'1997-05-23 09:15:28'` interpretiert, aber `'971122129015'` ist unzulässig (der Minutenanteil ist unsinnig) und wird deswegen zu `'0000-00-00 00:00:00'`.

- Als String ohne Trennzeichen in den Formaten `'YYYYMMDD'` oder `'YYMMDD'`, sofern der String als Datum sinngebend ist. Zum Beispiel werden `'19970523'` und `'970523'` als `'1997-05-23'` interpretiert, aber `'971332'` ist unzulässig (der Tages- und der Minutenanteil sind unsinnig) und wird deswegen zu `'0000-00-00'`.

- Als Zahl in den Formaten `YYYYMMDDHHMMSS` oder `YYMMDDHHMMSS`, sofern die Zahl als Datum sinngebend ist. Beispielsweise werden sowohl `19830905132800` als auch `830905132800` als `'1983-09-05 13:28:00'` interpretiert.

- Als Zahl in den Formaten `YYYYMMDD` oder `YYMMDD`, sofern die Zahl als Datum sinngebend ist. Beispielsweise werden sowohl `19830905` als auch `830905` als `'1983-09-05'` interpretiert.

- Als Ergebnis einer Funktion, die einen Wert zurückgibt, der im Kontext von `DATETIME`, `DATE` oder `TIMESTAMP` sinngebend ist, z. B. `NOW()` oder `CURRENT_DATE`.

Unzulässige `DATETIME`-, `DATE`- oder `TIMESTAMP`-Werte werden in den „Nullwert“ des entsprechenden Typs umgewandelt (`'0000-00-00 00:00:00'` oder `'0000-00-00'`).

Bei als Strings angegebenen Werten, die Trennzeichen für Datumsbestandteile enthalten, ist es nicht erforderlich, zwei Stellen für Monats- oder Tageswerte anzugeben, die kleiner als `10` sind. So wird etwa `'1979-6-9'` als `'1979-06-09'` ausgewertet. Ähnlich ist es bei als Strings angegebenen Werten, die Trennzeichen für Uhrzeitbestandteile enthalten, nicht erforderlich, zwei Stellen für Stunden-, Minuten oder Sekundenwerte anzugeben, die kleiner als `10` sind: `'1979-10-30 01:02:03'` ist das Gleiche wie `'1979-10-30 1:2:3'`.

Als Zahlen angegebene Werte sollten eine Länge von 6, 8, 12 oder 14 Stellen haben. Wenn eine Zahl 8 oder 14 Stellen lang ist, werden die Formate `YYYYMMDD` bzw. `YYYYMMDDHHMMSS` angenommen, wobei das Jahr durch die ersten vier Stellen angegeben wird. Umfasst die Zahl 6 oder 12 Stellen, dann werden die Formate `YYMMDD` bzw. `YYMMDDHHMMSS` angenommen, wobei das Jahr durch die ersten beiden Stellen angegeben ist. Zahlen, die eine andere Länge aufweisen, werden so interpretiert, als ob sie am Anfang mit Nullen auf die nächste Länge aufgefüllt würden.

Werte, die als Strings ohne Trennzeichen angegeben werden, werden entsprechend ihrer Länge interpretiert. Ist der String 8 oder 14 Zeichen lang, dann wird angenommen, dass die ersten vier Zeichen das Jahr angeben. Andernfalls wird die Jahresangabe durch die ersten zwei Zeichen erwartet. Der String wird von links nach rechts interpretiert, als Reihenfolge wird Jahr, Monat, Tag, Stunde, Minute und Sekunde angenommen – je nachdem, wie viele Bestandteil im String vorhanden sind. Das bedeutet, dass Sie niemals Strings mit weniger als sechs Zeichen verwenden sollten. Wenn Sie beispielsweise `'9903'` angeben, um den März 1999 darzustellen, dann fügt MySQL einen „Nullwert“ für das Datum in Ihre Tabelle ein. Dies geschieht, weil die Jahres- und Monatsangaben `99` bzw. `03` sind, der Tag aber vollständig fehlt: Der Wert ist kein gültiges Datum. Sie können jedoch ausdrücklich einen Wert Null zur Darstellung fehlender Monats- oder Tagesangaben spezifizieren. So können Sie etwa `'990300'` verwenden, um den Wert `'1999-03-00'` einzufügen.

Sie können bis zu einem gewissen Grad Werte eines Datumstyps einem Objekt zuweisen, welches von einem anderen Datumstyp ist. Allerdings kann es hierdurch zu Werteänderungen oder Datenverlust kommen:

- Wenn Sie einen `DATE`-Wert einem `DATETIME`- oder `TIMESTAMP`-Objekt zuweisen, wird die Uhrzeit des resultierenden Werts auf `'00:00:00'` gesetzt, da `DATE` diese Information nicht enthält.

- Wenn Sie einen `DATETIME`- oder `TIMESTAMP`-Wert einem `DATE`-Objekt zuweisen, wird die Uhrzeit des resultierenden Werts gelöscht, weil der Typ `DATE` diese Information nicht speichert.

- Beachten Sie, dass `DATETIME`-, `DATE`- und `TIMESTAMP`-Werte zwar alle in denselben Formatvarianten angegeben werden können, aber die Typen nicht dieselben Wertebereiche aufweisen. So kann ein `TIMESTAMP`-Wert nicht vor `1970` und nicht nach `2037` liegen. Das bedeutet, dass ein Datum wie `'1968-01-01'` zwar als `DATETIME`- und `DATE`-Wert zulässig, als `TIMESTAMP`-Wert jedoch illegal ist und deswegen zu `0` konvertiert wird.

Beachten Sie die folgenden Widrigkeiten bei der Angabe von Datumswerten:

- Das weniger strikte Format, welches die Angabe von Werten als Strings gestattet, kann heimtückisch sein. So sieht etwa ein Wert wie `'10:11:12'` wegen des als Trennzeichen verwendeten Doppelpunkts (‘`:`’) wie eine Uhrzeit aus, in einem Datumskontext wird er jedoch als `'2010-11-12'` interpretiert. Der Wert `'10:45:15'` wird zu `'0000-00-00'` konvertiert, weil `'45'` kein zulässiger Monat ist.

- Für den Server ist es erforderlich, dass Monats- und Tagesangaben gültig sind und sich nicht einfach nur in den Bereichen 1 bis 12 bzw. 1 bis 31 bewegen. Wenn der strikte Modus deaktiviert ist, werden ungültige Daten wie `'2004-04-31'` in `'0000-00-00'` umgewandelt, und es wird eine Warnung erzeugt. Ist der strikte Modus hingegen aktiviert, dann erzeugen ungültige Datumsangaben einen Fehler. Um derartige Daten zuzulassen, aktivieren Sie `ALLOW_INVALID_DATES`. Weitere Informationen finden Sie in Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

- Datumsangaben mit zwei Stellen für die Jahreszahl sind mehrdeutig, da das Jahrhundert unbekannt ist. MySQL interpretiert Werte mit zweistelligen Jahreszahlen gemäß den folgenden Regeln:

  - Jahreszahlen im Bereich zwischen 00 und 69 werden als `2000-2069` interpretiert.

  - Jahreszahlen im Bereich zwischen 70 und 99 werden als `1970-1999` interpretiert.

#### 11.3.1.1. `TIMESTAMP`-Eigenschaften ab MySQL 4.1

Hinweis: Bei älteren MySQL-Versionen (vor 4.1) unterscheiden sich die Eigenschaften des Datentyps `TIMESTAMP` erheblich von dem, was in diesem Abschnitt beschrieben wurde. Wenn Sie ältere `TIMESTAMP`-Daten konvertieren müssen, damit sie in MySQL 5.1 funktionieren, lesen Sie in jedem Fall die einschlägigen Abschnitte im MySQL-Referenzhandbuch für die Versionen 3.23, 4.0 und 4.1.

`TIMESTAMP`-Spalten werden im selben Format angezeigt wie `DATETIME`-Spalten. Mit anderen Worten ist die Anzeigebreite auf 19 Zeichen festgesetzt, und das Format lautet `YYYY-MM-DD HH:MM:SS`.

Der MySQL Server kann auch mit aktiviertem SQL-Modus `MAXDB` laufen. Wenn am Server dieser Modus aktiv ist, ist `TIMESTAMP` mit `DATETIME` identisch. Das bedeutet, dass, wenn dieser Modus zum Zeitpunkt der Erstellung einer Tabelle aktiviert ist, `TIMESTAMP`-Spalten als `DATETIME`-Spalten erstellt werden. Aufgrund dessen verwenden solche Spalten das `DATETIME`-Anzeigeformat und haben denselben Wertebereich, und es gibt keine automatische Initialisierung oder Aktualisierung auf die aktuellen Werte für Datum und Uhrzeit.

Um den Modus `MAXDB` zu aktivieren, setzen Sie entweder den SQL-Modus des Servers beim Start mit der Serveroption `--sql-mode=MAXDB` auf `MAXDB`, oder Sie stellen die globale Variable `sql_mode` zur Laufzeit ein:

    mysql> SET GLOBAL sql_mode=MAXDB;

Ein Client kann den Server auch so einstellen, dass die eigene Verbindung im `MAXDB`-Modus läuft:

    mysql> SET SESSION sql_mode=MAXDB;

Beachten Sie, dass die Informationen im nachfolgenden Abschnitt nur für `TIMESTAMP`-Spalten in solchen Tabellen gelten, die nicht mit `MAXDB` als aktivem Modus erstellt wurden, weil solche Spalten als `DATETIME`-Spalten erstellt werden.

MySQL akzeptiert keine Zeitstempelwerte, die eine Null in der Tages- oder Monatsspalte oder andere Werte enthalten, die kein gültiges Datum darstellen. Die einzige Ausnahme dieser Regel ist der Sonderwert `'0000-00-00 00:00:00'`.

Bei der Bestimmung, wann die automatische `TIMESTAMP`-Initialisierung und -Aktualisierung erfolgen soll und welche Spalten dieses Verhalten aufweisen sollen, verfügen Sie über ausgesprochen viel Flexibilität:

- Für eine `TIMESTAMP`-Spalte in einer Tabelle können Sie den aktuellen Zeitstempel als Standardwert und Wert für die automatische Aktualisierung angeben. Es ist möglich, den aktuellen Zeitstempel als Vorgabewert für die Initialisierung der Spalte und/oder als Wert für die automatische Aktualisierung zu verwenden. Es ist jedoch nicht möglich, den aktuellen Zeitstempel als Vorgabewert für eine Spalte und als Wert für die automatische Aktualisierung einer anderen Spalte zu verwenden.

- Sie können festlegen, welche `TIMESTAMP`-Spalte sich automatisch initialisieren oder auf die aktuellen Werte für Datum und Uhrzeit setzen soll. Dies muss nicht unbedingt die erste `TIMESTAMP`-Spalte sein.

Die folgenden Regeln bestimmen die Initialisierung und Aktualisierung von `TIMESTAMP`-Spalten:

- Wird ein `DEFAULT`-Wert für die erste `TIMESTAMP`-Spalte in einer Tabelle festgelegt, so wird dieser nicht ignoriert. Als Vorgabe kann `CURRENT_TIMESTAMP` oder ein konstanter Wert für Datum und Uhrzeit verwendet werden.

- `DEFAULT NULL` ist bei der ersten `TIMESTAMP`-Spalte dasselbe wie `DEFAULT CURRENT_TIMESTAMP`. Bei jeder anderen `TIMESTAMP`-Spalte hingegen wird `DEFAULT NULL` als `DEFAULT 0` behandelt.

- Jede einzelne `TIMESTAMP`-Spalte in einer Tabelle kann als diejenige benutzt werden, die mit dem aktuellen Zeitstempel initialisiert oder automatisch aktualisiert wird.

- In einer `CREATE TABLE`-Anweisung kann die erste `TIMESTAMP`-Spalte auf eine der folgenden Weisen deklariert werden:

  - Wenn sowohl `DEFAULT CURRENT_TIMESTAMP`- als auch `ON UPDATE CURRENT_TIMESTAMP`-Klauseln vorhanden sind, dann hat die Spalte den aktuellen Zeitstempel als Vorgabewert und wird automatisch aktualisiert.

  - Fehlen sowohl `DEFAULT`- als auch `ON UPDATE`-Klausel, dann ist dies das Gleiche wie `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP`.

  - Mit `DEFAULT CURRENT_TIMESTAMP`-, aber ohne `ON UPDATE`-Klausel hat die Spalte den aktuellen Zeitstempel als Vorgabewert, wird jedoch nicht automatisch aktualisiert.

  - Ohne `DEFAULT`-, aber mit `ON UPDATE CURRENT_TIMESTAMP`-Klausel hat die Spalte den Standardwert 0 und wird automatisch aktualisiert.

  - Bei einem konstanten `DEFAULT`-Wert erhält die Spalte den angegebenen Standardwert. Wenn die Spalte eine `ON UPDATE CURRENT_TIMESTAMP`-Klausel hat, wird sie automatisch aktualisiert, andernfalls nicht.

  Anders gesagt: Sie können den aktuellen Zeitstempel sowohl als Initialisierungs- als auch als Aktualisierungswert, als einen dieser beiden Werte oder gar nicht verwenden. (So können Sie beispielsweise `ON UPDATE` angeben, um die automatische Aktualisierung zu aktivieren, ohne dass die Spalte automatisch initialisiert werden müsste.)

- `CURRENT_TIMESTAMP`, `CURRENT_TIMESTAMP()` und `NOW()` können gleichermaßen in `DEFAULT`- und `ON UPDATE`-Klauseln verwendet werden. Sie alle haben die Bedeutung „aktueller Zeitstempel“.

  Die Reihenfolge der `DEFAULT`- und `ON UPDATE`-Attribute ist unerheblich. Wenn sowohl `DEFAULT` als auch `ON UPDATE` für eine `TIMESTAMP`-Spalte angegeben werden, kann das eine Attribut vor oder hinter dem anderen stehen. So sind beispielsweise die folgenden Anweisungen gleichwertig:

      CREATE TABLE t (ts TIMESTAMP);
      CREATE TABLE t (ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                                   ON UPDATE CURRENT_TIMESTAMP);
      CREATE TABLE t (ts TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                                   DEFAULT CURRENT_TIMESTAMP);

- Um für eine andere als die erste `TIMESTAMP`-Spalte die automatische Initialisierung oder Aktualisierung festzulegen, müssen Sie dieses Verhalten für die erste `TIMESTAMP`-Spalte unterdrücken. Dies tun Sie, indem Sie ihr explizit einen konstanten `DEFAULT`-Wert zuweisen (z. B. `DEFAULT 0` oder `DEFAULT '2003-01-01 00:00:00'`). Nachfolgend gelten für die andere `TIMESTAMP`-Spalte dieselben Regeln wie für die erste; die einzige Ausnahme besteht darin, dass, wenn Sie sowohl `DEFAULT` als auch `ON UPDATE` weglassen, keine automatische Initialisierung oder Aktualisierung erfolgt.

  So sind beispielsweise die folgenden Anweisungen gleichwertig:

      CREATE TABLE t (
          ts1 TIMESTAMP DEFAULT 0,
          ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                        ON UPDATE CURRENT_TIMESTAMP);
      CREATE TABLE t (
          ts1 TIMESTAMP DEFAULT 0,
          ts2 TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
                        DEFAULT CURRENT_TIMESTAMP);

Sie können die aktuelle Zeitzone für jede Verbindung separat einstellen (siehe Beschreibung in Abschnitt 5.11.8, „Zeitzonen-Unterstützung des MySQL-Servers“). `TIMESTAMP`-Werte werden in UTC gespeichert; zur Speicherung werden sie aus der aktuellen Zeitzone konvertiert und beim Abrufen wieder in die aktuelle Zeitzone zurückkonvertiert. Solange die Zeitzoneneinstellung gleich bleibt, erhalten Sie denselben Wert zurück, den Sie auch gespeichert haben. Wenn Sie einen `TIMESTAMP`-Wert speichern, dann die Zeitzone ändern und den Wert abrufen, unterscheidet sich dieser abgerufene vom gespeicherten Wert. Grund hierfür ist die Tatsache, dass unterschiedliche Zeitzonen für die beiden Konvertierungsvorgänge benutzt wurden. Die aktuelle Zeitzone ist über den Wert der Systemvariablen `time_zone` verfügbar.

Sie können das Attribut `NULL` in die Definition einer `TIMESTAMP`-Spalte einfügen, damit die Spalte auch `NULL`-Werte enthalten kann. Zum Beispiel:

    CREATE TABLE t
    (
      ts1 TIMESTAMP NULL DEFAULT NULL,
      ts2 TIMESTAMP NULL DEFAULT 0,
      ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP
    );

Wenn das Attribut `NULL` nicht angegeben wurde und die Spalte auf `NULL` gesetzt wird, wird sie automatisch auf den aktuellen Zeitstempel umgestellt. Beachten Sie, dass eine `TIMESTAMP`-Spalte, die `NULL`-Werte gestattet, den aktuellen Zeitstempel nur unter einer der folgenden Bedingungen annimmt:

- Ihr Vorgabewert ist als `CURRENT_TIMESTAMP` definiert.

- `NOW()` oder `CURRENT_TIMESTAMP` werden in die Spalte eingefügt.

Mit anderen Worten: Eine `TIMESTAMP`-Spalte, die als `NULL` definiert ist, wird nur dann automatisch aktualisiert, wenn sie unter Verwendung einer Definition wie der folgenden erstellt wurde:

    CREATE TABLE t (ts TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP);

Betrachten Sie im Unterschied dazu folgende Definition einer `TIMESTAMP`-Spalte, die `NULL`-Werte erlaubt, `DEFAULT TIMESTAMP` aber nicht verwendet:

    CREATE TABLE t1 (ts TIMESTAMP NULL DEFAULT NULL);
    CREATE TABLE t2 (ts TIMESTAMP NULL DEFAULT '0000-00-00 00:00:00');

In diesem Fall müssen Sie explizit einen Wert einfügen, der den aktuellen Werten für Datum und Uhrzeit entspricht. Zum Beispiel:

    INSERT INTO t1 VALUES (NOW());
    INSERT INTO t2 VALUES (CURRENT_TIMESTAMP);

### 11.3.2. Der `TIME`-Typ

Abruf und Anzeige von `TIME`-Werten durch MySQL erfolgen im Format `'HH:MM:SS'` (oder im Format `'HHH:MM:SS'` bei einer großen Zahl von Stunden). `TIME`-Werte liegen in einem Bereich zwischen `'-838:59:59'` und `'838:59:59'`. Der Stundenteil kann so groß sein, weil `TIME` nicht nur eine Uhrzeit darstellen kann (diese muss kleiner sein als 24 Stunden), sondern auch die verstrichene Zeit oder ein Zeitintervall zwischen zwei Ereignissen. Ein solches Intervall kann wesentlich länger als 24 Stunden oder sogar negativ sein.

Zur Angabe von `TIME`-Werten steht eine Vielzahl von Formaten zur Verfügung:

- Als String im Format `'D HH:MM:SS.fraction'`. Sie können auch eines der folgenden weniger stringenten Syntaxformate verwenden: `'HH:MM:SS.fraction'`, `'HH:MM:SS'`, `'HH:MM'`, `'D HH:MM:SS'`, `'D HH:MM'`, `'D HH'` oder `'SS'`. Hierbei steht `D` für Tage und kann einen Wert zwischen 0 und 34 haben. Beachten Sie, dass MySQL den Bruchteil (`fraction`) nicht speichert.

- Als String ohne Trennzeichen im Format `'HHMMSS'`, sofern er als Zeitangabe sinngebend ist. Zum Beispiel wird `'101112'` als `'10:11:12'` interpretiert, aber `'109712'` ist unzulässig (der Minutenanteil ist unsinnig) und wird deswegen zu `'00:00:00'`.

- Als Zahl im Format `HHMMSS`, sofern er als Zeitangabe sinngebend ist. So wird etwa `101112` als `'10:11:12'` interpretiert. Die folgenden alternativen Formate werden ebenfalls verstanden: `SS`, `MMSS`, `HHMMSS`, `HHMMSS.fraction`. Beachten Sie, dass MySQL den Bruchteil nicht speichert.

- Als Ergebnis einer Funktion, die einen Wert zurückgibt, der im Kontext von `TIME` sinngebend ist, z. B. `CURRENT_TIME`.

Bei als String angegebenen `TIME`-Werten, die Trennzeichen für Uhrzeitbestandteile enthalten, ist es nicht erforderlich, zwei Stellen für Stunden-, Minuten oder Sekundenwerte anzugeben, die kleiner als `10` sind: `'8:3:2'` ist das Gleiche wie `'08:03:02'`.

Seien Sie vorsichtig bei der Zuweisung abgekürzter Werte zu einer `TIME`-Spalte. Ohne Doppelpunkte interpretiert MySQL die Werte in der Annahme, dass die beiden ganz rechts stehenden Stellen die Sekunden angeben. (MySQL interpretiert `TIME`-Werte nicht als Uhrzeit, sondern als verstrichene Zeit.) So könnte man etwa annehmen, dass `'1112'` und `1112` die Bedeutung `'11:12:00'` (also 12 Minuten nach 11 Uhr) hätten; MySQL liest die Angabe jedoch als `'00:11:12'` (also 11 Minuten und 12 Sekunden). Ähnlich werden `'12'` und `12` als `'00:00:12'` interpretiert. `TIME`-Werte mit Doppelpunkten hingegen werden immer als Uhrzeit betrachtet: `'11:12'` bedeutet also `'11:12:00'` und nicht `'00:11:12'`.

Standardmäßig werden Werte, die außerhalb des für `TIME` zulässigen Bereichs liegen, aber ansonsten zulässig sind, auf den nächstgelegenen Endpunkt des Bereichs gesetzt. Beispielsweise werden `'-850:00:00'` und `'850:00:00'` zu `'-838:59:59'` bzw. `'838:59:59'` konvertiert. Unzulässige `TIME`-Werte werden zu `'00:00:00'` konvertiert. Beachten Sie, dass es, weil `'00:00:00'` selbst ein zulässiger `TIME`-Wert ist, keine Möglichkeit gibt, festzustellen, ob ein in der Tabelle gespeicherter Wert `'00:00:00'` als `'00:00:00'` oder als unzulässiger Wert angegeben wurde.

Zur restriktiveren Behandlung ungültiger `TIME`-Werte aktivieren Sie den strikten SQL-Modus. In diesem Fall werden Fehler ausgegeben. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

### 11.3.3. Der `YEAR`-Typ

Der Datentyp `YEAR` hat genau ein Byte und dient der Darstellung von Jahreszahlen.

MySQL ruft `YEAR`-Werte im Format `YYYY` ab und zeigt sie auch so an. Der Bereich liegt zwischen `1901` und `2155`.

Zur Angabe von `YEAR`-Werten steht eine Vielzahl von Formaten zur Verfügung:

- Als vierstelliger String im Bereich `'1901'` bis `'2155'`.

- Als vierstellige Zahl im Bereich `1901` bis `2155`.

- Als zweistelliger String im Bereich `'00'` bis `'99'`. Werte in den Bereichen `'00'` bis `'69'` und `'70'` bis `'99'` werden zu `YEAR`-Werten in den Bereichen `2000` bis `2069` bzw. `1970` bis `1999` konvertiert.

- Als zweistellige Zahl im Bereich `1` bis `99`. Werte in den Bereichen `1` bis `69` und `70` bis `99` werden zu `YEAR`-Werten in den Bereichen `2001` bis `2069` bzw. `1970` bis `1999` konvertiert. Beachten Sie, dass sich der Bereich der zweistelligen Zahlen leicht von dem der zweistelligen Strings unterscheidet, da Sie Null nicht direkt als Zahl angeben und als `2000` interpretieren lassen können. Die Angabe muss vielmehr als String `'0'` oder `'00'` erfolgen, andernfalls wird sie als `0000` interpretiert.

- Als Ergebnis einer Funktion, die einen Wert zurückgibt, der im Kontext von `YEAR` sinngebend ist, z. B. `NOW()`.

Unzulässige `YEAR`-Werte werden zu `0000` konvertiert.

### 11.3.4. Jahr-2000-Probleme und Datumstypen

Wie in Abschnitt 1.4.5, „Jahr-2000-Konformität“, beschrieben, ist MySQL selbst Jahr-2000-sicher; bestimmte Werte, die in MySQL eingegeben werden, sind es jedoch unter Umständen nicht. Jeder Wert, der eine zweistellige Jahresangabe enthält, ist mehrdeutig, da das Jahrhundert unbekannt ist. Solche Werte müssen in das vierstellige Format umgesetzt werden, da MySQL Jahreszahlen intern vierstellig speichert.

Bei den Typen `DATETIME`, `DATE`, `TIMESTAMP` und `YEAR` interpretiert MySQL nicht eindeutige Jahreszahlen entsprechend den folgenden Regeln:

- Jahreszahlen im Bereich zwischen 00 und 69 werden als `2000-2069` interpretiert.

- Jahreszahlen im Bereich zwischen 70 und 99 werden als `1970-1999` interpretiert.

Denken Sie daran, dass diese Regeln nur heuristischer Natur sind und sinnvoll zu erschließen versuchen, was Ihr Datenwert bedeuten könnte. Wenn die von MySQL verwendeten Regeln keine korrekten Werte erzeugen, sollten Sie eindeutige Angaben mit vierstelligen Jahreszahlen machen.

`ORDER BY` sortiert zweistellige `YEAR`-Werte wie erwartet.

Einige Funktionen wie `MIN()` und `MAX()` konvertieren einen `YEAR`-Wert in eine Zahl. Das bedeutet, dass ein Wert mit einer zweistelligen Jahresangabe für diese Funktionen ungeeignet ist. Dieses Problem beheben Sie, indem Sie den `TIMESTAMP`- oder `YEAR`-Wert in das vierstellige Jahresformat konvertieren.

## 11.4. String-Typen

Es gibt die folgenden String-Datentypen: `CHAR`, `VARCHAR`, `BINARY`, `VARBINARY`, `BLOB`, `TEXT`, `ENUM` und `SET`. In diesem Abschnitt wird erläutert, wie diese Typen funktionieren und wie Sie sie in Ihren Abfragen verwenden. Informationen zu den Speicheranforderungen von String-Typen finden Sie in Abschnitt 11.5, „Speicherbedarf von Spaltentypen“.

### 11.4.1. Die `CHAR`- und `VARCHAR`-Typen

Die Typen `CHAR` und `VARCHAR` ähneln einander, werden aber auf unterschiedliche Weise gespeichert und abgerufen. Weitere Unterschiede sind die maximale Länge und die Behandlung von Leerzeichen am String-Ende. Beim Speichern und Abrufen solcher Werte erfolgt keine Wandlung der Groß-/Kleinschreibung.

Die Typen `CHAR` und `VARCHAR` werden unter Angabe einer Länge deklariert, die die maximale Anzahl von Zeichen spezifiziert, die gespeichert werden kann. So kann ein `CHAR(30)`-Wert beispielsweise 30 Zeichen aufnehmen.

Die Länge einer `CHAR`-Spalte ist auf den von Ihnen beim Anlegen der Tabelle deklarierten Wert beschränkt. Dieser kann zwischen 0 und 255 liegen. Wenn `CHAR`-Werte gespeichert werden, dann werden sie nach rechts mit Leerzeichen bis auf die angegebene Länge aufgefüllt. Beim Abrufen von `CHAR`-Werten werden die am Ende stehenden Leerzeichen dann entfernt.

Werte in `VARCHAR`-Spalten sind Strings variabler Länge. Diese kann zwischen 0 und 65.535 liegen. (Die effektive Maximallänge einer `VARCHAR`-Spalte wird durch die maximale Datensatzgröße und den verwendeten Zeichensatz bestimmt. Die gesamte Maximallänge liegt bei 65.532 Byte.)

Im Gegensatz zu `CHAR`- werden `VARCHAR`-Werte nur mit so vielen Zeichen wie erforderlich zuzüglich eines Bytes gespeichert, welches die Länge angibt (bei Spalten, die mit einer Länge größer 255 deklariert sind, werden hierfür 2 Byte verwendet).

`VARCHAR`-Werte werden beim Speichern nicht aufgefüllt. Ferner werden am Ende stehende Leerzeichen entsprechend dem SQL-Standard beim Speichern und Abrufen beibehalten.

Wenn Sie einer `CHAR`- oder `VARCHAR`-Spalte einen Wert zuweisen, der die deklarierte Länge der Spalte überschreitet, dann wird der Wert so weit gekürzt, bis er passend ist. Handelt es sich bei den abgeschnittenen Zeichen nicht um Leerzeichen, dann wird eine Warnung erzeugt. Wenn Sie den strikten SQL-Modus verwenden, erscheint beim Abschneiden von anderen Zeichen als Leerzeichen eine Fehlermeldung (statt einer Warnung), und der Wert wird nicht eingefügt. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

Die folgende Tabelle veranschaulicht die Unterschiede zwischen den Typen `CHAR` und `VARCHAR`. Hierzu wird das jeweilige Ergebnis der Speicherung verschiedener String-Werte in `CHAR(4)`- und `VARCHAR(4)`-Spalten angezeigt:

Wert | `CHAR(4)` | Erforderlicher Speicherplatz | `VARCHAR(4)` | Erforderlicher Speicherplatz
`''` | `' '` | 4 Byte | `''` | 1 Byte
`'ab'` | `'ab '` | 4 Byte | `'ab '` | 3 Byte
`'abcd'` | `'abcd'` | 4 Byte | `'abcd'` | 5 Byte
`'abcdefgh'` | `'abcd'` | 4 Byte | `'abcd'` | 5 Byte

Beachten Sie, dass die in der letzten Zeile der Tabelle gezeigten Werte nur gelten, wenn der strikte Modus nicht verwendet wird; wird MySQL hingegen im strikten Modus ausgeführt, dann werden Werte, die die Spaltenlänge überschreiten, nicht gespeichert, und ein Fehler wird ausgegeben.

Wird ein gegebener Wert in die Spalten `CHAR(4)` und `VARCHAR(4)` gespeichert, dann sind die aus den Spalten abgerufenen Werte nicht immer identisch, weil in `CHAR`-Spalten am Ende stehende Leerzeichen beim Abrufen entfernt werden. Das folgende Beispiel veranschaulicht diesen Unterschied:

    mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
    Query OK, 0 rows affected (0.01 sec)

    mysql> INSERT INTO vc VALUES ('ab  ', 'ab  ');
    Query OK, 1 row affected (0.00 sec)

    mysql> SELECT CONCAT('(', v, ')'), CONCAT('(', c, ')') FROM vc;
    +---------------------+---------------------+
    | CONCAT('(', v, ')') | CONCAT('(', c, ')') |
    +---------------------+---------------------+
    | (ab  )              | (ab)                |
    +---------------------+---------------------+
    1 row in set (0.06 sec)

Werte in `CHAR`- und `VARCHAR`-Spalten werden entsprechend der zeichensatzspezifischen Sortierungsweise, die der Spalte zugewiesen ist, sortiert und verglichen.

Beachten Sie, dass alle MySQL-Sortierungen vom Typ `PADSPACE` sind, d. h. alle `CHAR`- und `VARCHAR`-Werte in MySQL werden ohne Berücksichtigung der am Ende stehenden Leerzeichen verglichen. Zum Beispiel:

    mysql> CREATE TABLE names (myname CHAR(10), yourname VARCHAR(10));
    Query OK, 0 rows affected (0.09 sec)

    mysql> INSERT INTO names VALUES ('Monty ', 'Monty ');
    Query OK, 1 row affected (0.00 sec)

    mysql> SELECT myname = 'Monty  ', yourname = 'Monty  ' FROM names;
    +--------------------+----------------------+
    | myname = 'Monty  ' | yourname = 'Monty  ' |
    +--------------------+----------------------+
    |                  1 |                    1 |
    +--------------------+----------------------+
    1 row in set (0.00 sec)

Dies gilt für alle MySQL-Versionen ungeachtet des gewählten SQL-Modus.

Bei solchen Fällen, in denen Leerzeichen am Ende entfernt werden oder Vergleiche diese ignorieren, hat, wenn eine Spalte einen Index hat, der eindeutige Werte erfordert, das Einfügen von Werten, die sich nur durch die Anzahl am Ende stehender Füllleerzeichen unterscheiden, eine Fehlermeldung bezüglich einer Schlüsseldublette zur Folge. Wenn beispielsweise eine Tabelle den Wert `'a'` enthält, wird diese Fehlermeldung erzeugt, sobald Sie versuchen, `'a '` zu speichern.

### 11.4.2. Die `BINARY`- und `VARBINARY`-Typen

Die Typen `BINARY` und `VARBINARY` ähneln `CHAR` bzw. `VARCHAR`. Der Unterschied besteht darin, dass diese beiden Typen binäre (statt nichtbinärer) Strings speichern, d. h., sie enthalten byte- statt zeichenbasierter Strings. Diese Datentypen haben aufgrund dessen keinen Zeichensatz: Sortierung und Vergleiche basieren in diesem Fall auf den numerischen Werten der Bytes in den Werten.

Die zulässige Maximallänge von `BINARY` und `VARBINARY` entspricht der von `CHAR` bzw. `VARCHAR`, nur wird die Länge von `BINARY` und `VARBINARY` in Bytes statt in Zeichen angegeben.

Die Datentypen `BINARY` und `VARBINARY` sind nicht identisch mit den Typen `CHAR BINARY` und `VARCHAR BINARY` Bei Letzteren hat das Attribut `BINARY` nicht zur Folge, dass die Spalte als binäre String-Spalte behandelt wird. Stattdessen aktiviert sie die binäre Sortierung für den Spaltenzeichensatz, und die Spalte selbst enthält nichtbinäre zeichenbasierte Strings statt binärer bytebasierter Strings. So wird beispielsweise `CHAR(5) BINARY` als `CHAR(5) CHARACTER SET latin1 COLLATE latin1_bin` behandelt (vorausgesetzt, der Standardzeichensatz ist `latin1`). Hier liegt ein Unterschied zu `BINARY(5)` vor, das binäre Strings mit einer Länge von 5 Byte speichert, für die kein Zeichensatz und keine Sortierung definiert sind.

Wenn `BINARY`-Werte gespeichert werden, werden sie nach rechts hin mit dem Füllwert auf die gewünschte Länge aufgefüllt. Der Füllwert ist `0x00` (das Nullbyte). Beim Einfügen werden Werte nach rechts hin mit `0x00` aufgefüllt, und beim Auswählen werden am Ende stehende Nullbytes nicht entfernt. Alle Bytes werden in Vergleichen (einschließlich `ORDER BY`- und `DISTINCT`-Operationen) berücksichtigt. `0x00`-Bytes und Leerzeichen sind in Vergleichen unterschiedlich, wobei `0x00` einen kleineren Wert als das Leerzeichen hat.

Beispiel: Bei einer `BINARY(3)`-Spalte wird `'a '` beim Einfügen zu `'a \0'`. `'a\0'` wird beim Einfügen zu `'a\0\0'`. Bei der Auswahl bleiben die gewählten Werte unverändert.

Bei `VARBINARY` werden weder beim Einfügen Füllbytes angehängt noch bei der Auswahl Bytes abgeschnitten. Alle Bytes werden in Vergleichen (einschließlich `ORDER BY`- und `DISTINCT`-Operationen) berücksichtigt. `0x00`-Bytes und Leerzeichen sind in Vergleichen unterschiedlich, wobei `0x00` einen kleineren Wert als das Leerzeichen hat.

Bei solchen Fällen, in denen Füllbytes am Ende entfernt werden oder Vergleiche diese ignorieren, hat, wenn eine Spalte einen Index hat, der eindeutige Werte erfordert, das Einfügen von Werten, die sich nur durch die Anzahl am Ende stehender Füllbytes unterscheiden, eine Fehlermeldung bezüglich einer Schlüsseldublette zur Folge. Wenn beispielsweise eine Tabelle den Wert `'a'` enthält, wird diese Fehlermeldung erzeugt, sobald Sie versuchen, `'a\0'` zu speichern.

Wenn Sie den Datentyp `BINARY` zur Speicherung binärer Daten verwenden wollen und es wichtig ist, dass der abgerufene mit dem zuvor gespeicherten Wert vollständig identisch ist, dann sollten Sie die beschriebenen Merkmale zum Auffüllen und Abschneiden sorgfältig lesen. Das folgende Beispiel veranschaulicht, wie sich das Auffüllen von `BINARY`-Werten mit `0x00` auf Vergleiche von Spaltenwerten auswirkt:

    mysql> CREATE TABLE t (c BINARY(3));
    Query OK, 0 rows affected (0.01 sec)

    mysql> INSERT INTO t SET c = 'a';
    Query OK, 1 row affected (0.01 sec)

    mysql> SELECT HEX(c), c = 'a', c = 'a\0\0' from t;
    +--------+---------+-------------+
    | HEX(c) | c = 'a' | c = 'a\0\0' |
    +--------+---------+-------------+
    | 610000 |       0 |           1 |
    +--------+---------+-------------+
    1 row in set (0.09 sec)

Wenn der abgerufene Wert mit dem zur Speicherung angegebenen Wert identisch sein muss, ohne dass aufgefüllt wird, dann sollten Sie unter Umständen besser `VARBINARY` oder einen der `BLOB`-Datentypen verwenden.

### 11.4.3. Die Spaltentypen `BLOB` und `TEXT`

Ein `BLOB` ist ein binäres großes Objekt, welches eine variable Menge von Daten aufnehmen kann. Die vier `BLOB`-Typen sind `TINYBLOB`, `BLOB`, `MEDIUMBLOB` und `LONGBLOB`. Sie unterscheiden sich lediglich in der maximalen Länge der Werte, die sie aufnehmen können. Die vier `TEXT`-Typen sind `TINYTEXT`, `TEXT`, `MEDIUMTEXT` und `LONGTEXT`. Sie entsprechen den vier `BLOB`-Typen, d. h., sie haben dieselben Längenbeschränkungen und Speicheranforderungen. Siehe auch Abschnitt 11.5, „Speicherbedarf von Spaltentypen“. Beim Speichern und Abrufen von `TEXT`- und `BLOB`-Spalten erfolgt keine Wandlung der Groß-/Kleinschreibung.

`BLOB`-Spalten werden als binäre Strings (Byte-Strings) behandelt, `TEXT`-Spalten als nichtbinäre Strings (zeichenbasierte Strings). `BLOB`-Spalten haben keinen Zeichensatz, und die Sortierung basiert auf den numerischen Werten der Bytes in den Spaltenwerten; `TEXT`-Spalten hingegen haben einen Zeichensatz, dessen Sortierung auch bestimmt, wie die Werte sortiert und verglichen werden.

Wird eine `TEXT`-Spalte indiziert, dann werden Vergleiche von Indexeinträgen am Ende mit Leerzeichen aufgefüllt. Das bedeutet, dass, wenn der Index eindeutige Werte erfordert, Fehlermeldungen zu doppelt vorhandenen Schlüsseln auftreten werden, wenn sich Werte lediglich in der Anzahl der am Ende stehenden Leerzeichen unterscheiden. Wenn beispielsweise eine Tabelle den Wert `'a'` enthält, wird diese Fehlermeldung erzeugt, sobald Sie versuchen, `'a '` zu speichern. Für `BLOB`-Spalten trifft dies allerdings nicht zu.

Wenn Sie im strikten Modus einer `BLOB`- oder `TEXT`-Spalte einen Wert zuweisen, der die zulässige Länge des Datentyps überschreitet, dann wird der Wert so weit gekürzt, bis er passend ist. Handelt es sich bei den abgeschnittenen Zeichen nicht um Leerzeichen, dann wird eine Warnung erzeugt. Wenn Sie den strikten SQL-Modus verwenden, erscheint stattdessen eine Fehlermeldung, und der Wert wird nicht eingefügt. Siehe auch Abschnitt 5.2.5, „Der SQL-Modus des Servers“.

In vielerlei Hinsicht können Sie eine `BLOB`-Spalte als `VARBINARY`-Spalte betrachten, die beliebig groß sein kann. Ähnlich können Sie eine `TEXT`-Spalte auch als `VARCHAR`-Spalte betrachten. `BLOB` und `TEXT` unterscheiden sich wie folgt von `VARBINARY` bzw. `VARCHAR`:

- Bei Indizes in `BLOB`- und `TEXT`-Spalten müssen Sie eine Länge für das Indexpräfix angeben. Bei `CHAR` und `VARCHAR` ist die Präfixlänge optional. Siehe auch Abschnitt 7.4.3, „Spaltenindizes“.

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

`LONG` und `LONG VARCHAR` lassen sich dem Datentyp `MEDIUMTEXT` zuordnen. Grund hierfür sind Kompatibilitätsaspekte. Wenn Sie das Attribut `BINARY` mit einem `TEXT`-Datentyp verwenden, wird der Spalte die binäre Sortierung des Spaltenzeichensatzes zugewiesen.

MySQL Connector/ODBC definiert `BLOB`-Werte als `LONGVARBINARY` und `TEXT`-Werte als `LONGVARCHAR`-Werte.

Da `BLOB`- und `TEXT`-Werte sehr lang sein können, können Sie bei ihrer Verwendung auf einige Einschränkungen treffen:

- Nur die ersten `max_sort_length` Bytes der Spalte werden zur Sortierung verwendet. Der Standardwert von `max_sort_length` beträgt 1024. Dieser Wert kann mithilfe der Option `--max_sort_length=`N`` beim Start des mysqld-Servers geändert werden. Siehe auch Abschnitt 5.2.2, „Server-Systemvariablen“.

  Sie können die Berücksichtigung von mehr Bytes bei der Sortierung oder Gruppierung implementieren, indem Sie den Wert von `max_sort_length` zur Laufzeit erhöhen. Jeder Client kann den Wert für seine Sitzungsvariable `max_sort_length` selbst ändern:

      mysql> SET max_sort_length = 2000;
      mysql> SELECT id, comment FROM t
          -> ORDER BY comment;

  Eine andere Möglichkeit, `GROUP BY` oder `ORDER BY` für eine `BLOB`- oder `TEXT`-Spalte, die lange Werte enthält, zu verwenden und dabei mehr als die mit `max_sort_length` angegebene Anzahl von Bytes zu berücksichtigen, besteht darin, den Spaltenwert in ein Objekt fester Länge zu konvertieren. Standardmäßig erfolgt eine solche Konvertierung mit der Funktion `SUBSTRING`. Die folgende Anweisung beispielsweise hat die Berücksichtigung von 2000 Byte in der Spalte `comment` für die Sortierung zur Folge:

      mysql> SELECT id, SUBSTRING(comment,1,2000) FROM t
          -> ORDER BY SUBSTRING(comment,1,2000);

- Die maximale Größe eines `BLOB`- oder `TEXT`-Objekts ist durch seinen Typ bestimmt. Der größte Wert jedoch, den Sie tatsächlich zwischen Client und Server übertragen können, wird durch die Menge des verfügbaren Speichers und die Größe der Kommunikationspuffer festgelegt. Sie können die Größe des Meldungspuffers ändern, indem Sie der Variablen `max_allowed_packet` einen anderen Wert zuweisen. Dies muss allerdings sowohl für den Server als auch für Ihr Clientprogramm erfolgen. So können Sie etwa sowohl mit mysql als auch mit mysqldump den `max_allowed_packet`-Wert auf der Clientseite verändern. Siehe auch Abschnitt 7.5.2, „Serverparameter feineinstellen“, Abschnitt 8.5, „mysql — Das MySQL-Befehlszeilenwerkzeug mysql“ und Abschnitt 8.10, „mysqldump — Programm zur Datensicherung“.

Jeder `BLOB`- und `TEXT`-Wert wird intern durch ein separat reserviertes Objekt dargestellt. Dies steht im Gegensatz zu allen anderen Datentypen, für die der Speicherplatz pro Spalte genau einmal beim Öffnen der Tabelle reserviert wird.

In manchen Fällen kann es wünschenswert sein, Binärdaten wie Mediendateien in `BLOB`- oder `TEXT`-Spalten zu speichern. Beim Umgang mit solchen Daten können sich die MySQL-Funktionen zur String-Verarbeitung als recht praktisch erweisen. Siehe auch Abschnitt 12.3, „String-Funktionen“. Aus Sicherheits- und anderen Gründen empfiehlt es sich in der Regel, dies im Anwendungscode zu tun, statt Benutzern der Anwendung die Berechtigung `FILE` zu gewähren. Details zu Sprachen und Plattformen können Sie in den MySQL-Foren (http://forums.mysql.com/) diskutieren.

### 11.4.4. Der Spaltentyp `ENUM`

Der Datentyp `ENUM` ist ein String-Objekt mit einem Wert, der aus einer Liste zulässiger Werte ausgewählt wird, die beim Erstellen der Tabelle explizit in der Spaltendefinition aufgelistet werden.

Als Werte kommen unter bestimmten Umständen auch der Leer-String (`''`) oder `NULL` in Frage:

- Wenn Sie einen ungültigen Wert (d. h. einen String, der nicht in der Liste zulässiger Werte vorhanden ist) in eine `ENUM`-Spalte einzufügen versuchen, dann wird stattdessen als spezieller Fehlerwert der Leer-String eingefügt. Dieser String lässt sich von einem „normalen“ leeren String dadurch unterscheiden, dass er den numerischen Wert 0 hat. Weitere Informationen hierzu folgen weiter unten.

  Wenn der strikte SQL-Modus aktiviert ist, führen Versuche, ungültige `ENUM`-Werte einzufügen, zu einer Fehlermeldung.

- Wird für eine `ENUM`-Spalte die Zulässigkeit von `NULL` deklariert, dann ist der `NULL`-Wert für die Spalte erlaubt. Ferner ist in diesem Fall auch der Standardwert `NULL`. Wenn eine `ENUM`-Spalte als `NOT NULL` deklariert wird, dann wird als Vorgabe das erste Element der Liste zulässiger Werte verwendet.

Jeder Wert in der Auflistung hat einen Index:

- Werte aus der Liste zulässiger Elemente in der Spaltenspezifikation werden beginnend mit 1 nummeriert.

- Der Indexwert des als Fehlerwert verwendeten Leer-Strings ist 0. Sie können also folgende `SELECT`-Anweisung verwenden, um Datensätze zu ermitteln, bei denen ungültige `ENUM`-Werte zugewiesen wurden:

      mysql> SELECT * FROM tbl_name WHERE enum_col=0;

- Der Indexwert des `NULL`-Werts ist `NULL`.

- Der Begriff „Index“ bezeichnet in diesem Kontext nur die Position innerhalb der Auflistung möglicher Werte. Es gibt keine Verbindung zu Tabellenindizes.

Eine Spalte, die als `ENUM('one', 'two', 'three')` definiert ist, kann jeden der nachfolgend angegebenen Werte annehmen. Auch die Indizes der einzelnen Werte werden angezeigt:

Wert | Index
`NULL` | `NULL`
`''` | 0
`'one'` | 1
`'two'` | 2
`'three'` | 3

Eine Auflistung darf maximal 65.535 Elemente enthalten.

Beim Erstellen der Tabelle werden bei `ENUM`-Mitgliedswerten am Ende stehende Leerzeichen in der Tabellendefinition automatisch entfernt.

Beim Abrufen werden Werte, die in einer `ENUM`-Spalte gespeichert sind, in der Groß-/Kleinschreibung angezeigt, die bei der Spaltendefinition verwendet wurde. Beachten Sie, dass `ENUM`-Spalten ein Zeichensatz und eine Sortierung zugewiesen werden können. Bei binären Sortierungen oder solchen, bei denen die Groß-/Kleinschreibung unterschieden wird, wird die Schreibweise beim Zuweisen von Werten zur Spalte berücksichtigt.

Wenn Sie einen `ENUM`-Wert in einem numerischen Kontext abrufen, wird der Index des Spaltenwerts zurückgegeben. So können Sie beispielsweise numerische Werte wie folgt aus einer `ENUM`-Spalte abrufen:

    mysql> SELECT enum_col+0 FROM tbl_name;

Wenn Sie eine Zahl in einer `ENUM`-Spalte ablegen, wird diese als Index behandelt, und der mit diesem Index verknüpfte Mitgliedswert wird in der Spalte gespeichert. (Allerdings funktioniert dies nicht bei `LOAD DATA`, weil diese Anweisung alle Eingaben als Strings behandelt.) Es ist nicht ratsam, eine `ENUM`-Spalte mit Auflistungswerten zu definieren, die wie Zahlen aussehen, da dies schnell zu Verwirrung führen kann. So hat beispielsweise die folgende Spalte Auflistungswerte mit den String-Werten `'0'`, `'1'` und `'2'`, aber die numerischen Indexwerte `1`, `2` und `3`:

    numbers ENUM('0','1','2')

`ENUM`-Werte werden entsprechend der Reihenfolge sortiert, in der sie in der Spaltendefinition aufgeführt wurden. (Anders gesagt: `ENUM`-Werte werden nach ihren Indexzahlen sortiert.) So wird beispielsweise bei `ENUM('a', 'b')` `'a'` vor `'b'` einsortiert, bei `ENUM('b', 'a')` hingegen wird `'b'` vor `'a'` einsortiert. Der Leer-String wird immer vor nichtleeren Strings einsortiert, und `NULL`-Werte werden vor allen anderen Auflistungswerten einsortiert. Um unerwünschte Ergebnisse zu vermeiden, geben Sie die `ENUM`-Liste am besten in alphabetischer Reihenfolge an. Sie können auch mit `GROUP BY CAST(col AS CHAR)` oder `GROUP BY CONCAT(col)` sicherstellen, dass die Spalte lexikalisch statt nach Indexnummer sortiert wird.

Wenn Sie alle möglichen Werte für eine `ENUM`-Spalte bestimmen wollen, verwenden Sie `SHOW COLUMNS FROM `tbl_name` LIKE `enum_col`` und verarbeiten die `ENUM`-Definition in der Spalte `Type` der Ausgabe.

### 11.4.5. Der Spaltentyp `SET`

Der Datentyp `SET` (Menge) ist ein String-Objekt, das null oder mehr Werte haben kann. Alle diese Werte entstammen einer Liste zulässiger Werte, die beim Erstellen der Tabelle angegeben werden. Bei `SET`-Spaltenwerten, die mehrere Mitglieder der Menge umfassen, werden die Mitgliedswerte durch Kommata (‘`,`’) getrennt angegeben. Hieraus ergibt sich, dass `SET`-Mitgliedswerte ihrerseits keine Kommata enthalten sollten.

Eine Spalte, die als `SET('one', 'two') NOT NULL` definiert ist, kann jeden der folgenden Werte annehmen:

    ''
    'one'
    'two'
    'one,two'

Ein `SET` kann maximal 64 Mitgliedswerte umfassen.

Beim Erstellen der Tabelle werden bei `SET`-Mitgliedswerten am Ende stehende Leerzeichen in der Tabellendefinition automatisch entfernt.

Beim Abrufen werden Werte, die in einer `SET`-Spalte gespeichert sind, in der Groß-/Kleinschreibung angezeigt, die bei der Spaltendefinition verwendet wurde. Beachten Sie, dass `SET`-Spalten ein Zeichensatz und eine Sortierung zugewiesen werden können. Bei binären Sortierungen oder solchen, bei denen die Groß-/Kleinschreibung unterschieden wird, wird die Schreibweise beim Zuweisen von Werten zur Spalte berücksichtigt.

MySQL speichert `SET`-Werte numerisch, wobei das niederwertige Bit des gespeicherten Werts dem ersten Mitgliedswert der Menge entspricht. Wenn Sie einen `SET`-Wert in einem numerischen Kontext abrufen, sind die Bits dieses Werts entsprechend den Mitgliedswerten der Menge gesetzt, die den Spaltenwert bilden. So können Sie beispielsweise numerische Werte wie folgt aus einer `SET`-Spalte abrufen:

    mysql> SELECT set_col+0 FROM tbl_name;

Wenn eine Zahl in einer `SET`-Spalte gespeichert wird, bestimmen die Bits, die in der Binärform der Zahl gesetzt sind, die im Spaltenwert vorhandenen Mitglieder. Bei einer Spalte, die als `SET('a','b','c','d')` definiert ist, haben die Mitglieder die folgenden Dezimal- und Binärwerte:

`SET` Mitgliedswert | Dezimalwert | Binärwert
`'a'` | `1` | `0001`
`'b'` | `2` | `0010`
`'c'` | `4` | `0100`
`'d'` | `8` | `1000`

Wenn Sie dieser Spalte den Wert `9` zuweisen, entspricht dies dem Binärwert `1001`, d. h., der erste und der vierte `SET`-Mitgliedswert (`'a'` und `'d'`) werden ausgewählt. Das Ergebnis lautet also `'a,d'`.

Bei einem Wert, der mehr als ein `SET`-Element enthält, spielt es keine Rolle, in welcher Reihenfolge die Elemente beim Einfügen des Werts aufgeführt sind. Ebenso wenig ist relevant, wie häufig ein gegebenes Element in der Liste auftaucht. Wenn der Wert später abgerufen wird, erscheint jedes Element des Werts genau einmal in der Liste, und diese ist in der Reihenfolge sortiert, in der die Mitglieder bei Erstellung der Tabelle aufgeführt wurden. Nehmen wir beispielsweise einmal an, eine Spalte sei als `SET('a','b','c','d')` definiert:

    mysql> CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));

Nun fügen Sie die Werte `'a,d'`, `'d,a'`, `'a,d,d'`, `'a,d,a'` und `'d,a,d'` ein:

    mysql> INSERT INTO myset (col) VALUES
    -> ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
    Query OK, 5 rows affected (0.01 sec)
    Records: 5  Duplicates: 0  Warnings: 0

Beim Abrufen erscheinen alle diese Werte als `'a,d'`:

    mysql> SELECT col FROM myset;
    +------+
    | col  |
    +------+
    | a,d  |
    | a,d  |
    | a,d  |
    | a,d  |
    | a,d  |
    +------+
    5 rows in set (0.04 sec)

Wenn Sie eine `SET`-Spalte auf einen nicht unterstützten Wert setzen, wird dieser ignoriert, und es wird eine Warnung ausgegeben:

    mysql> INSERT INTO myset (col) VALUES ('a,d,d,s');
    Query OK, 1 row affected, 1 warning (0.03 sec)

    mysql> SHOW WARNINGS;
    +---------+------+------------------------------------------+
    | Level   | Code | Message                                  |
    +---------+------+------------------------------------------+
    | Warning | 1265 | Data truncated for column 'col' at row 1 |
    +---------+------+------------------------------------------+
    1 row in set (0.04 sec)

    mysql> SELECT col FROM myset;
    +------+
    | col  |
    +------+
    | a,d  |
    | a,d  |
    | a,d  |
    | a,d  |
    | a,d  |
    | a,d  |
    +------+
    6 rows in set (0.01 sec)

Wenn der strikte SQL-Modus aktiviert ist, führen Versuche, ungültige `SET`-Werte einzufügen, zu einer Fehlermeldung.

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

Meist werden Sie `SET`-Werte mithilfe der Funktion `FIND_IN_SET()` oder des Operators `LIKE` durchsuchen:

    mysql> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;
    mysql> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';

Die erste Anweisung findet Datensätze, bei denen `set_col` den Mitgliedswert `value` enthält. Die zweite ist ähnlich, aber nicht identisch: Sie findet Datensätze, bei denen `set_col` `value` an beliebiger Stelle (auch als Teil-String eines anderen Mitglieds) enthält.

Die folgenden Anweisungen sind ebenfalls zulässig:

    mysql> SELECT * FROM tbl_name WHERE set_col & 1;
    mysql> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';

Die erste Anweisung sucht nach Werten, die das erste Mitglied der Menge enthalten. Die zweite sucht nach einer exakten Übereinstimmung. Seien Sie bei Vergleichen des zweiten Typs vorsichtig. Der Vergleich von Mengenwerten mit `'`val1`,`val2`'` gibt andere Resultate zurück als der Vergleich mit `'`val2`,`val1`'`. Sie sollten die Werte in derselben Reihenfolge angeben, in der sie in der Spaltendefinition aufgelistet sind.

Wenn Sie alle möglichen Werte für eine `SET`-Spalte bestimmen wollen, verwenden Sie `SHOW COLUMNS FROM `tbl_name` LIKE `set_col`` und verarbeiten die `SET`-Definition in der Spalte `Type` der Ausgabe.

## 11.5. Speicherbedarf von Spaltentypen

Die Speicheranforderungen der einzelnen von MySQL unterstützten Datentypen sind nachfolgend nach Kategorie sortiert aufgelistet.

Die maximale Größe eines Datensatzes in einer `MyISAM`-Tabelle beträgt 65.534 Byte. Jede `BLOB`- oder `TEXT`-Spalte trägt nur zwischen 5 und 9 Byte zu dieser Größe bei.

Speicheranforderungen für numerische Typen

Datentyp | Erforderlicher Speicherplatz
`TINYINT` | 1 Byte
`SMALLINT` | 2 Byte
`MEDIUMINT` | 3 Byte
`INT`, `INTEGER` | 4 Byte
`BIGINT` | 8 Byte
`FLOAT(`p`)` | 4 Byte, sofern 0 <= `p` <= 24; 8 Byte, sofern 25 <= `p` <= 53
`FLOAT` | 4 Byte
`DOUBLE [PRECISION]`, `REAL` | 8 Byte
`DECIMAL(`M`,`D`)`, `NUMERIC(`M`,`D`)` | Variiert (siehe nachfolgende Beschreibung)
`BIT(`M`)` | ca. (`M`+7) ÷ 8 Byte

Werte für `DECIMAL`-Spalten (und auch für `NUMERIC`-Spalten) werden in einem Binärformat dargestellt, das 9 Dezimalstellen (Basis 10) mit 4 Byte repräsentiert. Die Speicheranforderungen für ganzzahlige und Bruchteile eines Werts werden separat bestimmt. Jedes Vielfache von 9 Stellen erfordert 4 Byte, und die „restlichen“ Stellen erfordern einen Bruchteil von 4 Byte. Der für überzählige Stellen erforderliche Speicherplatz ist in der folgenden Tabelle angegeben:

Überzählige Stellen | Anzahl Bytes
0 | 0
1 | 1
2 | 1
3 | 2
4 | 2
5 | 3
6 | 3
7 | 4
8 | 4
9 | 4

Speicheranforderungen für Datums- und Uhrzeittypen

Datentyp | Erforderlicher Speicherplatz
`DATE` | 3 Byte
`DATETIME` | 8 Byte
`TIMESTAMP` | 4 Byte
`TIME` | 3 Byte
`YEAR` | 1 Byte

Speicheranforderungen für String-Typen

Datentyp | Erforderlicher Speicherplatz
`CHAR(`M`)` | ``M`` Bytes, 0 `<= `M` <=` 255
`VARCHAR(`M`)` | `L` + 1 Byte, wobei ``L` <= `M`` und 0 `<= `M` <=` 255 (siehe nachfolgender Hinweis) or `L` + 2 Byte, wobei ``L` <= `M`` und 256 `<= `M` <=` 65535 (siehe nachfolgender Hinweis)
`BINARY(`M`)` | ``M`` Bytes, 0 `<= `M` <=` 255
`VARBINARY(`M`)` | `L` + 1 Byte, wobei ``L` <= `M`` und 0 `<= `M` <=` 255 (siehe nachfolgender Hinweis) or `L` + 2 Byte, wobei ``L` <= `M`` und 256 `<= `M` <=` 65535 (siehe nachfolgender Hinweis)
`TINYBLOB`, `TINYTEXT` | `L`+1 Byte, wobei `L` < 28
`BLOB`, `TEXT` | `L`+2 Byte, wobei `L` < 216
`MEDIUMBLOB`, `MEDIUMTEXT` | `L`+3 Byte, wobei `L` < 224
`LONGBLOB`, `LONGTEXT` | `L`+4 Byte, wobei `L` < 232
`ENUM('`value1`','`value2`',...)` | 1 oder 2 Byte, abhängig von der Anzahl der Auflistungswerte (maximal 65.535)
`SET('`value1`','`value2`',...)` | 1, 2, 3, 4 oder 8 Byte, abhängig von der Anzahl der Mitglieder der Menge (maximal 64)

Bei den Typen `CHAR`, `VARCHAR` und `TEXT` sollten die Werte `L` und `M` in obiger Tabelle als Anzahl der Zeichen aufgefasst werden. Längen für diese Typen in der Spaltendefinition geben die Anzahl der Zeichen an. Um beispielsweise einen `TINYTEXT`-Wert zu speichern, benötigen Sie `L` Zeichen plus 1 Byte.

`VARCHAR` und die `VARBINARY`- und `BLOB`- und `TEXT`-Typen haben jeweils variable Längen. Bei ihnen hängen die Speicheranforderungen von den folgenden Faktoren ab:

- der tatsächlichen Länge des Spaltenwerts

- der maximal zulässigen Länge der Spalte

- dem für die Spalte verwendeten Zeichensatz

Eine `VARCHAR(10)`-Spalte beispielsweise kann einen String mit einer maximalen Länge von 10 aufnehmen. Wenn man voraussetzt, dass die Spalte den Zeichensatz `latin1` verwendet (bei dem jedes Zeichen durch 1 Byte dargestellt wird), dann entspricht die tatsächliche Speicheranforderung der Länge des Strings (`L`) zuzüglich eines Bytes zur Angabe der String-Länge. Beim String `'abcd'` ist `L` 4, und der Speicherbedarf beträgt 5 Byte. Wenn dieselbe Spalte stattdessen als `VARCHAR(500)` deklariert würde, dann benötigte der String `'abcd'` 4 + 2 = 6 Bytes. Es werden 2 Byte (statt nur eines) für das Präfix benötigt, da die Länge der Spalte größer als 255 Zeichen ist.

Um die Anzahl der Bytes zu berechnen, die zur Speicherung eines bestimmten `CHAR`-, `VARCHAR`- oder `TEXT`-Spaltenwerts benötigt werden, müssen Sie den Zeichensatz der betreffenden Spalte in Betracht ziehen. Dies gilt insbesondere bei Verwendung des `utf8`-Unicode-Zeichensatzes: Hierbei ist darauf zu achten, dass nicht alle `utf8`-Zeichen dieselbe Anzahl Bytes verwenden. Eine Auflistung der Speicheranforderungen verschiedener Kategorien von `utf8`-Zeichen finden Sie in Abschnitt 10.7, „Unicode-Unterstützung“.

Hinweis: Die effektive Maximallänge einer `VARCHAR`- oder `VARBINARY`-Spalte beträgt 65.532.

Die `NDBCLUSTER`-Speicher-Engine in MySQL 5.1 unterstützt echte Spalten variabler Breite. Das bedeutet, dass eine `VARCHAR`-Spalte in einer MySQL-Cluster-Tabelle dieselbe Menge Speicher benötigt, die sie bei Verwendung einer beliebigen anderen Speicher-Engine erfordern würde. Dieses Verhalten unterscheidet sich von dem früherer Versionen von `NDBCLUSTER`.

Die Typen `BLOB` und `TEXT` erfordern je nach maximal möglicher Länge des Datentyps 1 bis 4 Byte zur Aufnahme des Spaltenwerts. Siehe auch Abschnitt 11.4.3, „Die Spaltentypen `BLOB` und `TEXT`“.

`TEXT`- und `BLOB`-Spalten sind in der `NDBCLUSTER`-Speicher-Engine unterschiedlich implementiert. Dabei besteht jeder Datensatz in einer `TEXT`-Spalte aus zwei separaten Teilen. Der eine Teil hat eine feste Größe von 256 Byte und wird tatsächlich in der Ursprungstabelle gespeichert. Der andere besteht aus den Daten, die den Umfang von 256 Byte überschreiten. Diese werden in einer verborgenen Tabelle gespeichert. Die Datensätze in dieser zweiten Tabelle sind immer 2.000 Byte lang. Das bedeutet, dass die Größe einer `TEXT`-Spalte 256 beträgt, wenn `size` <= 256 (wobei `size` die Größe des Datensatzes darstellt); andernfalls beträgt die Größe 256 + `size` + (2000 – (`size` – 256) % 2000).

Die Größe eines `ENUM`-Objekts wird anhand der Anzahl verschiedener Auflistungswerte bestimmt. Ein Byte wird für Auflistungen mit bis zu 255 möglichen Werten benötigt. 2 Byte sind für Auflistungen erforderlich, die zwischen 256 und 65.535 mögliche Werte besitzen. Siehe auch Abschnitt 11.4.4, „Der Spaltentyp `ENUM`“.

Die Größe eines `SET`-Objekts wird anhand der Anzahl verschiedener Mitglieder der Menge bestimmt. Wenn die Größe der Menge `N` ist, dann benötigt das Objekt `(`N`+7)/8` Byte, gerundet auf 1, 2, 3, 4 oder 8 Byte. Ein `SET` kann maximal 64 Mitgliedswerte umfassen. Siehe auch Abschnitt 11.4.5, „Der Spaltentyp `SET`“.

## 11.6. Auswahl des richtigen Datentyps für eine Spalte

Um den Speicher optimal zu nutzen, sollten Sie in allen Fällen den geeignetsten Datentyp auswählen. Wird eine Integer-Spalte etwa für Werte im Bereich zwischen `1` und `99999` verwendet, dann ist `MEDIUMINT UNSIGNED` als Typ am besten geeignet. Von allen Typen, die alle erforderlichen Werte darstellen können, verwendet dieser Typ am wenigsten Speicher.

Berechnungen in den Grundrechenarten (`+,-,*,/`) erfolgen bei `DECIMAL`-Spalten stets mit einer Genauigkeit von 65 Dezimalstellen (Basis 10). Siehe auch Abschnitt 11.1.1, „Überblick über numerische Datentypen“.

Für Berechnungen mit `DECIMAL`-Werten werden Operationen mit doppelter Genauigkeit verwendet. Sofern die Genauigkeit nicht zu wichtig ist oder Geschwindigkeit die höchste Priorität hat, kann der Typ `DOUBLE` unter Umständen ausreichend sein. Für eine hohe Genauigkeit können Sie jederzeit eine Konvertierung in einen Festkommatyp durchführen, der als `BIGINT` gespeichert wird. Dies ermöglicht Ihnen die Durchführung aller Berechnungen mit 64-Bit-Integers und nachfolgend ggf. die Rückkonvertierung der Ergebnisse in Fließkommawerte.

## 11.7. Verwendung von Datentypen anderer Datenbanken

Um die Verwendung von Code zu erleichtern, den andere Anbieter für SQL-Implementierungen geschrieben haben, ordnet MySQL Datentypen entsprechend der folgenden Tabelle zu. Diese Zuordnungen vereinfachen den Import von Tabellendefinitionen aus anderen Datenbanksystemen in MySQL:

Datentyp bei anderem Anbieter | Typ bei MySQL
`BOOL`, | `TINYINT`
`BOOLEAN` | `TINYINT`
`CHAR VARYING(`M`)` | `VARCHAR(`M`)`
`DEC` | `DECIMAL`
`FIXED` | `DECIMAL`
`FLOAT4` | `FLOAT`
`FLOAT8` | `DOUBLE`
`INT1` | `TINYINT`
`INT2` | `SMALLINT`
`INT3` | `MEDIUMINT`
`INT4` | `INT`
`INT8` | `BIGINT`
`LONG VARBINARY` | `MEDIUMBLOB`
`LONG VARCHAR` | `MEDIUMTEXT`
`LONG` | `MEDIUMTEXT`
`MIDDLEINT` | `MEDIUMINT`
`NUMERIC` | `DECIMAL`

Die Datentypzuordnung erfolgt zum Zeitpunkt der Tabellenerstellung. Nachfolgend werden die ursprünglichen Typenspezifikationen verworfen. Wenn Sie eine Tabelle mit von anderen Anbietern verwendeten Typen erstellen und dann eine `DESCRIBE `tbl_name``-Anweisung absetzen, meldet MySQL die Tabellenstruktur unter Verwendung der gleichwertigen MySQL-Typen. Zum Beispiel:

    mysql> CREATE TABLE t (a BOOL, b FLOAT8, c LONG VARCHAR, d NUMERIC);
    Query OK, 0 rows affected (0.00 sec)

    mysql> DESCRIBE t;
    +-------+---------------+------+-----+---------+-------+
    | Field | Type          | Null | Key | Default | Extra |
    +-------+---------------+------+-----+---------+-------+
    | a     | tinyint(1)    | YES  |     | NULL    |       |
    | b     | double        | YES  |     | NULL    |       |
    | c     | mediumtext    | YES  |     | NULL    |       |
    | d     | decimal(10,0) | YES  |     | NULL    |       |
    +-------+---------------+------+-----+---------+-------+
    4 rows in set (0.01 sec)

Dies ist eine Übersetzung des MySQL-Referenzhandbuchs, das sich auf dev.mysql.com befindet. Das ursprüngliche Referenzhandbuch ist auf Englisch, und diese Übersetzung ist nicht notwendigerweise so aktuell wie die englische Ausgabe. Das vorliegende deutschsprachige Handbuch behandelt MySQL bis zur Version 5.1.

Zurück |  | Weiter
Kapitel 10. Zeichensatz-Unterstützung | Zum Anfang | Kapitel 12. Funktionen für die Benutzung in `SELECT`- und `WHERE`-Klauseln