
# Esquema

Os esquemas são opcionais. Um esquema tem duas funções independentes: valida cada
operação de gravação e declara quais campos recebem [índices](https://storh.inline0.dev/pt/docs/indexes). Coleções
sem esquema aceitam dados de qualquer array.

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

O nome da coleção no esquema deve corresponder ao nome da coleção no armazenamento;
a construção gera um erro caso contrário. Passar o esquema ao construtor também
sincroniza imediatamente os índices declarados.

## Regras de validação

- Os campos `required` precisam estar presentes nos dados gravados. A verificação considera a presença: um `null` explícito satisfaz um campo obrigatório.
- Os campos tipados são verificados somente quando estão presentes e não são nulos. Um campo `string` rejeita um valor `int`; um campo `float` aceita tanto `float` quanto `int`.
- Os campos `mixed` aceitam qualquer valor e são úteis para marcar um campo como obrigatório ou indexado sem restringir seu tipo.
- Campos não declarados no esquema não têm restrições.

Uma validação malsucedida gera um `StorageException` antes de qualquer gravação.

## Tipos e sinalizadores de campo

Tipos compatíveis: `string`, `int`, `float`, `bool`, `mixed`.

Sinalizadores por campo: `index()` (índice de igualdade), `unique()` (unicidade aplicada
no momento da gravação), `range()` (índice ordenado para `gt`/`lt`/`between`/`prefix` e
consultas de intervalo ordenadas) e `required()`.

## Alterações no esquema

Os índices são sincronizados quando o armazenamento é construído. Se uma alteração no esquema modifica
o conjunto de índices declarados, o manifesto de índices muda e os índices afetados
são reconstruídos a partir dos registros existentes; alterações nas regras de validação se aplicam
somente a gravações futuras e nunca reescrevem registros armazenados.

O mesmo objeto `Schema` pode ser reutilizado para mapear colunas tipadas em um espelho [SQL](https://storh.inline0.dev/pt/docs/sql-mirror), inclusive em coleções cujo armazenamento não usa o esquema em si.
