메인 콘텐츠로 건너뛰기

소개

Laravel은 다음 데이터베이스를 공식 지원합니다.
  • MySQL / MariaDB
  • PostgreSQL
  • SQLite
  • SQL Server
여러분은 원시 SQL, Query Builder, Eloquent ORM 중 어느 것을 사용하든 동일한 접속 설정을 사용할 수 있습니다.
이 페이지는 데이터베이스 접속의 전제를 다룹니다. 실용적인 쿼리는 Query Builder, 스키마 관리는 Migrations, 초기 데이터 투입은 Seeding을 참조해 주세요.

설정

데이터베이스 설정은 config/database.php에 통합되어 있습니다. 여러분은 default에서 기본 접속명을 선택하고, connections에서 접속별 상세를 정의합니다.
// 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에는 최소한 다음을 설정해 주세요.
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=sqliteDB_DATABASE의 경로를 설정합니다.

읽기·쓰기 접속 분리

읽기(SELECT)와 쓰기(INSERT / UPDATE / DELETE)를 별도의 호스트로 분리하려면 동일 접속 내에서 readwrite를 설정해 주세요.
'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', ''),
],
stickytrue로 하면 동일 요청 내에서 쓰기 후의 읽기가 write 접속으로 고정됩니다.
레플리카 지연이 있는 구성에서는 sticky를 활성화하면 쓰기 직후 오래된 데이터를 읽을 위험을 줄일 수 있습니다.

Pooled PostgreSQL 접속

PgBouncer 같은 트랜잭션 모드 접속 풀링을 제공하는 매니지드 PostgreSQL 서비스를 사용하는 경우, pooled 옵션과 direct 옵션을 설정해 주세요.
'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:tabledirect(자동)
php artisan dbdirect(기본), --pooled로 pooled로 전환
애플리케이션 코드 내에서 명시적으로 direct 접속을 사용하고 싶은 경우, 접속 이름에 ::direct 접미사를 붙여 주세요.
DB::connection('pgsql::direct')->statement('create extension if not exists "uuid-ossp"');

다중 데이터베이스 접속

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

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

SQL 쿼리 실행

DB 파사드는 쿼리 종류별로 전용 메서드를 가지고 있습니다.
use Illuminate\Support\Facades\DB;

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

DB::insert('insert into users (name, email) values (?, ?)', ['Taylor', '[email protected]']);

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

쿼리 리스닝

실행된 SQL을 추적하고 싶을 때는 Service Provider의 boot()에서 DB::listen()을 등록해 주세요.
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이 자동으로 롤백합니다.
use Illuminate\Support\Facades\DB;

DB::transaction(function () {
    DB::update('update users set votes = 1');
    DB::delete('delete from posts where archived = 1');
});
데드락 재시도가 필요하다면 attempts를 지정할 수 있습니다.
DB::transaction(function () {
    // ...
}, attempts: 5);
수동으로 제어하고 싶은 경우에는 beginTransaction / rollBack / commit을 사용해 주세요.
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;
}

다음 단계

Query Builder

접속 설정을 사용해 안전하게 쿼리를 조립하는 방법을 배웁니다.

Migrations

접속된 데이터베이스의 스키마를 버전 관리하는 방법을 배웁니다.

Seeding

개발·테스트용 데이터를 재현 가능한 형태로 투입하는 방법을 배웁니다.
마지막 수정일 2026년 7월 13일