Advanced MySQL - Referentielle Integrität - Der Strict-Modus
1. Toleranz
... ist eigentlich eine schöne Sache, so lange man es nicht übertreibt. Nur leider macht MySQL genau das, wenn es um eigentlich
fehlerhafte Eingaben geht. Da wird bei einem Feld vom Typ INT
aus einem 345a2
ein 345
. Und
wenn man ein falsches Datumsformat angibt, so wandelt das MySQL in 0000-00-00
um. Und das kann dann schon mal
für ziemliche Verwirrung sorgen.
2. Die Lösung
... ist der so genannte Strict-Modus. Wenn man den einschaltet, werden Fehler wie oben beschrieben nicht ausgeführt und es fliegt uns eine entsprechende Meldung um die Ohren.
Konfiguration
Dafür gibt es drei Möglichkeiten.
- Start des Servers mit der Option
--sql-mode="modus"
- In der
my.ini
odermy.cnf
mit dem Eintragsql-mode="modus"
- Über einen Query mittels
SET sql_mode='modus'
Bei letzterer Variante muss man unterscheiden zwischen GLOBAL
(gilt für alle Clients) und SESSION
(gilt
nur für den Client, der die Abfrage sendet).
Dauerhaftigkeit
Das kann man sich sicher denken. Bei den ersten beiden Varianten wird der Modus automatisch beim Start des MySQL-Servers aktiviert.
Bei Letzterer verfallen die Einstellungen, wenn der Client die Verbindung unterbricht (SESSION
) oder der Server abraucht.
3. Die Hauptmodi
Konzentrieren wir uns zunächst auf die drei wichtigsten. Denn mit denen kann man schon (fast) alles erschlagen.
STRICT_ALL_TABLES
Hier wird für alle Tabellen der Strict-Modus aktiviert. Sobald man versucht, einen falschen Wert in eine Tabelle zu schreiben, wird der Vorgang abgebrochen.
STRICT_TRANS_TABLES
Wirkt sich wirklich sicher nur auf transaktionssichere Tabellen wie InnoDB aus. Bei den anderen wird es versucht(!). Im
Gegensatz zu STRICT_ALL_TABLES
erfolgt noch ein komplettes Rollback (dazu später mehr).
TRADITIONAL
In diesem Modus verhält sich MySQL wie ein "traditionelles" RDMS. Anstelle eines Warnhinweises wird eine Fehlermeldung ausgegeben.
4. Weitere Modi
Davon gibt es eine ziemliche Latte. Ich stelle hier mal die wirklich Sinnvollen vor. Eine komplette Liste gibt es hier.
ERROR_FOR_DIVISION_BY_ZERO
Hier wird bei einem Teilen durch Null eine Fehlermeldung ausgegeben.
IGNORE_SPACE
Erlaubt Leerzeichen zwischen einer Funktion der folgenden öffnenden Klammer.
NO_ZERO_DATE
Hier wird 0000-00-00
nicht als gültiges Datum angesehen.
NO_ZERO_IN_DATE
Lässt keine einzelnen Nullangaben zu, also zum Beispiel 2011-08-00
.
5. Kombinationen
Je nachdem, was man alles abfangen möchte, muss man die einzelnen Modi kombinieren. So lässt zum Beispiel STRICT_ALL_TABLES
das Nulldatum (0000-00-00) zu. Um das zu verhindern, benötigt man NO_ZERO_DATE
. Aber da kann man immer noch Nullangaben
in das Datum setzen. Um auch das abzuklemmen bedarf es eines NO_ZERO_IN_DATE
.
SET sql_mode='STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE';
Wichtig
Wenn man mehrere Modi kombiniert, so werden sie durch ein Komma getrennt. Es darf aber kein Leerzeichen verwendet werden!
6. Weitere Infos
Will man den aktuellen Status der Modi abfragen, so geschieht das mit folgendem Query. Den Unterschied zwischen session
und global
habe ich ja oben schon erklärt.
SELECT @@global.sql_mode;
SELECT @@session.sql_mode;
Wenn man dagegen wieder den Gammelmodus aktivieren möchte, so geschieht das mit
SET sql_mode='';
Ein Hinweis
Da es hier nur um grundsätzliche Dinge geht, werde ich auf die Feinheiten in einem kommenden Tutorial eingehen.
zurück zum vorherigen Abschnitt weiter zum nächsten Abschnitt