Zum Inhalt springen
SQL Anfänger 20 min

SQL Datentypen

Alle wichtigen SQL-Datentypen im Überblick: Zahlen, Text, Datum, Boolean und mehr - mit Unterschieden zwischen PostgreSQL und SQLite.

Aktualisiert:

Die richtige Wahl des Datentyps ist entscheidend fuer Speicherplatz, Performance und Datenqualitaet. In diesem Tutorial lernst du alle wichtigen SQL-Datentypen kennen und wann du welchen verwenden solltest.

Warum sind Datentypen wichtig?

Stell dir vor, du speicherst Preise als Text. Was passiert dann?

-- Text-Sortierung: '9.99' kommt NACH '10.00' (alphabetisch!)
-- Zahlen-Sortierung: 9.99 kommt VOR 10.00 (mathematisch korrekt)

Der richtige Datentyp sorgt fuer:

  • Korrekte Sortierung und Berechnungen
  • Datenvalidierung (keine Buchstaben in Zahlenspalten)
  • Effizienten Speicherplatz
  • Bessere Performance bei Abfragen

Ganzzahlen (Integer)

TypSpeicherWertebereichVerwendung
SMALLINT2 Byte-32.768 bis 32.767Kleine Zahlen (Alter, Menge)
INTEGER / INT4 Byte-2,1 Mrd. bis 2,1 Mrd.Standard fuer IDs, Mengen
BIGINT8 ByteSehr grosse ZahlenGrosse IDs, Zaehlwerte
CREATE TABLE lager (
    id INTEGER PRIMARY KEY,
    regal_nr SMALLINT NOT NULL,
    artikel_id INTEGER NOT NULL,
    menge INTEGER DEFAULT 0,
    gesamtverkauf BIGINT DEFAULT 0
);

Auto-Increment Typen

-- PostgreSQL:
CREATE TABLE benutzer (
    id SERIAL PRIMARY KEY,           -- Auto-Increment INTEGER
    name TEXT NOT NULL
);

-- Oder moderner:
CREATE TABLE benutzer (
    id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name TEXT NOT NULL
);

-- SQLite: INTEGER PRIMARY KEY ist automatisch auto-increment
CREATE TABLE benutzer (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL
);

Dezimalzahlen

TypBeschreibungGenauigkeitVerwendung
DECIMAL(p,s) / NUMERIC(p,s)Exakte DezimalzahlExaktGeld, Preise
REAL / FLOATGleitkommazahlUngefaehrWissenschaft, Messungen
DOUBLE PRECISIONDoppelte GenauigkeitUngefaehrBerechnungen
-- DECIMAL(10,2) = maximal 10 Stellen, davon 2 Nachkomma
-- Beispiele: 12345678.99, 0.01, 99999999.99

CREATE TABLE finanzen (
    id INTEGER PRIMARY KEY,
    betrag DECIMAL(10,2) NOT NULL,       -- Exakt: fuer Geldbetraege
    zinssatz DECIMAL(5,4),                -- z.B. 0.0375 (3,75%)
    steuersatz DECIMAL(4,3)               -- z.B. 0.190 (19%)
);

Wichtig: Verwende fuer Geldbetraege IMMER DECIMAL / NUMERIC, niemals FLOAT!

-- FLOAT ist ungenau bei Geldbetraegen:
SELECT CAST(0.1 AS FLOAT) + CAST(0.2 AS FLOAT);
-- Ergebnis koennte 0.30000000000000004 sein!

-- DECIMAL ist exakt:
SELECT CAST(0.1 AS DECIMAL(3,1)) + CAST(0.2 AS DECIMAL(3,1));
-- Ergebnis: 0.3 (genau)

Text-Datentypen

TypBeschreibungVerwendung
VARCHAR(n)Text mit max. n ZeichenNamen, E-Mails
CHAR(n)Text mit genau n ZeichenLaendercodes, PLZ
TEXTUnbegrenzter TextBeschreibungen, Artikel
CREATE TABLE adressen (
    id INTEGER PRIMARY KEY,
    strasse VARCHAR(200) NOT NULL,
    hausnummer VARCHAR(10) NOT NULL,
    plz CHAR(5) NOT NULL,           -- Immer 5 Zeichen
    stadt VARCHAR(100) NOT NULL,
    land CHAR(2) DEFAULT 'DE'       -- Immer 2 Zeichen (ISO-Code)
);

VARCHAR vs. TEXT

VARCHAR(n)TEXT
LaengenbegrenzungJa (max n Zeichen)Nein
ValidierungFehler bei zu langem TextAlles erlaubt
PerformanceGleich (in PostgreSQL)Gleich (in PostgreSQL)
EmpfehlungWenn Laenge bekanntWenn Laenge variabel

In PostgreSQL gibt es performance-maessig keinen Unterschied. VARCHAR(n) dient hauptsaechlich der Dokumentation und Validierung.

Datum und Zeit

TypSpeichertFormatBeispiel
DATENur DatumYYYY-MM-DD’2026-03-10’
TIMENur UhrzeitHH:MM:SS’14:30:00’
TIMESTAMPDatum + UhrzeitYYYY-MM-DD HH:MM:SS’2026-03-10 14:30:00’
INTERVALZeitdauer (PostgreSQL)Verschiedene’3 days’, ‘2 hours’
CREATE TABLE termine (
    id INTEGER PRIMARY KEY,
    titel TEXT NOT NULL,
    datum DATE NOT NULL,
    uhrzeit TIME,
    erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Beispiel-Daten
INSERT INTO termine (id, titel, datum, uhrzeit)
VALUES (1, 'Meeting', '2026-03-15', '10:00:00');

Datum-Berechnungen

-- PostgreSQL:
SELECT
    datum,
    datum + INTERVAL '7 days' AS naechste_woche,
    datum - INTERVAL '1 month' AS letzter_monat,
    CURRENT_DATE - datum AS tage_bis_termin
FROM termine;

-- SQLite:
SELECT
    datum,
    date(datum, '+7 days') AS naechste_woche,
    date(datum, '-1 month') AS letzter_monat,
    julianday(datum) - julianday('now') AS tage_bis_termin
FROM termine;

Boolean

-- PostgreSQL: Echter Boolean-Typ
CREATE TABLE einstellungen (
    id INTEGER PRIMARY KEY,
    benachrichtigungen BOOLEAN DEFAULT TRUE,
    newsletter BOOLEAN DEFAULT FALSE,
    premium BOOLEAN DEFAULT FALSE
);

INSERT INTO einstellungen (id, benachrichtigungen, newsletter, premium)
VALUES (1, TRUE, FALSE, TRUE);

SELECT * FROM einstellungen WHERE premium = TRUE;

-- SQLite: Kein nativer Boolean, nutzt INTEGER (0 = false, 1 = true)
CREATE TABLE einstellungen (
    id INTEGER PRIMARY KEY,
    benachrichtigungen INTEGER DEFAULT 1,
    newsletter INTEGER DEFAULT 0,
    premium INTEGER DEFAULT 0
);

JSON (PostgreSQL)

PostgreSQL unterstuetzt JSON-Daten nativ:

-- PostgreSQL:
CREATE TABLE events (
    id INTEGER PRIMARY KEY,
    typ TEXT NOT NULL,
    daten JSONB NOT NULL,           -- JSONB = Binary JSON (schneller)
    erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

INSERT INTO events (id, typ, daten) VALUES
(1, 'klick', '{"seite": "/produkte", "button": "kaufen"}');

-- JSON-Felder abfragen
SELECT daten->>'seite' AS seite
FROM events
WHERE daten->>'button' = 'kaufen';

Datentyp-Vergleich: PostgreSQL vs. SQLite

ZweckPostgreSQLSQLite
GanzzahlINTEGER, BIGINTINTEGER
DezimalzahlDECIMAL, NUMERICREAL
TextVARCHAR, TEXTTEXT
BooleanBOOLEANINTEGER (0/1)
DatumDATE, TIMESTAMPTEXT (als ISO-String)
JSONJSON, JSONBTEXT
BinaerdatenBYTEABLOB

SQLite hat ein sehr flexibles Typsystem. Es speichert intern nur 5 Typen: NULL, INTEGER, REAL, TEXT, BLOB. Andere Typnamen werden automatisch zugeordnet.

Den richtigen Datentyp waehlen

Entscheidungshilfe

DatenEmpfohlener TypGrund
IDsINTEGER / SERIALEindeutig, schnell
Preise / GeldDECIMAL(10,2)Exakte Berechnung
NamenVARCHAR(100)Laengenbegrenzung
E-MailsVARCHAR(255)Standard-Maximallaenge
BeschreibungenTEXTVariable Laenge
Ja/NeinBOOLEANKlar und eindeutig
GeburtstagDATENur Datum noetig
ErstellungszeitTIMESTAMPDatum + Uhrzeit
PLZ (DE)CHAR(5)Immer 5 Zeichen
LaendercodeCHAR(2)ISO-Standard

Was kommt als Naechstes?

Im naechsten Tutorial lernst du Constraints und Schluessel im Detail kennen - damit sicherst du die Qualitaet deiner Daten ab.

Zusammenfassung

  • INTEGER fuer Ganzzahlen, DECIMAL fuer exakte Dezimalzahlen (Geld!)
  • VARCHAR(n) fuer Text mit bekannter Maximallaenge, TEXT fuer unbegrenzten Text
  • DATE fuer Datum, TIMESTAMP fuer Datum + Uhrzeit
  • Verwende niemals FLOAT/REAL fuer Geldbetraege
  • PostgreSQL hat mehr Datentypen (JSON, Arrays, etc.) als SQLite
  • Der richtige Datentyp schuetzt vor Fehlern und verbessert die Performance

Uebungen

  1. Entscheidung: Welchen Datentyp wuerdest du fuer diese Spalten waehlen: Alter, Gewicht (in kg), Telefonnummer, Geburtsdatum, Kontostand?
  2. Tabelle erstellen: Erstelle eine Tabelle rezepte mit sinnvollen Datentypen fuer: Titel, Beschreibung, Zubereitungszeit in Minuten, Schwierigkeit (1-5), vegetarisch (ja/nein), Erstelldatum.
  3. Fehler finden: Was ist an dieser Tabelle falsch?
    CREATE TABLE rechnungen (
        id TEXT PRIMARY KEY,
        betrag FLOAT,
        datum VARCHAR(50)
    );
  4. PostgreSQL JSON: Erstelle eine Tabelle fuer Benutzereinstellungen, die flexible JSON-Daten speichern kann.
-- Loesung zu Uebung 2:
CREATE TABLE rezepte (
    id INTEGER PRIMARY KEY,
    titel VARCHAR(200) NOT NULL,
    beschreibung TEXT,
    zubereitungszeit INTEGER NOT NULL,
    schwierigkeit SMALLINT CHECK (schwierigkeit BETWEEN 1 AND 5),
    vegetarisch BOOLEAN DEFAULT FALSE,
    erstellt_am DATE DEFAULT CURRENT_DATE
);

Pro-Tipp: Im Zweifel waehle den spezifischeren Datentyp. Eine Telefonnummer sollte TEXT sein (wegen fuehrender Nullen und +49), nicht INTEGER. Ein Datum sollte DATE sein, nicht TEXT. Je spezifischer der Datentyp, desto besser kann die Datenbank deine Daten schuetzen und optimieren.

Zurück zum SQL Kurs