CREATE TABLE
Lerne, wie du eigene Tabellen erstellst: Spalten definieren, Datentypen wählen und die richtige Struktur planen.
Bisher hast du mit vorbereiteten Tabellen gearbeitet. Jetzt lernst du, wie du eigene Tabellen erstellst - mit genau den Spalten, Datentypen und Einschraenkungen, die du brauchst.
Grundsyntax von CREATE TABLE
CREATE TABLE tabellenname (
spaltenname1 datentyp [einschraenkungen],
spaltenname2 datentyp [einschraenkungen],
...
);
Deine erste eigene Tabelle
CREATE TABLE kontakte (
id INTEGER PRIMARY KEY,
vorname TEXT NOT NULL,
nachname TEXT NOT NULL,
email TEXT UNIQUE,
telefon TEXT,
erstellt_am DATE DEFAULT CURRENT_DATE
);
Jede Spalte hat:
- Einen Namen (z.B.
vorname) - Einen Datentyp (z.B.
TEXT) - Optionale Einschraenkungen (z.B.
NOT NULL,UNIQUE)
Wichtige Datentypen
Die gaengigsten Datentypen, die in SQLite und PostgreSQL funktionieren:
| Datentyp | Beschreibung | Beispiel |
|---|---|---|
INTEGER | Ganzzahl | 42, -7, 1000 |
DECIMAL(p,s) / NUMERIC | Dezimalzahl | 19.99, 1234.56 |
TEXT / VARCHAR(n) | Text | ’Hallo Welt’ |
BOOLEAN | Wahrheitswert | TRUE / FALSE |
DATE | Datum | ’2026-03-10’ |
TIMESTAMP | Datum + Uhrzeit | ’2026-03-10 14:30:00’ |
Zahlendatentypen im Detail
CREATE TABLE artikel (
id INTEGER PRIMARY KEY, -- Ganzzahl
name TEXT NOT NULL, -- Text
preis DECIMAL(10, 2) NOT NULL, -- Max 10 Stellen, davon 2 Nachkomma
gewicht_kg DECIMAL(5, 3), -- z.B. 1.250
menge INTEGER DEFAULT 0, -- Ganzzahl mit Standardwert
aktiv BOOLEAN DEFAULT TRUE -- Wahr/Falsch
);
Text-Datentypen
CREATE TABLE nachrichten (
id INTEGER PRIMARY KEY,
betreff VARCHAR(200) NOT NULL, -- Max 200 Zeichen
inhalt TEXT, -- Beliebig langer Text
absender VARCHAR(100) NOT NULL
);
| Typ | Beschreibung |
|---|---|
VARCHAR(n) | Text mit maximaler Laenge n |
CHAR(n) | Text mit fester Laenge n (mit Leerzeichen aufgefuellt) |
TEXT | Text ohne Laengenbeschraenkung |
Datums-Datentypen
CREATE TABLE ereignisse (
id INTEGER PRIMARY KEY,
titel TEXT NOT NULL,
datum DATE NOT NULL, -- Nur Datum
zeitpunkt TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- Datum + Uhrzeit
dauer INTEGER -- Dauer in Minuten
);
Einschraenkungen (Constraints)
Constraints definieren Regeln fuer die Daten in deinen Spalten:
NOT NULL - Wert erforderlich
CREATE TABLE mitarbeiter (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL, -- Name muss angegeben werden
email TEXT, -- Email ist optional (darf NULL sein)
abteilung TEXT NOT NULL -- Abteilung muss angegeben werden
);
UNIQUE - Eindeutiger Wert
CREATE TABLE benutzer (
id INTEGER PRIMARY KEY,
benutzername TEXT UNIQUE NOT NULL, -- Muss eindeutig sein
email TEXT UNIQUE NOT NULL -- Muss eindeutig sein
);
DEFAULT - Standardwert
CREATE TABLE aufgaben (
id INTEGER PRIMARY KEY,
titel TEXT NOT NULL,
status TEXT DEFAULT 'offen',
prioritaet INTEGER DEFAULT 3,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Beim INSERT werden Standardwerte automatisch gesetzt:
INSERT INTO aufgaben (id, titel) VALUES (1, 'Einkaufen');
-- status = 'offen', prioritaet = 3, erstellt_am = jetzt
CHECK - Wertebedingung
CREATE TABLE produkte_v2 (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
preis DECIMAL(10,2) CHECK (preis > 0), -- Preis muss positiv sein
rabatt DECIMAL(3,2) CHECK (rabatt >= 0 AND rabatt <= 1), -- 0 bis 1
lagerbestand INTEGER CHECK (lagerbestand >= 0) -- Nicht negativ
);
PRIMARY KEY - Primaerschluessel
Einfacher Primaerschluessel
CREATE TABLE kategorien (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE
);
Zusammengesetzter Primaerschluessel
-- Primaerschluessel aus mehreren Spalten
CREATE TABLE kurs_teilnahme (
kurs_id INTEGER,
teilnehmer_id INTEGER,
anmeldedatum DATE DEFAULT CURRENT_DATE,
PRIMARY KEY (kurs_id, teilnehmer_id)
);
Auto-Increment
-- PostgreSQL: SERIAL
CREATE TABLE blog_posts (
id SERIAL PRIMARY KEY,
titel TEXT NOT NULL,
inhalt TEXT
);
-- PostgreSQL (modern): GENERATED ALWAYS
CREATE TABLE blog_posts_v2 (
id INTEGER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
titel TEXT NOT NULL,
inhalt TEXT
);
-- SQLite: INTEGER PRIMARY KEY ist automatisch auto-increment
CREATE TABLE blog_posts (
id INTEGER PRIMARY KEY,
titel TEXT NOT NULL,
inhalt TEXT
);
FOREIGN KEY - Fremdschluessel
Fremdschluessel verknuepfen Tabellen miteinander:
CREATE TABLE autoren (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE buecher (
id INTEGER PRIMARY KEY,
titel TEXT NOT NULL,
autor_id INTEGER,
FOREIGN KEY (autor_id) REFERENCES autoren(id)
);
Oder die kuerzere Schreibweise:
CREATE TABLE buecher (
id INTEGER PRIMARY KEY,
titel TEXT NOT NULL,
autor_id INTEGER REFERENCES autoren(id)
);
Fremdschluessel mit Aktionen
CREATE TABLE kommentare (
id INTEGER PRIMARY KEY,
beitrag_id INTEGER REFERENCES blog_posts(id) ON DELETE CASCADE,
autor TEXT NOT NULL,
text TEXT NOT NULL,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Wenn ein Blog-Post geloescht wird, werden seine Kommentare automatisch mitgeloescht
Tabelle nur erstellen, wenn sie nicht existiert
-- Fehler, wenn die Tabelle schon existiert:
CREATE TABLE kunden (id INTEGER PRIMARY KEY);
-- Kein Fehler, wenn die Tabelle schon existiert:
CREATE IF NOT EXISTS TABLE kunden (id INTEGER PRIMARY KEY);
-- Korrekte Syntax:
CREATE TABLE IF NOT EXISTS kunden (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
DROP TABLE - Tabelle loeschen
-- Tabelle loeschen (Fehler, wenn sie nicht existiert)
DROP TABLE alte_tabelle;
-- Tabelle loeschen, wenn sie existiert
DROP TABLE IF EXISTS alte_tabelle;
Vorsicht: DROP TABLE loescht die Tabelle und alle Daten unwiderruflich!
Temporaere Tabellen
Temporaere Tabellen existieren nur fuer die aktuelle Sitzung:
CREATE TEMPORARY TABLE temp_berechnung (
produkt_id INTEGER,
neuer_preis DECIMAL(10,2)
);
-- Daten einfuegen und verwenden
INSERT INTO temp_berechnung
SELECT id, preis * 1.1 FROM produkte;
-- Die Tabelle verschwindet automatisch am Ende der Sitzung
Praxisbeispiel: Blog-System entwerfen
-- Benutzer
CREATE TABLE benutzer (
id INTEGER PRIMARY KEY,
benutzername VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
passwort_hash TEXT NOT NULL,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Blog-Beitraege
CREATE TABLE beitraege (
id INTEGER PRIMARY KEY,
titel VARCHAR(200) NOT NULL,
inhalt TEXT NOT NULL,
autor_id INTEGER NOT NULL REFERENCES benutzer(id),
veroeffentlicht BOOLEAN DEFAULT FALSE,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Kommentare
CREATE TABLE kommentare (
id INTEGER PRIMARY KEY,
beitrag_id INTEGER NOT NULL REFERENCES beitraege(id) ON DELETE CASCADE,
autor_id INTEGER NOT NULL REFERENCES benutzer(id),
text TEXT NOT NULL,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Tags
CREATE TABLE tags (
id INTEGER PRIMARY KEY,
name VARCHAR(50) UNIQUE NOT NULL
);
-- Beitrag-Tag Zuordnung (N:M)
CREATE TABLE beitrag_tags (
beitrag_id INTEGER REFERENCES beitraege(id) ON DELETE CASCADE,
tag_id INTEGER REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (beitrag_id, tag_id)
);
Was kommt als Naechstes?
Im naechsten Tutorial gehen wir tiefer auf SQL-Datentypen ein und lernst du die Unterschiede zwischen PostgreSQL und SQLite.
Zusammenfassung
- CREATE TABLE erstellt neue Tabellen mit definierten Spalten
- Jede Spalte hat einen Datentyp (INTEGER, TEXT, DECIMAL, DATE, …)
- Constraints schuetzen die Datenqualitaet (NOT NULL, UNIQUE, CHECK)
- PRIMARY KEY identifiziert Datensaetze eindeutig
- FOREIGN KEY verknuepft Tabellen und erzwingt referentielle Integritaet
- IF NOT EXISTS verhindert Fehler bei bestehenden Tabellen
- DROP TABLE loescht eine Tabelle unwiderruflich
Uebungen
- Einfach: Erstelle eine Tabelle
notizenmit den Spalten id, titel (Pflichtfeld), inhalt und erstellt_am. - Constraints: Erstelle eine Tabelle
mitarbeitermit id, name (Pflicht), email (eindeutig), gehalt (muss positiv sein) und abteilung. - Fremdschluessel: Erstelle zwei Tabellen
kurseundteilnehmermit einer Zwischentabellekurs_anmeldung. - Blog-System: Ergaenze das Blog-System um eine Tabelle
likes(ein Benutzer kann einen Beitrag einmal liken). - Design: Entwirf ein Tabellenschema fuer eine einfache To-Do-App mit Benutzern, Listen und Aufgaben.
-- Loesung zu Uebung 1:
CREATE TABLE notizen (
id INTEGER PRIMARY KEY,
titel TEXT NOT NULL,
inhalt TEXT,
erstellt_am TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Pro-Tipp: Plane deine Tabellenstruktur auf Papier oder in einem Diagramm, bevor du CREATE TABLE schreibst. Ueberlege dir: Welche Tabellen brauche ich? Welche Beziehungen bestehen? Welche Spalten sind Pflichtfelder? Ein gutes Schema spart spaeter viel Aerger mit Dateninkonsistenzen.