Claude Code MySQL: Datenbankdesign, Queries und Migrationen mit KI

MySQL ist noch immer die meistgenutzte relationale Datenbank der Welt — in Start-ups genauso wie in Konzernen. Und trotzdem: Datenbankarbeit kostet unverhältnismäßig viel Zeit. Schema-Entscheidungen, die sich erst drei Monate später als falsch herausstellen. JOINs, bei denen man nach zwanzig Minuten immer noch keinen richtigen Output bekommt. Migrations-Skripte, die man in Prod ausführt und dann die Hände faltet.

Claude Code ändert das. Nicht weil es Magie ist, sondern weil es das gesamte Datenbankschema, die bestehenden Queries und den Applikationscode gleichzeitig liest — und dann konkrete, auf deinen Kontext zugeschnittene SQL schreibt statt generische Stack-Overflow-Snippets. Dieser Artikel zeigt, wie das in der Praxis aussieht.

Claude Code Mastery — Datenbanken, Agents, Hooks auf Deutsch

MySQL ist nur ein Thema: der Kurs zeigt, wie du Claude Code für den gesamten Backend-Stack produktiv einsetzt. Einmalig bezahlt, kein Abo.

Zum Kurs — Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht

1. MySQL-Installation und Konfiguration mit Claude Code

Wer MySQL frisch aufsetzt, kennt die typischen Stolpersteine: Zeichensatz-Probleme mit latin1 statt utf8mb4, fehlende Konfigurationsoptimierungen für den jeweiligen Workload, oder Benutzerrechte die entweder zu eng oder viel zu weit sind. Claude Code löst das nicht durch Raten, sondern durch Lesen — deiner vorhandenen Config, deines Systems, deiner Anforderungen.

claude "Ich setze MySQL 8.0 auf Ubuntu 22.04 auf für eine Node.js-App
mit ca. 50 gleichzeitigen Verbindungen. Zeig mir die optimale
my.cnf-Konfiguration und erkläre jeden Parameter."

Claude Code liest den Systemkontext, gibt dir eine vollständige my.cnf mit Erklärungen — innodb_buffer_pool_size passend zum verfügbaren RAM, max_connections mit Puffer, character-set-server = utf8mb4 von Anfang an. Keine Copy-Paste-Config aus 2018 die auf deinem System nicht passt.

Tipp: Starte Claude Code immer aus dem Root-Verzeichnis deines Projekts. So sieht es deine .env-Dateien, vorhandene Konfigurationen und Datenbankschemas — und kann passgenau antworten statt generisch.

2. Schema-Design: CREATE TABLE und ALTER TABLE

Das Datenbankschema ist die Grundlage für alles. Ein schlecht entworfenes Schema zieht sich durch den gesamten Entwicklungszyklus — schlechte Performance, schwierige Queries, komplizierte Migrations. Claude Code hilft dir, von Anfang an die richtigen Entscheidungen zu treffen.

claude "Entwirf das Datenbankschema für einen Online-Shop:
Produkte, Kategorien (hierarchisch), Benutzer, Bestellungen,
Bestellpositionen. MySQL 8.0, InnoDB, utf8mb4."

Das Ergebnis ist kein generisches Schema — Claude Code denkt die Beziehungen durch und gibt dir normalisierte Tabellen mit sinnvollen Datentypen, Foreign Keys und Constraints:

-- Kategorien mit Self-Join für Hierarchie
CREATE TABLE categories (
  id         INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  parent_id  INT UNSIGNED NULL,
  name       VARCHAR(255) NOT NULL,
  slug       VARCHAR(255) NOT NULL UNIQUE,
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  CONSTRAINT fk_cat_parent
    FOREIGN KEY (parent_id) REFERENCES categories(id)
    ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

-- Produkte
CREATE TABLE products (
  id          INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  category_id INT UNSIGNED NOT NULL,
  sku         VARCHAR(100) NOT NULL UNIQUE,
  name        VARCHAR(500) NOT NULL,
  price       DECIMAL(10,2) NOT NULL,
  stock       INT UNSIGNED NOT NULL DEFAULT 0,
  created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  CONSTRAINT fk_product_category
    FOREIGN KEY (category_id) REFERENCES categories(id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

ALTER TABLE ohne Datenverlust

Schema-Änderungen an bestehenden Produktionsdatenbanken sind heikel. Claude Code begleitet dich dabei mit einer Analyse der Auswirkungen, bevor die erste Zeile SQL ausgeführt wird:

claude "Ich muss in der Tabelle 'orders' eine neue Spalte 'coupon_code'
hinzufügen (VARCHAR 50, nullable) und einen Index auf (user_id, created_at).
Die Tabelle hat ca. 2 Millionen Zeilen. Was sind die Risiken und
wie führe ich das sicher durch?"

3. SELECT mit JOINs: INNER, LEFT, RIGHT

JOINs sind das Herzstück relationaler Datenbanken — und gleichzeitig der häufigste Ort, wo Queries langsam werden oder falsche Ergebnisse liefern. Claude Code schreibt JOINs nicht aus dem Gedächtnis, sondern liest dein Schema und generiert passende Queries.

claude "Schreib eine Query die alle Bestellungen der letzten 30 Tage
abruft, mit Benutzername, Gesamtbetrag und Anzahl der Positionen.
Zeig auch Benutzer ohne Bestellungen."

Das Ergebnis kombiniert INNER und LEFT JOIN korrekt:

-- Benutzer mit Bestellungen (LEFT JOIN zeigt auch Benutzer ohne)
SELECT
  u.id                              AS user_id,
  u.email,
  COUNT(o.id)                       AS order_count,
  COALESCE(SUM(oi.qty * oi.price), 0) AS total_spent
FROM users u
LEFT JOIN orders o
  ON o.user_id = u.id
  AND o.created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY)
LEFT JOIN order_items oi
  ON oi.order_id = o.id
GROUP BY u.id, u.email
ORDER BY total_spent DESC;

Claude Code erklärt dabei auch, warum LEFT statt INNER JOIN — weil das die Anforderung war, Benutzer ohne Bestellungen einzuschließen. Nicht einfach eine Query hinwerfen, sondern den Denkweg zeigen.

4. Indexes: PRIMARY, UNIQUE und zusammengesetzte Indexes

Falsch gesetzte Indexes sind der häufigste Grund für langsame MySQL-Queries. Zu wenige Indexes bedeuten Full-Table-Scans. Zu viele verlangsamen Schreibvorgänge. Claude Code analysiert deine Queries und dein Schema und empfiehlt gezielt:

claude "EXPLAIN ANALYZE dieser Query läuft 2 Sekunden auf 500k Zeilen:
SELECT * FROM orders WHERE user_id = 42 AND status = 'pending'
ORDER BY created_at DESC LIMIT 20.
Welche Indexes fehlen?"

Die Antwort ist konkret — kein "füge einen Index auf user_id hinzu", sondern der richtige zusammengesetzte Index in der richtigen Reihenfolge:

-- Zusammengesetzter Index: Gleichheitsbedingungen zuerst, dann Sort-Spalte
CREATE INDEX idx_orders_user_status_date
  ON orders (user_id, status, created_at DESC);

-- Für den häufigen Fall "alle offenen Bestellungen":
-- Partial Index wäre in MySQL nicht direkt möglich, aber:
CREATE INDEX idx_orders_pending
  ON orders (user_id, created_at DESC)
  WHERE status = 'pending';
-- (Funktioniert ab MySQL 8.0.13 mit expression indexes)

Wichtig: Indexes auf Produktionsdatenbanken immer mit CREATE INDEX ... ALGORITHM=INPLACE, LOCK=NONE hinzufügen, um Table-Locks zu vermeiden. Claude Code weist dich darauf hin — frage explizit nach dem sicheren Weg für Live-Systeme.

5. Stored Procedures und Transactions

Komplexe Datenbankoperationen gehören in Stored Procedures oder werden mit Transactions abgesichert. Claude Code schreibt beides — und erklärt, wann welcher Ansatz sinnvoll ist.

Transactions: BEGIN / COMMIT / ROLLBACK

-- Bestellung mit Lagerbestandsprüfung transaktional abschließen
START TRANSACTION;

-- Lagerbestand prüfen und sperren (FOR UPDATE verhindert Race Conditions)
SELECT stock INTO @current_stock
FROM products
WHERE id = 42
FOR UPDATE;

-- Abbrechen wenn nicht genug Bestand
IF @current_stock < 3 THEN
  ROLLBACK;
  SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = 'Nicht genug Lagerbestand';
END IF;

-- Bestand reduzieren
UPDATE products SET stock = stock - 3 WHERE id = 42;

-- Bestellung anlegen
INSERT INTO orders (user_id, status) VALUES (7, 'confirmed');
SET @order_id = LAST_INSERT_ID();

INSERT INTO order_items (order_id, product_id, qty, price)
VALUES (@order_id, 42, 3, 29.99);

COMMIT;

Claude Code erkennt selbstständig, wo Transactions nötig sind: überall dort, wo mehrere zusammenhängende Schreibvorgänge atomar sein müssen. Bestandsreduktion plus Bestellanlage ist ein klassischer Fall — geht einer der Schritte schief, muss der andere zurückgerollt werden.

6. Datenbankverbindung in Node.js mit mysql2

Der Standard für MySQL in Node.js ist mysql2 mit Promise-Support. Claude Code liest deine bestehende Projektstruktur und generiert Code der zu deinem Setup passt — kein generisches Snippet aus der Dokumentation.

// db/connection.js
import mysql from 'mysql2/promise';

const pool = mysql.createPool({
  host:     process.env.DB_HOST,
  port:     Number(process.env.DB_PORT) || 3306,
  user:     process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit:    10,
  queueLimit:         0,
  timezone:           '+00:00',
  charset:            'utf8mb4',
});

export default pool;
// Beispiel: Bestellungen eines Nutzers abrufen
import pool from './db/connection.js';

export async function getOrdersByUser(userId) {
  const [rows] = await pool.execute(
    `SELECT o.id, o.status, o.created_at,
            SUM(oi.qty * oi.price) AS total
     FROM orders o
     JOIN order_items oi ON oi.order_id = o.id
     WHERE o.user_id = ?
     GROUP BY o.id
     ORDER BY o.created_at DESC`,
    [userId]          // Parameterized query — kein SQL-Injection-Risiko
  );
  return rows;
}

Sicherheitsregel: Datenbankpasswörter gehören ausschließlich in Umgebungsvariablen (process.env.DB_PASSWORD). Niemals Klartext-Credentials im Code oder in Commits. Claude Code hält diese Regel ein und weist aktiv darauf hin, wenn es verdächtige Muster im Code sieht.

7. Datenbankverbindung in Python mit PyMySQL und SQLAlchemy

In Python-Projekten gibt es zwei gängige Wege zu MySQL: PyMySQL für direktes SQL, SQLAlchemy für ORM-basierten Zugriff. Claude Code kennt beide und wählt je nach Kontext den passenden Ansatz.

# Mit SQLAlchemy (async, für FastAPI / moderne Python-Apps)
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
import os

DATABASE_URL = (
    f"mysql+aiomysql://{os.environ['DB_USER']}:"
    f"{os.environ['DB_PASSWORD']}@"
    f"{os.environ['DB_HOST']}:{os.environ.get('DB_PORT', 3306)}/"
    f"{os.environ['DB_NAME']}?charset=utf8mb4"
)

engine = create_async_engine(DATABASE_URL, pool_size=10, echo=False)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def get_db():
    async with AsyncSessionLocal() as session:
        yield session
# Mit PyMySQL für einfaches direktes SQL
import pymysql
import os

def get_connection():
    return pymysql.connect(
        host=os.environ["DB_HOST"],
        user=os.environ["DB_USER"],
        password=os.environ["DB_PASSWORD"],
        database=os.environ["DB_NAME"],
        charset="utf8mb4",
        cursorclass=pymysql.cursors.DictCursor,
    )

def fetch_pending_orders(user_id: int):
    with get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                "SELECT id, status, created_at FROM orders "
                "WHERE user_id = %s AND status = 'pending'",
                (user_id,)
            )
            return cur.fetchall()

8. Migrationen mit Flyway oder mysql2

Migrationen sind das Sorgenkind jedes Teams: Wer hat welches Schema-Update wann eingespielt? Stimmt die Produktionsdatenbank noch mit dem Entwicklungsstand überein? Claude Code hilft nicht nur beim Schreiben von Migrations-Skripten, sondern auch beim Aufsetzen einer sauberen Migrations-Strategie.

Einfache Migrations mit mysql2 (Node.js)

// migrations/001_create_orders.sql
-- Migration: 001
-- Datum: 2026-09-11
-- Beschreibung: Bestelltabellen anlegen

CREATE TABLE IF NOT EXISTS orders (
  id         INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  user_id    INT UNSIGNED NOT NULL,
  status     ENUM('pending','confirmed','shipped','delivered','cancelled')
             NOT NULL DEFAULT 'pending',
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE IF NOT EXISTS schema_migrations (
  version    VARCHAR(50) PRIMARY KEY,
  applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Flyway für Teams und CI/CD

Für größere Teams empfiehlt Claude Code Flyway: Migrationen liegen als versionierte SQL-Dateien im Repository, Flyway verwaltet den Zustand automatisch und verhindert doppeltes Einspielen.

claude "Ich möchte Flyway in meinem Java-Spring-Projekt für MySQL
einrichten. Zeig mir die Maven-Dependency, die application.properties
und wie ich die erste Migration anlege."
"Flyway sucht automatisch nach Dateien nach dem Muster V{Version}__{Beschreibung}.sql im Verzeichnis src/main/resources/db/migration. Die Reihenfolge ist durch die Versionsnummer garantiert. Einmal eingespielt, werden Migrationen nie nochmal ausgeführt — Flyway speichert den Hash in der flyway_schema_history-Tabelle."

9. Der Claude Code Workflow für MySQL-Arbeit

Das Besondere an Claude Code ist nicht eine einzelne Funktion — es ist der durchgehende Kontext über alle Schritte hinweg. Du arbeitest nicht mit einem Chatbot, der nach jeder Antwort alles vergisst, sondern mit einem Werkzeug das dein gesamtes Projekt liest und kennt.

Ein typischer Workflow in der Praxis:

  1. Schema-Entwurf besprechen und iterieren — Claude Code sieht die bestehenden Tabellen und schlägt passende Ergänzungen vor
  2. Query schreiben lassen, dann mit EXPLAIN ANALYZE prüfen — Claude Code liest das Explain-Output und empfiehlt Indexes
  3. Migrations-Skript generieren — basierend auf dem Diff zwischen aktuellem und gewünschtem Schema
  4. Applikationscode anpassen — Claude Code sieht deine bestehenden Repository-Klassen und erweitert sie konsistent
  5. Tests schreiben — Integration Tests mit einer In-Memory-Datenbank oder einem Test-Container
claude "Ich habe das Schema in schema.sql geändert und einen neuen
Produkt-Typ 'digital' hinzugefügt. Erstelle:
1. Ein Flyway-Migrations-Skript (V3__add_digital_products.sql)
2. Die entsprechende TypeScript-Repository-Methode
3. Einen Integration-Test mit mysql2"

Claude Code liest schema.sql, die bestehenden Repository-Dateien und die vorhandenen Tests — und liefert alle drei Dateien konsistent und fertig. Kein manuelles Zusammenführen, kein "das musst du noch anpassen".

Zwei verwandte Artikel die auf diesem Thema aufbauen:


Claude Code Mastery — von MySQL bis zum produktiven Agenten

Datenbanken sind ein Thema, Agents, MCP-Server und Hooks sind die nächsten. Der Kurs zeigt den gesamten Workflow auf Deutsch — einmalig bezahlt, kein Abo.

Jetzt starten → Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht

Kurs · Claude Code Mastery

MySQL, Datenbanken, Agents — alles auf Deutsch

Schema-Design. Queries. Migrationen. MCP. Hooks. Multi-Agent-Workflows. Einmalig bezahlt — kein Abo, keine Plattformabhängigkeit.

Jetzt einsteigen → Kursübersicht ansehen →

Einmalzahlung · Kein Abo · 14 Tage Rückgaberecht