MySQL Tabellen-Optimierung: Der optimale Datentyp

Hand aufs Herz: Wieviel Zeit invenstieren Sie vor dem Anlegen der ersten Datenbank-Tabelle in das optimale Tabellendesign? Ich hoffe viel, denn durch das richtige Design, die richtig gewählten Dateitypen und letztlich die richtigen Indizes lassen sich die Größe einer Datenbank minimieren und die Abfragen massiv beschleunigen.

Doch meistens ist das folgende Bild eher an der Tagesordnung. Man legt die erste Tabelle an, füllt die mit Testdaten und programmiert die Anwendung. Es kommen Spalten hinzu, manche werden gelöscht, umbenannt und viele schlichtweg vergessen. Später scheut man sich, das Datenbankdesign noch einmal zu überarbeiten, da man froh ist, dass die Anwendung läuft und man keine Zeit mehr investieren möchte.

Doch wenn die Größe der Datenbanktabelle wächst, wird man von der Realität eingeholt. Es rächt sich mit steigender Datenbankgröße, wenn man das Design vernachlässigt hat. Wer nicht ständig die programminternen Datenbankabfragen auf das Vorhandensein eines optimalen Index prüft, wird schnell Schiffbruch erleiden. Und wer zu großzügig mit Datentypen umgeht, wir schnell unnötigen Plattenplatz belegen und seine Datenbank aufgrund der Größe der Tabellen verlangsamen.

Gerade bei den numerischen Datentypen ist es unumgänglich, den „besten“ Datentyp für ein Feld zu wählen. Es gilt immer: Man wählen den kleinsten Datentyp, der für das Feld ausreicht. Wählt man einen zu großen Datentyp, belegt dieser nur unnötiger Weise Speicherplatz. Bremst unter Umständen sogar die Datenbank. Daher ist es wichtig zu wissen, welche maximale Werte ein numerischer Datentyp unter MySQL annehmen kann.

Unten aufgeführt habe ich die gängigen Datentypen (nicht vollständig!) aufgeführt und gebe Tipps für die Verwendung. Eine detaillierte Aufstellung kann in der MySQL-Doku nachgelesen werden.

  • TINYINT: Nimmt Werte zwischen 0 bis255 oder -128 bis 127 auf. Optimal für die ID von kleinen Tabellen (maximal 255 Einträge) oder Status-Felder.
  • SMALLINT: Nimmt Werte zwischen 0 bis 65.535 oder -32.768 bis 32.767 auf. Langt bereits als Datentyp für die ID-Spalte vieler Tabellen.
  • MEDIUMINT: Nimmt Werte zwischen 0 bis 16.777.215 oder -8.388.608 bis 8.838.607 auf. Optimaler Wert für ID-Felder im „kleinen“ Millionenbereich.
  • INT: Nimmt Werte zwischen 0 und 4.294.967.295 oder -2.147.438.648 und 2.147.483.647 auf. Im Gegensatz zu anderen Datenbanken ist der Integer bei MySQL schon sehr, sehr mächtig. Für viele Felder ist dieser bereits schon überdimensioniert und sollte durch einen kleineren Datentyp ersetzt werden.
  • BIGINT: Nimmt Werte zwischen 0 und 18.446.744.073.709.551.615 oder -9.223.372.036.854.775.808 und 9.223.372.036.854.775.807 auf. Gerade Umsteiger von anderen Datenbanksystemen wählen gerne das „große INT“ für die ID einer stark wachsenden Tabelle. Doch unter MySQL ist der der Integer bereits groß genug für die meisten Tabellen.

Speicherplatzbedarf von nummerischen Daten-Typen
Warum wir nur den kleinsten Datensatztyp wählen sollten, der wirklich benötigt wird, zeigt die folgende Tabelle. In dieser ist der erforderliche Speicherplatz eines Datentyp aufgeführt. Wenn wir beispielsweise für eine Spalte großzügig BIGINT (8 Byte) deklariert haben, aber ein SMALLINT (2 Byte) als Spaltentyp reichen würde, verschenken wir 6 Bytes. Pro Datensatz, wohlgemerkt! Wer als Datensatz-ID BIGINT gewählt hat und nun den Spaltentyp auf INT reduziert, spart 4 Bytes (50 Prozent) an Speicherplatz, bezogen auf das ID-Feld. Es lohnt sich also, auch laufende Tabellen zu gegebener Zeit auf die Datentypen hin zu prüfen.

  • TINYINT: 1 Byte
  • SMALLINT: 2 Byte
  • MEDIUMINT: 3 Byte
  • INTEGER: 4 Byte
  • BIGINT: 8 Byte

Update: Noch weniger Gedanken macht man sich um TEXT …

Schon mal Gedanken gemacht, wieviel Text in ein MySQL-Text-Feld passt? Viel. Sehr viel, sollte man meinen. Dem ist aber nicht so. Rund 65.000 Zeichen passen in ein Text-Feld. Nachfolgend der Speicherplatz und die maximale Textlänge von MySQL Text Feldern:

TINYTEXT 256 bytes
TEXT 65,535 bytes ~64kb
MEDIUMTEXT  16,777,215 bytes ~16MB
LONGTEXT 4,294,967,295 bytes ~4GB

Schreibe einen Kommentar