SQL-Datentypen: numerische, Zeichen-, Datums-/Uhrzeit- und Binärtypen. Meistern Sie Speicheroptimierung, Abfrageleistung, Best Practices für Datenintegrität und herstellerspezifische Unterschiede.
Ein SQL-Datentyp ist eine grundlegende Spezifikation, die definiert, welche Werte eine Spalte enthalten kann und wie viel Speicherplatz diese Werte in einer Datenbanktabelle benötigen. Das Verständnis von SQL-Datentypen ist für jeden wichtig, der Datenpipelines aufbaut, Abfragen schreibt oder Datenbankschemata entwirft, da diese Typen die Datenintegrität, die Speichereffizienz und die Abfrageleistung direkt steuern. Wenn Sie eine Spalte in einer Datenbanktabelle definieren, geben Sie nicht nur einen Namen an – Sie schließen einen Vertrag darüber ab, welche Art von Informationen in dieser Spalte gespeichert werden und wie die Datenbank sie behandeln soll.
Die Bedeutung der Wahl des richtigen Datentyps kann gar nicht hoch genug eingeschätzt werden. SQL-Datentypen setzen logische Regeln für die speicherbaren Werte durch und verhindern so von vornherein die Eingabe ungültiger Daten. Sie haben auch einen enormen Einfluss darauf, wie schnell Ihre Abfragen ausgeführt werden und wie viel Speicherplatz Ihre Tabellen belegen. Ein schlecht gewählter Datentyp kann Abfragen verlangsamen, Speicherplatz verschwenden und subtile Fehler in Ihren Datenpipelines verursachen. Umgekehrt kann die Auswahl geeigneter Typen die langfristige Skalierbarkeit verbessern und die Datenbankleistung bei Analyse-Workloads, Echtzeitanwendungen und Feature-Pipelines für maschinelles Lernen drastisch steigern.
SQL-Datentypen werden im Wesentlichen in vier Hauptgruppen unterteilt: numerische Datentypen für mathematische Berechnungen, Zeichen- und String-Datentypen für Text, Datums- und Zeitdatentypen zur Erfassung von Ereignissen sowie spezialisierte Datentypen für Binärdaten und andere Formate. Verschiedene Datenbanksysteme – wie MySQL, PostgreSQL, SQL Server und Oracle – implementieren diese Kategorien mit geringfügigen Abweichungen bei Benennung, Präzision und Speicheranforderungen. Dieser Leitfaden bietet eine praktische Referenz zum Verständnis von SQL-Datentypen in gängigen Datenbanksystemen sowie Best Practices für die Auswahl des richtigen Typs für Ihren Anwendungsfall.
Ein Datentyp ist mehr als nur eine Bezeichnung. Wenn Sie deklarieren, dass eine Spalte vom Typ INTEGER oder VARCHAR ist, teilen Sie Ihrem Datenbankmanagementsystem genau mit, welche Art von Werten in diese Spalte gehört und wie sie bei Abfragen und der Speicherung zu behandeln sind. Die Datenbank nutzt diese Informationen, um Daten beim Einfügen zu validieren und Einträge zu verhindern, die die Einschränkungen des Typs verletzen. Moderne Datenbanksysteme, wie sie beispielsweise auf ACID-Transaktionen basieren, stellen sicher, dass diese Validierung auch bei gleichzeitigen Zugriffsmustern zuverlässig erfolgt.
Betrachten Sie ein einfaches Beispiel: Wenn Sie eine Spalte als INTEGER definieren, lehnt die Datenbank jeden Versuch ab, Text wie "hello" oder Nicht-Ganzzahlwerte wie 3.14 einzufügen. Diese Validierung erfolgt automatisch und erzwingt die Datenintegrität, indem sie die Speicherung falscher Datenformate verweigert. Ohne diese Durchsetzung würden nachgelagerte Abfragen und Analysen auf fehlerhafte oder inkonsistente Daten stoßen, was zu falschen Ergebnissen und unnötigem Debugging-Aufwand führen würde.
Datentypen vermitteln auch anderen Entwicklern und Dateningenieuren, die mit Ihrem Schema arbeiten, die Absicht dahinter. Wenn jemand sieht, dass eine Spalte als DECIMAL statt als FLOAT definiert ist, versteht er sofort, dass diese Spalte präzise Geldwerte speichert, die keine Rundungsfehler zulassen. Diese implizite Dokumentation reduziert Missverständnisse und macht Schemata im Laufe der Zeit wartungsfreundlicher.
Die Wahl des Datentyps hat direkte Auswirkungen darauf, wie viel Festplattenspeicher Ihre Tabellen verbrauchen und wie schnell Abfragen ausgeführt werden können. Die Speichereffizienz beeinflusst Ihre Cloud-Kosten, die Backup-Zeiten und die Anzahl der Zeilen, die zur Verarbeitung in den Arbeitsspeicher passen. Die Abfrageleistung hängt teilweise von der Größe des Datentyps ab – kleinere Typen können schneller verarbeitet werden, da mehr Zeilen in den CPU-Cache passen und weniger Daten zwischen Speicher und Rechenleistung übertragen werden müssen. Für Teams, die ETL-Pipelines aufbauen, die täglich Millionen von Zeilen verarbeiten, summieren sich diese Optimierungen zu messbaren Kosten- und Latenzverbesserungen.
String-Datentypen unterscheiden sich erheblich in ihrem Speicherbedarf. Eine CHAR-Spalte reserviert immer ihre gesamte deklarierte Länge und füllt sie mit Leerzeichen auf, selbst wenn Sie einen kurzen Wert speichern. Eine VARCHAR-Spalte hingegen verbraucht nur so viel Platz, wie für den tatsächlich gespeicherten Wert benötigt wird. Wenn die meisten Ihrer Kundennamen weniger als 30 Zeichen lang sind, spart die Speicherung als VARCHAR(50) im Vergleich zu CHAR(50) erheblich Platz. Diese Platzeinsparung summiert sich über Millionen von Zeilen hinweg und kann die Abfragelatenz verringern, da mehr Daten in den verfügbaren Arbeitsspeicher passen.
Numerische Typen beeinflussen ebenfalls die Leistung. Die Verwendung von BIGINT, wenn INT ausreichen würde, verschwendet Speicherplatz und Rechenleistung. Umgekehrt führt die Verwendung von SMALLINT für eine Spalte, die Werte über 32.000 speichern muss, zu Überlauffehlern. Wenn Sie die Bereichs- und Präzisionsanforderungen Ihrer Daten verstehen, können Sie den kleinsten Datentyp wählen, der Ihre Werte sicher aufnimmt, sodass Ihre Datenbank schnell und schlank bleibt.
Indizes, die die Abfrageleistung drastisch beschleunigen, sind schneller, wenn sie auf geeigneten Datentypen definiert sind. Ein Index auf einer TINYINT-Spalte ist effizienter als ein Index auf einer TEXT-Spalte. Indem Sie numerische Typen in der passenden Größe wählen und Indizes auf sehr großen Textspalten vermeiden, vervielfachen Sie die Leistungsvorteile der Indexierung für Ihren gesamten Workload. Verteilte Abfrage-Engines wie Apache Spark profitieren besonders von passend dimensionierten Datentypen, da kleinere Typen den Netzwerktransfer bei Shuffle-Operationen reduzieren.
Die goldene Regel bei der Auswahl von Datentypen lautet: Verwenden Sie den kleinsten Typ, der Ihre Daten sicher aufnehmen kann. Dieses Prinzip, das beim Schemaentwurf konsequent angewendet wird, zahlt sich bei der Speichereffizienz, der Abfragegeschwindigkeit und der Systemskalierbarkeit aus. Bevor Sie einen Typ auswählen, fragen Sie sich: Was ist der maximale Wert, den diese Spalte enthalten kann? Wie viel Präzision benötige ich? Wird dieser Wert jemals NULL sein?
Untersuchen Sie bei numerischen Daten Ihre tatsächliche Datenverteilung. Wenn eine Spalte Werte zwischen 0 und 100 enthält, ist TINYINT perfekt. Wenn Sie Kunden-IDs speichern, die 2 Milliarden überschreiten könnten, reicht INT aus. Verwenden Sie BIGINT nur, wenn Sie tatsächlich Speicherplatz für Werte über 2 Milliarden benötigen. Wenn Sie diese Unterscheidung bei Dutzenden von Spalten in Ihrem Schema treffen, kann dies die Gesamtgröße der Tabelle um 20–30 % reduzieren und die Abfrageleistung direkt verbessern.
Berücksichtigen Sie bei der Arbeit mit Strings den Kompromiss zwischen Speicherplatz und Flexibilität. CHAR zwingt Sie dazu, eine maximale Länge zu wählen, und belegt diesen Speicherplatz immer. Mit VARCHAR können Sie Daten variabler Länge effizient speichern, erfordert jedoch, dass Sie ein Maximum wählen, das nicht zu einer Kürzung führt. VARCHAR(50) für Namen bietet ein gutes Gleichgewicht – es ist groß genug für praktisch alle Namen, verhindert aber die versehentliche Speicherung extrem langer Werte, die auf Probleme mit der Datenqualität hindeuten könnten. Verwenden Sie für sehr große Textblöcke wie Artikeltexte oder Protokollmeldungen die Typen TEXT oder CLOB, die keine vorherige Längenangabe erfordern.
Validieren Sie Ihre Auswahl mit Beispieldaten, bevor Sie sie in der Produktion bereitstellen. Fügen Sie echte Daten in eine Testtabelle mit Ihrem vorgeschlagenen Schema ein und beobachten Sie die tatsächliche Speichernutzung. Führen Sie Ihre beabsichtigten Abfragen aus und messen Sie die Leistung. Dieser empirische Ansatz zeigt, ob Ihre Auswahl den tatsächlich ausgeführten Workload unterstützt. Datenbankplattformen bieten in der Regel Tools zur Analyse von Abfrageausführungsplänen und zur Identifizierung langsamer Operationen, die durch suboptimale Datentypen verursacht werden.
Numerische Datentypen speichern Zahlen und lassen sich in zwei Hauptfamilien unterteilen: Ganzzahltypen für ganze Zahlen sowie Dezimal- oder Gleitkommatypen für Zahlen mit Nachkommastellen.
Ganzzahltypen stellen ganze Zahlen ohne Dezimalstellen dar. Der Datentyp INTEGER, auch INT genannt, ist die am häufigsten verwendete Option für Ganzzahlwerte und speichert eine 4-Byte-Zahl, die Werte von etwa -2 Milliarden bis +2 Milliarden darstellen kann. Wenn Sie einen kleineren Bereich benötigen – beispielsweise zum Speichern von Alterswerten, die 127 nicht überschreiten –, verbraucht TINYINT nur ein Byte und ist perfekt geeignet. SMALLINT belegt zwei Byte und verarbeitet Werte bis zu etwa 32.000, was für Spalten wie Mengen oder Zähler nützlich ist, die relativ klein bleiben. BIGINT, eine 8-Byte-Ganzzahl, bietet Platz für astronomische Zahlen und ist erforderlich, wenn IDs aus verteilten Systemen oder in Millisekunden gemessene Zeitstempel gespeichert werden.
Der Datentyp DECIMAL, in der SQL-Standarddokumentation manchmal auch als NUMERIC bezeichnet, speichert Zahlen mit fester Genauigkeit, die sich für Finanzberechnungen und andere Kontexte eignen, in denen Rundungsfehler inakzeptabel sind. DECIMAL speichert exakte Werte ohne die bei der Gleitkomma-Arithmetik übliche Annäherung. Wenn Sie DECIMAL(10,2) definieren, sagen Sie damit: "Ich möchte Zahlen mit insgesamt bis zu 10 Ziffern speichern, wobei genau 2 dieser Ziffern rechts vom Dezimalpunkt stehen." Diese Präzision bedeutet, dass DECIMAL(10,2) Werte wie 99999999.99 sicher speichert, aber alles mit mehr als zwei Dezimalstellen ablehnt. Banken und Buchhaltungssysteme verlassen sich auf DECIMAL, da Finanzvorschriften exakte, prüfbare Berechnungen ohne Rundungsfehler verlangen.
NUMERIC dient als SQL-Standardname für Dezimaldaten mit fester Genauigkeit und verhält sich in den meisten Datenbanksystemen identisch mit DECIMAL. Einige Datenbanken verwenden NUMERIC und DECIMAL synonym, während andere sie aus historischen Gründen separat dokumentieren. Überprüfen Sie die Dokumentation Ihrer Datenbank, um das genaue Verhalten zu bestätigen, aber betrachten Sie sie in der Praxis als funktionell gleichwertig.
Das Erstellen einer Tabelle mit numerischen Spalten veranschaulicht diese Typen im Kontext. Eine typische Verkaufstabelle könnte so aussehen:
Hier verwendet employee_id den Typ INT, da Mitarbeiter-IDs in der Regel im Millionenbereich liegen. age verwendet TINYINT, da das Alter von Menschen nie 127 überschreitet. salary und bonus_percentage verwenden DECIMAL, um präzise Berechnungen bei der Gehaltsabrechnung zu gewährleisten, bei der sich selbst kleinste Rundungsfehler im gesamten Unternehmen summieren. Moderne Datenplattformen wie Delta Lake setzen diese Typen streng durch und garantieren, dass Daten mit falschem Typ nicht in Produktionstabellen eingefügt werden können.
Gleitkommatypen speichern ungefähre numerische Werte mit einer bestimmten Genauigkeit. FLOAT und DOUBLE verwenden die binäre Darstellung nach IEEE 754, die Genauigkeit gegen Geschwindigkeit und Wertebereich eintauscht. Ein FLOAT belegt in der Regel 4 Bytes und speichert ungefähre Werte, während DOUBLE 8 Bytes belegt und eine höhere Präzision bietet.
Die Gleitkommadarstellung führt zu Rundungsartefakten, da viele Dezimalwerte binär nicht exakt dargestellt werden können. Beispielsweise kann 0,1 in binärer Gleitkommadarstellung nicht exakt abgebildet werden, sodass jede Berechnung mit 0,1 geringfügig abweichen kann. Diese winzigen Fehler summieren sich in langen Berechnungsketten und führen schließlich zu sichtlich falschen Ergebnissen. Aus diesem Grund sollten Sie FLOAT oder DOUBLE niemals für Währungsdaten oder andere Werte verwenden, bei denen es auf Exaktheit ankommt.
Die richtige Wahl zwischen DECIMAL und FLOAT hängt von Ihrem Anwendungsfall ab. Verwenden Sie DECIMAL für alle Finanzdaten, präzise wissenschaftliche Messungen oder Berechnungen, bei denen die Korrektheit überprüfbar sein muss. Verwenden Sie FLOAT für Näherungswerte, wissenschaftliche Berechnungen, bei denen kleine Fehler akzeptabel sind, oder für Machine-Learning-Features, bei denen die geringe Ungenauigkeit die Modellqualität nicht beeinträchtigt. Die Abfrageleistung verbessert sich durch die Verwendung von Datentypen in der passenden Größe, und FLOAT-Operationen sind schneller als DECIMAL-Operationen, da Gleitkomma-Arithmetik auf allen modernen Prozessoren hardwarebeschleunigt ist.
Vergleichen Sie diese beiden Ansätze zur Speicherung von Produktpreisen:
Die zweite Version stellt sicher, dass Preise wie 19,99 exakt gespeichert werden und es bei Berechnungen oder der Anzeige nie zu Rundungsfehlern kommt. Die erste Version stellt 19,99 intern möglicherweise als 19,989999... dar, was zu minimalen Abweichungen bei Gesamtberechnungen und den für Kunden angezeigten Preisen führt.
Datums- und Uhrzeittypen speichern zeitliche Informationen – den Moment, in dem Ereignisse aufgetreten sind oder ab wann Daten als relevant betrachtet werden sollten. Diese Typen sind unerlässlich für Zeitreihenanalysen, Event-Logging und Geschäftsprozesse, die nachverfolgen, wann Ereignisse stattfinden.
Der Typ DATE speichert nur den Datumsteil – Jahr, Monat und Tag – im Format YYYY-MM-DD ohne Zeitkomponente. Verwenden Sie DATE, wenn Sie nur den Tag erfassen müssen, an dem etwas passiert ist, wie das Geburtsdatum eines Kunden oder das Datum einer Transaktion, ohne sich um die genaue Stunde oder Minute kümmern zu müssen. DATE benötigt minimalen Speicherplatz (in der Regel 3 Bytes) und vereinfacht Abfragen, die Ereignisse nach Kalendertag gruppieren.
Der Typ TIME speichert nur den Uhrzeitanteil – Stunden, Minuten und Sekunden – ohne Datum. TIME ist seltener als DATE oder TIMESTAMP, kommt aber in Schemata vor, die wiederkehrende Zeiten aufzeichnen, wie Geschäftszeiten oder Termine innerhalb eines Tages.
Der Typ TIMESTAMP (in einigen Systemen wie MySQL und SQL Server als DATETIME bezeichnet) speichert sowohl Datums- als auch Uhrzeitinformationen im Format YYYY-MM-DD HH:MM:SS. TIMESTAMP erfasst den genauen Moment, in dem etwas passiert ist, sekundengenau (oder feiner, je nach Datenbank). Die meisten ereignisgesteuerten Systeme verwenden TIMESTAMP, um genau aufzuzeichnen, wann Protokolleinträge erstellt, Bestellungen aufgegeben oder Sensorwerte empfangen wurden. Viele analytische Systeme, die mit Star-Schema-Designs erstellt wurden, verwenden TIMESTAMP-Schlüssel für eine effiziente zeitliche Analyse und die Verfolgung historischer Fakten.
Wählen Sie DATE oder TIMESTAMP basierend auf Ihren Abfragemustern. Wenn Ihre Geschäftslogik Ereignisse nach Kalendertag gruppiert und keine untertägige Präzision benötigt, ist DATE übersichtlicher und effizienter. Wenn Sie die verstrichene Zeit zwischen Ereignissen berechnen, Trends innerhalb einer Stunde erkennen oder eine präzise chronologische Reihenfolge einhalten müssen, ist TIMESTAMP erforderlich.
Beispiele für Datums- und Uhrzeitspaltendefinitionen:
Hier verwendet birthdate den Typ DATE, da Sie sich nur für das Geburtsdatum der Person interessieren, nicht für die Uhrzeit der Geburt. account_creation_date verwendet TIMESTAMP, da Sie genau wissen müssen, wann das Konto erstellt wurde, um beispielsweise Betrugsmuster zu erkennen oder das Alter des Kontos in Tagen zu berechnen. preferred_contact_time verwendet TIME, da Sie eine wiederkehrende Zeit wie „Rufen Sie mich um 14 Uhr an“ ohne ein bestimmtes Datum speichern.
Ein subtiles, aber kritisches Problem bei zeitlichen Daten ist die Handhabung von Zeitzonen. Wenn Sie aufzeichnen, dass ein Ereignis um „2024-03-15 14:30:00“ aufgetreten ist, bedeutet das dann 14:30 Uhr in New York, Tokio oder UTC? Die Antwort ist wichtig, da dieselbe Uhrzeit in verschiedenen Zeitzonen unterschiedliche Bedeutungen hat.
Die Best Practice besteht darin, alle Zeitstempel in UTC (Coordinated Universal Time) zu speichern, einer zeitzonenunabhängigen Zeitreferenz. Wenn Ihre Anwendung ein Ereignis von einem Benutzer in einer beliebigen Zeitzone empfängt, konvertieren Sie es in UTC, bevor Sie es in Ihrer Datenbank speichern. Dieser Ansatz stellt sicher, dass alle Zeitstempel vergleichbar sind und Sie Fragen wie „Welche Ereignisse traten zuerst auf?“ oder „Wie viel Zeit verging zwischen diesen Ereignissen?“ eindeutig beantworten können.
Einige Datenbanken wie PostgreSQL unterstützen TIMESTAMPTZ (Timestamp mit Zeitzone), wodurch sowohl der Zeitstempel als auch die zugehörige Zeitzoneninformation gespeichert werden. Wenn Sie Daten abrufen, konvertiert die Datenbank den UTC-Zeitstempel bei Bedarf wieder in die ursprüngliche Zeitzone. Dieser Ansatz bewahrt den ursprünglichen Zeitzonenkontext und gewährleistet gleichzeitig die interne Konsistenz.
DATETIME von SQL Server und DATETIME von MySQL enthalten keine Zeitzoneninformationen. Konvertieren Sie Zeiten daher vor dem Speichern in UTC und bei der Anzeige für Benutzer wieder zurück. Sitzungseinstellungen beeinflussen, wie Zeitstempel in einigen Datenbanken interpretiert werden, dokumentieren Sie Ihre Annahmen daher klar.
Zeichendatentypen speichern Text und sind in Varianten mit fester und variabler Länge verfügbar, die sich jeweils für unterschiedliche Szenarien eignen.
CHAR speichert Zeichenketten fester Länge und verwendet immer die gesamte deklarierte Länge, wobei mit Leerzeichen aufgefüllt wird, wenn der tatsächliche Wert kürzer ist. CHAR(10) belegt immer genau 10 Bytes pro Zeile, selbst wenn Sie „hello“ (5 Zeichen) einfügen. CHAR eignet sich hervorragend, wenn fast alle Werte die gleiche Länge haben, wie US-Postleitzahlen (5 Ziffern) oder Ländercodes (2 Buchstaben). Die Speicherung mit fester Länge vereinfacht die Indizierung und macht Tabellenscans in ihrer Größe vorhersehbar.
VARCHAR speichert Zeichenketten variabler Länge und benötigt nur so viel Platz, wie für die tatsächlichen Daten erforderlich ist, zuzüglich eines geringen Overheads zur Erfassung der Länge. VARCHAR(100) zur Speicherung von „hello“ belegt etwa 7 Bytes (5 für „hello“ plus 2 für die Längencodierung) und spart im Vergleich zu CHAR(100) beim gleichen Wert 93 Bytes. VARCHAR sollte unter Berücksichtigung realer Daten dimensioniert werden – wählen Sie VARCHAR(50) für Namen nur dann, wenn Sie sicher sind, dass Namen 50 Zeichen nicht überschreiten. Wenn Namen in der Regel 30 Zeichen lang sind, aber gelegentlich 50 erreichen können, ist VARCHAR(50) ratsam.
TEXT nimmt große Blöcke unstrukturierten Textes ohne deklarierte Maximallänge auf. Verwenden Sie TEXT für Artikel, Kommentare oder Dokumente, deren Größe stark variiert. Einige Datenbanken unterscheiden zwischen TEXT und spezielleren Typen wie CLOB (Character Large Object), aber die meisten modernen Systeme verarbeiten TEXT dank interner Komprimierung und Streaming effizient.
Verwenden Sie für internationalen Text, der Zeichen aus mehreren Sprachen enthält, Unicode-kompatible Typen: NVARCHAR- oder UTF8-Varianten, je nach Ihrer Datenbank. NVARCHAR (national VARCHAR) in SQL Server speichert UTF-16-codierten Text und unterstützt jedes Unicode-Zeichen. PostgreSQL und MySQL unterstützen UTF-8-Zeichensätze direkt in VARCHAR mit entsprechenden Collation-Einstellungen. Legen Sie beim Erstellen von Tabellen die Zeichenkodierung immer explizit fest, um überraschendes Verhalten zu vermeiden, falls sich die Standardeinstellung der Datenbank ändert.
Beispiele für Spaltendefinitionen von Zeichenketten:
Hier verwenden first_name und last_name VARCHAR, da Namen in der Regel kurz, aber variabel sind, was im Vergleich zu CHAR Platz spart. biography verwendet TEXT, da Kundenbiografien alles von einem einzelnen Satz bis hin zu einem ganzen Absatz sein können. country_code verwendet CHAR(2) weil alle Ländercodes genau 2 Buchstaben lang sind, was eine Speicherung mit fester Länge sinnvoll macht.
BLOB (Binary Large Object) speichert beliebige Binärdaten ohne maximale Größenbeschränkung. Verwenden Sie BLOB für Bilder, PDF-Dokumente, Videos oder andere unstrukturierte Binärinhalte, die nicht in Standardtypen passen. BLOB ist geeignet, wenn Sie Dateien in Ihrer Datenbank speichern müssen, obwohl viele Produktionssysteme es vorziehen, große Dateien in Objektspeichersystemen wie Amazon S3 zu speichern und nur Dateireferenzen in der Datenbank zu behalten.
VARBINARY speichert Binärdaten variabler Länge mit einer expliziten maximalen Größe. VARBINARY(256) speichert bis zu 256 Bytes an Binärdaten und belegt nur den für den tatsächlichen Inhalt benötigten Platz. VARBINARY eignet sich gut für Binärdaten fester Größe wie kryptografische Signaturen, Prüfsummen oder UUIDs.
BINARY speichert Binärdaten fester Länge und füllt sie bei Bedarf mit Null-Bytes auf. BINARY(16) belegt immer genau 16 Bytes, was für die Speicherung von Identifikatoren fester Größe wie 128-Bit-UUIDs nützlich ist. Die Größe von BINARY sollte sorgfältig gewählt werden, da Platzverschwendung durch zu große Deklarationen die Leistung beeinträchtigt.
In der Praxis ist die Speicherung großer Dateien im Objektspeicher anstelle von Datenbanken meist überlegen. Objektspeicher ist kostengünstiger, schneller bei großen Dateien und lässt sich einfacher skalieren als Datenbankdaten. Speichern Sie den Dateiverweis und die Metadaten in der Datenbank, nicht die Datei selbst.
Beispiele für Definitionen von Binärspalten:
Hier verwendet content BLOB, um die eigentlichen Dokumentdaten zu speichern. checksum verwendet VARBINARY zur Speicherung eines SHA-256-Hashs (32 Bytes), der überprüft, ob das Dokument beschädigt wurde. uuid verwendet BINARY(16), um einen UUID-Identifikator fester Größe zu speichern.
Die Indizierung von Binärspalten ist knifflig, da herkömmliche B-Tree-Indizes davon ausgehen, dass Werte sortierbar und vergleichbar sind. Sie können BINARY-Spalten für exakte Übereinstimmungen indizieren, jedoch nicht für Bereichsabfragen. Vermeiden Sie die Indizierung von BLOB-Spalten, es sei denn, Ihre Datenbank verfügt über spezielle Bitmap- oder Hash-Indizes, die für Binärdaten ausgelegt sind.
Verwenden Sie zur Überprüfung der Datenintegrität von Binärinhalten eine separate checksum-Spalte, die einen Hash der Binärdaten speichert. Wenn Sie eine Beschädigung vermuten, berechnen Sie den Hash neu und vergleichen Sie ihn mit dem gespeicherten Wert. Dieser Ansatz ist weataus schneller, als den gesamten Binärinhalt erneut zu überprüfen.
Boolean-Datentypen speichern True/False-Werte, die für Flags, Statusanzeigen und Ja/Nein-Entscheidungen unerlässlich sind. True- und False-Werte vereinfachen die Datenmodellierung und verhindern ungültige Zustände wie NULL oder mehrdeutige Zeichenfolgen wie "yes" oder "1".
Verschiedene Datenbanken implementieren Boolean unterschiedlich. PostgreSQL verfügt über einen nativen BOOLEAN-Typ, der true/false, yes/no, on/off, 1/0 in verschiedenen Formaten akzeptiert. MySQL behandelt BOOLEAN als kleine Ganzzahl und verweist darauf als TINYINT(1), wobei 1 für true und 0 für false steht. SQL Server verwendet BIT für Boolean-ähnliche Daten und speichert 1 für true und 0 für false unter Verwendung eines einzelnen Bits pro Wert (obwohl die tatsächliche Speicherung variiert).
Das Verständnis der Unterschiede zwischen den Anbietern ist wichtig, wenn Sie Schemata über Datenbanken hinweg migrieren. Ein PostgreSQL-BOOLEAN hat keine direkte Entsprechung in SQL Server – Sie würden stattdessen BIT verwenden. Anwendungscode, der von der flexiblen True/False-Eingabe von PostgreSQL ausgeht (er akzeptiert "yes", "on", "1"), könnte an den strengen 0/1-Anforderungen von SQL Server scheitern.
Beispiele für Boolean-Definitionen:
Alle drei sind funktionell identisch bei der Speicherung von True/False-Werten, aber die zugrunde liegenden Typnamen unterscheiden sich und das Eingabe-/Ausgabeverhalten variiert geringfügig.
Die Typumwandlung (Type Casting) konvertiert einen Wert von einem Datentyp in einen anderen. Dies ist unerlässlich, wenn Daten aus verschiedenen Quellen kombiniert werden müssen oder wenn Sie die Interpretation eines Werts ändern müssen.
Eine implizite Konvertierung erfolgt automatisch, wenn die Datenbank Typen konvertiert, um eine Operation zu ermöglichen. INSERT INTO table_name (int_column) VALUES ('123') konvertiert möglicherweise implizit die Zeichenfolge '123' in die Ganzzahl 123. Die implizite Konvertierung ist praktisch, aber riskant – die Datenbank führt möglicherweise Konvertierungen durch, die Sie nicht beabsichtigt haben, oder die Konvertierung schlägt unbemerkt fehl, was zu unerwarteten Ergebnissen führt.
Die explizite Konvertierung mit CAST oder CONVERT gibt Ihnen eine präzise Kontrolle und macht Ihre Absichten für andere Entwickler deutlich. Explizites Casting verhindert unbemerkte Überraschungen und macht die Abfrageleistung vorhersehbarer.
Zu den gängigen Konvertierungen gehören das Umwandeln von Zeichenfolgen in Zahlen für Berechnungen, das Umwandeln von Zahlen in Zeichenfolgen für die Verkettung und das Umwandeln in DATE oder TIMESTAMP, um nach Zeitbereichen zu filtern.
Beispiel für die Verwendung von CAST:
Diese expliziten Konvertierungen machen den Code klar: Jeder, der die Abfrage liest, versteht sofort, dass eine Konvertierung stattfindet, und weiß genau, welcher Typ erzeugt wird.
SQL-Datentypen variieren zwischen MySQL, PostgreSQL, SQL Server und Oracle. Während die Kernkonzepte (numerisch, Zeichen, Datum/Uhrzeit, binär) universell sind, unterscheiden sich die spezifischen Typnamen, die Präzision und die Speichereigenschaften.
MySQL verwendet TINYINT für Boolean-Werte (wobei BOOLEAN als TINYINT(1) bezeichnet wird), VARCHAR für variable Zeichenfolgen und BLOB für Binärdaten. PostgreSQL unterstützt BOOLEAN nativ, TEXT für großen Text ohne Größenbeschränkung und BYTEA für Binärdaten. SQL Server verwendet wie die meisten Datenbanken INT und BIGINT, VARCHAR für Zeichenfolgen und IMAGE für große Binärdaten. Oracle verwendet NUMBER für numerische Werte, VARCHAR2 für Zeichenfolgen (nicht VARCHAR) und BLOB für Binärdaten.
Diese Unterschiede sind bei der Migration von Schemata von Bedeutung. Eine PostgreSQL-TEXT-Spalte kann eine beliebige Datenmenge aufnehmen, aber MySQL-TEXT hat ein Limit von 64 KB und erfordert LONGTEXT für größere Inhalte. SQL Server VARCHAR(MAX) wird für wirklich großen Text benötigt, während PostgreSQL-TEXT dies direkt handhabt. Der NUMBER-Typ von Oracle ist flexibler als die numerischen Typen der meisten Datenbanken, sodass Sie Präzision und Skalierung unterschiedlich festlegen können.
Konsultieren Sie die offizielle Dokumentation Ihrer Datenbank, bevor Sie Schemata entwerfen, die portabel sein sollen. Testen Sie Ihre tatsächlichen Daten mit Ihrem Zieldatenbanksystem, um Grenzfälle zu erfassen, in denen Annahmen über das Typverhalten nicht zutreffen.
Bevorzugen Sie Typen mit fester Präzision wie DECIMAL für Finanzdaten und vermeiden Sie Gleitkommatypen in Buchhaltungs- oder Abrechnungssystemen vollständig. Finanzielle Genauigkeit ist nicht verhandelbar, und die Exaktheit von DECIMAL ist den geringen Leistungsaufwand wert. Organisationen, die Analysesysteme auf modernen Data-Warehouse-Plattformen aufbauen, legen zunehmend Wert auf die richtige Auswahl von Datentypen als Grundlage für Governance und Leistung.
Vermeiden Sie die Verwendung von Zeichenfolgen für Daten oder Booleans, auch wenn dies technisch möglich ist. Das Speichern von Daten als VARCHAR erschwert die Datumsarithmetik, verhindert, dass die Datenbank datumsbasierte Abfragen optimiert, und erschwert die Validierung. Das Speichern von Booleans als Zeichenfolgen führt zu Mehrdeutigkeiten – ist "false" dasselbe wie "no"? – und verschwendet Speicherplatz. Verwenden Sie native DATE-, TIMESTAMP- und BOOLEAN-Typen, die speziell für diese Werte entwickelt wurden.
Überprüfen und optimieren Sie Typen bei Schema-Audits, insbesondere wenn Datenbanken bereits seit Jahren existieren und sich die Nutzungsmuster geändert haben. Eine Spalte, die aus Gründen, die nicht mehr zutreffen, als VARCHAR(1000) definiert ist, verschwendet in jeder Zeile Platz. Verwenden Sie EXPLAIN PLAN oder die Abfrageanalysetools Ihrer Datenbank, um langsame Abfragen zu identifizieren, die durch falsche Typauswahlen verursacht werden, und führen Sie dann ein Refactoring durch.
Dokumentieren Sie Ihre Typauswahl, insbesondere Grenzfälle und Annahmen. Ein Kommentar, der erklärt, warum eine Spalte TINYINT statt INT ist, verhindert, dass sie später aufgrund eines unvollständigen Verständnisses geändert wird. Diese Dokumentation ist besonders wichtig für numerische Typen, bei denen der Bereich eine Rolle spielt.
CHAR speichert Zeichenfolgen fester Länge und verwendet immer die volle deklarierte Größe, wobei mit Leerzeichen aufgefüllt wird. VARCHAR speichert Zeichenfolgen variabler Länge und benötigt nur so viel Platz, wie für die tatsächlichen Daten erforderlich ist. CHAR ist effizienter für Daten fester Größe wie Ländercodes (immer 2 Buchstaben), während VARCHAR effizienter für Daten variabler Länge wie Namen ist. Zeichenfolgen-Datentypen setzen Regeln für die Dateneingabe in SQL-Spalten durch, und die Wahl zwischen CHAR und VARCHAR beeinflusst sowohl den Speicherplatz als auch die Leistung in Ihrem Datenbanksystem.
DECIMAL speichert exakte Werte und verhindert Rundungsfehler, was für Finanzdaten, bei denen es auf Präzision ankommt, unerlässlich ist. FLOAT speichert Näherungswerte schneller, führt jedoch zu Rundungsartefakten. Verwenden Sie DECIMAL für Geldbeträge, präzise wissenschaftliche Messungen und Berechnungen, bei denen die Exaktheit überprüfbar sein muss. Verwenden Sie FLOAT für Näherungen, Machine-Learning-Features und wissenschaftliches Rechnen, bei denen kleine Fehler akzeptabel sind. Die Wahl des richtigen Datentyps ist für die Datenintegrität in Finanzsystemen von entscheidender Bedeutung.
Verwenden Sie DATE, wenn Sie nur das Kalenderdatum ohne Zeitangabe erfassen müssen, z. B. das Geburtsdatum eines Kunden oder das Datum einer Transaktion. Verwenden Sie TIMESTAMP, wenn Sie präzise zeitliche Informationen einschließlich Stunden, Minuten und Sekunden benötigen, wie z. B. Ereignis-Zeitstempel oder Transaktionsabschlusszeiten. Datums- und Zeittypen werden verwendet, um aufzuzeichnen, wann Ereignisse eintreffen, und die Auswahl des richtigen Typs vereinfacht Abfragen und verhindert Speicherplatzverschwendung.
Die maximalen Längen variieren je nach Datenbank. VARCHAR unterstützt typischerweise Längen von bis zu 65.535 Bytes in MySQL, unbegrenzt in PostgreSQL und bis zu 8.000 Bytes in SQL Server (oder VARCHAR(MAX) für größere Werte). Überprüfen Sie immer die Dokumentation Ihrer spezifischen Datenbank auf genaue Grenzwerte. Die Wahl geeigneter Typen kann die langfristige Skalierbarkeit verbessern und verhindern, dass unerwartete Speichergrenzen erreicht werden.
Speichern Sie alle Zeitstempel in UTC, um Konsistenz und Vergleichbarkeit zu gewährleisten. Konvertieren Sie Zeitstempel vor dem Speichern in UTC und konvertieren Sie sie bei der Anzeige wieder in die lokale Zeitzone des Benutzers. Einige Datenbanken wie PostgreSQL unterstützen TIMESTAMPTZ, um diese Konvertierung automatisch durchzuführen. Eine konsistente Handhabung von Zeitzonen verhindert Fehler bei zeitbasierten Berechnungen und macht die Reihenfolge von Ereignissen eindeutig.
UUID-Werte verwenden typischerweise BINARY(16) für Speicherplatz mit fester Größe oder CHAR(36) für die standardmäßige String-Darstellung einschließlich Bindestrichen. Einige Datenbanken wie PostgreSQL unterstützen native UUID-Typen. INT oder BIGINT eignen sich für automatisch inkrementierende numerische IDs. Wählen Sie basierend auf Ihrem Identifikationsschema – sequenzielle numerische IDs sind einfach, machen das Erraten von IDs jedoch leichter, während UUIDs zufällig und für verteilte Systeme geeignet sind.
Kleinere Datentypen passen in größerer Zahl in den CPU-Cache, was Abfragen beschleunigt. Indizes sind bei entsprechend dimensionierten numerischen Typen effektiver. Die Speichereffizienz reduziert Festplatten-I/O und verbessert die Abfragelatenz. Die Abfrageleistung verbessert sich durch die Verwendung angemessen dimensionierter Datentypen. Die Wahl des kleinsten Typs, der Ihre Daten sicher aufnimmt, hält Datenbanken schnell und schlank.
(Dieser Blogbeitrag wurde mit KI-gestützten Tools übersetzt.) Originalbeitrag
Abonnieren Sie unseren Blog und erhalten Sie die neuesten Beiträge direkt in Ihren Posteingang.