
# 스키마

스키마는 선택 사항입니다. 스키마는 서로 독립적인 두 가지 역할을 합니다. 모든 쓰기를 검증하고, 어떤 필드에 [인덱스](https://storh.inline0.dev/ko/docs/indexes)를 적용할지 선언합니다. 스키마가 없는 컬렉션은 모든 배열 데이터를 허용합니다.

```php
$schema = Schema::collection('posts')
    ->string('slug')->unique()
    ->string('status')->index()
    ->int('publishedAt')->range()
    ->bool('featured')
    ->required(['slug', 'status']);

$posts = new DocStore($root, 'posts', schema: $schema);
```

스키마의 컬렉션 이름은 저장소의 컬렉션 이름과 일치해야 하며, 그렇지 않으면 생성 시 오류가 발생합니다. 생성자에 스키마를 전달하면 선언된 인덱스도 즉시 동기화됩니다.

## 검증 규칙

- `required` 필드는 기록되는 데이터에 있어야 합니다. 존재 여부를 검사하므로 명시적인 `null`도 필수 필드 조건을 충족합니다.
- 형식이 지정된 필드는 존재하고 null이 아닐 때만 검사합니다. `string` 필드는 `int` 값을 거부하고, `float` 필드는 `float`와 `int`를 모두 허용합니다.
- `mixed` 필드는 모든 값을 허용하며, 형식을 제한하지 않고 필수 또는 인덱스 필드로 표시할 때 유용합니다.
- 스키마에 선언되지 않은 필드에는 제한이 없습니다.

검증에 실패하면 아무것도 기록되기 전에 `StorageException`가 발생합니다.

## 필드 유형 및 플래그

지원되는 유형: `string`, `int`, `float`, `bool`, `mixed`.

필드별 플래그: `index()` (동등성 인덱스), `unique()` (쓰기 시 고유성 적용), `range()` (`gt`/`lt`/`between`/`prefix` 및 정렬된 범위 쿼리용 정렬 인덱스), `required()`.

## 스키마 변경

저장소를 생성할 때 인덱스가 동기화됩니다. 스키마 변경으로 선언된 인덱스 집합이 달라지면 인덱스 매니페스트가 바뀌고 해당 인덱스는 기존 레코드로부터 다시 빌드됩니다. 검증 규칙 변경은 이후 쓰기에만 적용되며 저장된 레코드는 다시 쓰지 않습니다.

동일한 `Schema` 객체를 사용해 [SQL 미러](https://storh.inline0.dev/ko/docs/sql-mirror)의 형식 지정 열을 매핑할 수 있습니다. 저장소에서 해당 스키마를 사용하지 않는 컬렉션에도 적용할 수 있습니다.
