SnapOtter використовує PostgreSQL 17 з [Drizzle ORM](https://orm.drizzle.team/) (pg-core / node-postgres) для збереження даних. Схему визначено у `apps/api/src/db/schema.ts`.
З'єднання налаштовується через змінну середовища `DATABASE_URL` (за замовчуванням `postgres://snapotter:snapotter@postgres:5432/snapotter`). У Docker Compose контейнер Postgres зберігає свої дані в іменованому томі `SnapOtter-pgdata`.
## Таблиці {#tables}
### users {#users}
Зберігає облікові записи користувачів. Створюється автоматично під час першого запуску з `DEFAULT_USERNAME` та `DEFAULT_PASSWORD`.
Постійна бібліотека файлів. За замовчуванням збережене редагування додається як незалежний кореневий рядок («зберегти як новий»: `version` 1, `parentId` null, тож оригінал лишається у списку) або як пов'язана з батьківською версія, коли ви перезаписуєте оригінал (`parentId` встановлено, `version` збільшено, замінюючи його). Стовпець `toolChain` записує застосовані інструменти.
Стан інтерфейсу для кожного користувача з ключем за назвою налаштування. Зберігає закріплені інструменти головної сторінки, які записуються через `PUT /api/v1/preferences`.
| Стовпець | Тип | Примітки |
|---|---|---|
| `userId` | text | Зовнішній ключ на users, каскадне видалення. Первинний ключ разом із `key` |
| `key` | text | Назва налаштування. Первинний ключ разом із `userId` |
| `value` | jsonb | Вміст налаштування |
| `updatedAt` | timestamp | Час останнього запису |
Цей дамп бази даних не містить збережених об’єктів бібліотеки в `/data/files` або тривалому стані BullMQ у Redis. Створюйте резервні копії та відновлюйте їх за допомогою скоординованої процедури в [Безпека та посилення](/uk/guide/security#backup-and-recovery).
Не копіюйте живий каталог даних PostgreSQL за допомогою `tar`. Створюйте префікси імен томів за проектом, тому вирішуйте ідентифікатори змонтованих томів із `docker inspect` або вашої платформи зберігання, а не припускайте буквальну мітку `SnapOtter-pgdata`.
### Міграція з 1.x (SQLite) {#migrating-from-1-x-sqlite}
Оновлення з SnapOtter 1.x має власний посібник: див. [Оновлення з 1.x до 2.0](./upgrading). Коротко: повторно використайте свій наявний том `/data`, і 2.0 автоматично виявить та імпортує `/data/snapotter.db` під час першого запуску (або встановіть `SQLITE_MIGRATE_PATH`, щоб явно вказати на нього). Спершу зробіть резервну копію всього тому `/data`, а не лише `snapotter.db`: 1.x використовує режим SQLite WAL, тож зупинений контейнер часто залишає більшість своїх даних у `snapotter.db-wal` поруч із майже порожнім `snapotter.db`.