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

# 데이터베이스 설정

> Laravel의 데이터베이스 접속 설정, read/write 분리, 다중 접속, SQL 실행, 쿼리 리스닝, transaction의 기본을 설명합니다.

## 소개

Laravel은 다음 데이터베이스를 공식 지원합니다.

* MySQL / MariaDB
* PostgreSQL
* SQLite
* SQL Server

여러분은 원시 SQL, Query Builder, Eloquent ORM 중 어느 것을 사용하든 동일한 접속 설정을 사용할 수 있습니다.

<Info>
  이 페이지는 데이터베이스 접속의 전제를 다룹니다. 실용적인 쿼리는 [Query Builder](/ko/query-builder), 스키마 관리는 [Migrations](/ko/migrations), 초기 데이터 투입은 [Seeding](/ko/seeding)을 참조해 주세요.
</Info>

## 설정

데이터베이스 설정은 `config/database.php`에 통합되어 있습니다.
여러분은 `default`에서 기본 접속명을 선택하고, `connections`에서 접속별 상세를 정의합니다.

```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', ''),
    ],
],
```

`.env`에는 최소한 다음을 설정해 주세요.

```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
```

SQLite를 사용하는 경우에는 `DB_CONNECTION=sqlite`와 `DB_DATABASE`의 경로를 설정합니다.

## 읽기·쓰기 접속 분리

읽기(`SELECT`)와 쓰기(`INSERT` / `UPDATE` / `DELETE`)를 별도의 호스트로 분리하려면 동일 접속 내에서 `read`와 `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', ''),
],
```

`sticky`를 `true`로 하면 동일 요청 내에서 쓰기 후의 읽기가 write 접속으로 고정됩니다.

<Tip>
  레플리카 지연이 있는 구성에서는 `sticky`를 활성화하면 쓰기 직후 오래된 데이터를 읽을 위험을 줄일 수 있습니다.
</Tip>

## Pooled PostgreSQL 접속

PgBouncer 같은 트랜잭션 모드 접속 풀링을 제공하는 매니지드 PostgreSQL 서비스를 사용하는 경우, `pooled` 옵션과 `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'),
    ]),
],
```

`pooled`를 활성화하면 Laravel이 자동으로 배분을 수행합니다.

| 조작                                          | 사용되는 접속                            |
| ------------------------------------------- | ---------------------------------- |
| 애플리케이션 쿼리                                   | pooled(에뮬레이트 프리페어가 자동 활성화)         |
| 마이그레이션 / `db:wipe` / `db:show` / `db:table` | direct(자동)                         |
| `php artisan db`                            | direct(기본), `--pooled`로 pooled로 전환 |

애플리케이션 코드 내에서 명시적으로 direct 접속을 사용하고 싶은 경우, 접속 이름에 `::direct` 접미사를 붙여 주세요.

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

## 다중 데이터베이스 접속

여러분은 `config/database.php`에 접속을 여러 개 정의하고, `DB::connection()`으로 전환할 수 있습니다.

```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 쿼리 실행

`DB` 파사드는 쿼리 종류별로 전용 메서드를 가지고 있습니다.

```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>
  사용자 입력을 SQL 문자열에 직접 연결하지 마세요. 반드시 바인딩 인수를 사용해 SQL injection을 방지해 주세요.
</Warning>

## 쿼리 리스닝

실행된 SQL을 추적하고 싶을 때는 Service Provider의 `boot()`에서 `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,
        ]);
    });
}
```

## transaction

여러 갱신을 하나의 단위로 다루려면 `DB::transaction()`을 사용해 주세요.
예외가 발생하면 Laravel이 자동으로 롤백합니다.

```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');
});
```

데드락 재시도가 필요하다면 `attempts`를 지정할 수 있습니다.

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

수동으로 제어하고 싶은 경우에는 `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;
}
```

## 다음 단계

<Card title="Query Builder" icon="table" href="/ko/query-builder">
  접속 설정을 사용해 안전하게 쿼리를 조립하는 방법을 배웁니다.
</Card>

<Card title="Migrations" icon="hammer" href="/ko/migrations">
  접속된 데이터베이스의 스키마를 버전 관리하는 방법을 배웁니다.
</Card>

<Card title="Seeding" icon="seedling" href="/ko/seeding">
  개발·테스트용 데이터를 재현 가능한 형태로 투입하는 방법을 배웁니다.
</Card>


## Related topics

- [설치](/ko/installation.md)
- [Socialite - Laravel Bluesky](/ko/packages/laravel-bluesky/socialite.md)
- [데이터베이스 시딩](/ko/seeding.md)
- [데이터베이스 테스트](/ko/database-testing.md)
- [데이터베이스 마이그레이션](/ko/migrations.md)
