> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Datenbankkonfiguration

> Erläutert die Konfiguration von Datenbankverbindungen in Laravel, Read/Write-Splitting, mehrere Verbindungen, SQL-Ausführung, Query Listening und die Grundlagen von Transaktionen.

## Einführung

Laravel unterstützt offiziell die folgenden Datenbanken:

* MySQL / MariaDB
* PostgreSQL
* SQLite
* SQL Server

Sie können dieselbe Verbindungskonfiguration mit Raw SQL, dem Query Builder oder dem Eloquent ORM verwenden.

<Info>
  Diese Seite behandelt die Grundlagen zu Datenbankverbindungen. Praxisnahe Queries finden Sie beim [Query Builder](/de/query-builder), Schema-Management bei [Migrations](/de/migrations) und das Einspielen initialer Daten bei [Seeding](/de/seeding).
</Info>

## Konfiguration

Die Datenbank-Konfiguration ist zentral in `config/database.php` gebündelt.
Über `default` legen Sie die Standardverbindung fest, in `connections` konfigurieren Sie die einzelnen Verbindungen im Detail.

```mermaid theme={null}
flowchart TD
    A[".env"] --> B["config/database.php"]
    B --> C["default connection"]
    B --> D["connections.mysql"]
    B --> E["connections.pgsql"]
    B --> F["connections.sqlite"]
    C --> G["DB-Facade / Query Builder / Eloquent"]
```

```php theme={null}
// config/database.php
'default' => env('DB_CONNECTION', 'sqlite'),

'connections' => [
    'mysql' => [
        'driver' => 'mysql',
        'host' => env('DB_HOST', '127.0.0.1'),
        'port' => env('DB_PORT', '3306'),
        'database' => env('DB_DATABASE', 'laravel'),
        'username' => env('DB_USERNAME', 'root'),
        'password' => env('DB_PASSWORD', ''),
    ],
],
```

In der `.env` sollten mindestens folgende Werte gesetzt sein:

```ini theme={null}
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=app
DB_USERNAME=app_user
DB_PASSWORD=secret
```

Für SQLite setzen Sie `DB_CONNECTION=sqlite` und den Pfad in `DB_DATABASE`.

## Trennung von Lese- und Schreibverbindung

Wenn Sie Lese- (`SELECT`) und Schreiboperationen (`INSERT` / `UPDATE` / `DELETE`) auf verschiedene Hosts verteilen möchten, konfigurieren Sie innerhalb derselben Verbindung `read` und `write`.

```php theme={null}
'mysql' => [
    'driver' => 'mysql',
    'read' => [
        'host' => ['10.0.0.10', '10.0.0.11'],
    ],
    'write' => [
        'host' => ['10.0.0.20'],
    ],
    'sticky' => true,

    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'laravel'),
    'username' => env('DB_USERNAME', 'root'),
    'password' => env('DB_PASSWORD', ''),
],
```

Mit `sticky` auf `true` werden Leseoperationen innerhalb desselben Requests nach einem Schreibvorgang auf die Schreibverbindung geleitet.

<Tip>
  In Setups mit Replikations-Lag verringert `sticky` das Risiko, dass Sie direkt nach einem Schreibvorgang veraltete Daten lesen.
</Tip>

## Pooled PostgreSQL-Verbindungen

Wenn Sie einen verwalteten PostgreSQL-Dienst mit transaktionsbasiertem Connection-Pooling verwenden (etwa PgBouncer), konfigurieren Sie die Optionen `pooled` und `direct`.

```php theme={null}
'pgsql' => [
    'driver' => 'pgsql',
    // ...
    'pooled' => env('DB_POOLED', false),
    'direct' => array_filter([
        'host' => env('DB_DIRECT_HOST'),
        'port' => env('DB_DIRECT_PORT'),
        'username' => env('DB_DIRECT_USERNAME'),
        'password' => env('DB_DIRECT_PASSWORD'),
        'sslmode' => env('DB_DIRECT_SSLMODE'),
    ]),
],
```

Ist `pooled` aktiviert, kümmert sich Laravel automatisch um die richtige Zuordnung.

| Operation                                        | Verwendete Verbindung                                               |
| ------------------------------------------------ | ------------------------------------------------------------------- |
| Anwendungs-Queries                               | pooled (emulierte Prepared Statements werden automatisch aktiviert) |
| Migrationen / `db:wipe` / `db:show` / `db:table` | direct (automatisch)                                                |
| `php artisan db`                                 | direct (Standard); mit `--pooled` auf pooled umschalten             |

Wenn Sie in Anwendungscode explizit die Direct-Verbindung nutzen möchten, hängen Sie den Suffix `::direct` an den Verbindungsnamen.

```php theme={null}
DB::connection('pgsql::direct')->statement('create extension if not exists "uuid-ossp"');
```

## Mehrere Datenbankverbindungen

Sie können in `config/database.php` mehrere Verbindungen definieren und mit `DB::connection()` zwischen ihnen wechseln.

```php theme={null}
use Illuminate\Support\Facades\DB;

$users = DB::connection('sqlite')->select('select * from users');
$pdo = DB::connection('pgsql')->getPdo();
```

```mermaid theme={null}
flowchart LR
    A["DB::connection('mysql')"] --> B["Primary DB"]
    C["DB::connection('pgsql')"] --> D["Analytics DB"]
    E["DB::connection('sqlite')"] --> F["Local file DB"]
```

## SQL-Abfragen ausführen

Die `DB`-Facade stellt für jeden Query-Typ eine dedizierte Methode bereit.

```php theme={null}
use Illuminate\Support\Facades\DB;

$users = DB::select('select * from users where active = ?', [1]);

DB::insert('insert into users (name, email) values (?, ?)', ['Taylor', 'taylor@example.com']);

$affected = DB::update('update users set votes = 100 where name = ?', ['Taylor']);

$deleted = DB::delete('delete from sessions where user_id = ?', [1]);

DB::statement('drop table temporary_imports');
```

<Warning>
  Konkatenieren Sie niemals Nutzereingaben direkt in einen SQL-String. Verwenden Sie unbedingt Bindungsparameter, um SQL-Injection zu verhindern.
</Warning>

## Query Listening

Um ausgeführte SQL-Statements nachvollziehen zu können, registrieren Sie im `boot()` eines Service Providers einen Listener über `DB::listen()`.

```php theme={null}
use Illuminate\Database\Events\QueryExecuted;
use Illuminate\Support\Facades\DB;

public function boot(): void
{
    DB::listen(function (QueryExecuted $query) {
        logger()->debug('SQL executed', [
            'sql' => $query->toRawSql(),
            'time_ms' => $query->time,
        ]);
    });
}
```

## Transaktionen

Um mehrere Änderungen als atomare Einheit zu behandeln, verwenden Sie `DB::transaction()`.
Tritt eine Ausnahme auf, führt Laravel automatisch einen Rollback aus.

```php theme={null}
use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    DB::update('update users set votes = 1');
    DB::delete('delete from posts where archived = 1');
});
```

Ist ein automatischer Retry bei Deadlocks erforderlich, geben Sie `attempts` an.

```php theme={null}
DB::transaction(function () {
    // ...
}, attempts: 5);
```

Möchten Sie die Transaktion manuell steuern, verwenden Sie `beginTransaction` / `rollBack` / `commit`.

```php theme={null}
DB::beginTransaction();

try {
    DB::update('update accounts set balance = balance - 100 where id = ?', [1]);
    DB::update('update accounts set balance = balance + 100 where id = ?', [2]);

    DB::commit();
} catch (\Throwable $e) {
    DB::rollBack();
    throw $e;
}
```

## Nächste Schritte

<Card title="Query Builder" icon="table" href="/de/query-builder">
  Erfahren Sie, wie Sie Abfragen sicher mithilfe Ihrer Verbindungen zusammenstellen.
</Card>

<Card title="Migrations" icon="hammer" href="/de/migrations">
  Verwalten Sie das Schema Ihrer Datenbank versioniert.
</Card>

<Card title="Seeding" icon="seedling" href="/de/seeding">
  Bringen Sie Entwicklungs- und Testdaten reproduzierbar in Ihre Datenbank.
</Card>
