
# 架构

架构是可选的。架构有两项独立用途：验证每次写入，并声明哪些字段获得[索引](https://storh.inline0.dev/zh/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/zh/docs/sql-mirror) 中的有类型列，
即使集合自身的存储没有使用该模式，也同样适用。
