SurrealDB — молодая база данных на Rust, которая объединяет документную модель, графовые связи и привычные таблицы. Вместо отдельной СУБД для JSON, отдельной для связей и отдельной для кэша можно держать один сервис и описывать данные в SurrealQL. Разберём установку, схему, графовые запросы и безопасный запуск на своём сервере.
Что такое SurrealDB
Запись адресуется идентификатором вида таблица:id, например user:alice. Поля могут быть вложенными документами и массивами, а связи оформляются как настоящие рёбра графа через RELATE. При этом доступны транзакции, индексы, ограничения и права на уровне таблиц.
База поддерживает несколько бэкендов хранения: memory для тестов, RocksDB для одного узла и TiKV для распределённой конфигурации. Для небольшого проекта достаточно RocksDB на локальном диске.
Установка и запуск
Установщик скачивает бинарник в ~/.surrealdb. Для сервера удобнее заранее создать каталог данных и запускать процесс от отдельного пользователя. Не открывайте порт 8000 в интернет без прокси и пароля.
curl -sSf https://install.surrealdb.com | sh
sudo mkdir -p /var/lib/surrealdb
sudo chown $USER:$USER /var/lib/surrealdb
surreal start --user root --pass 'Str0ngPass' \
--bind 127.0.0.1:8000 rocksdb:/var/lib/surrealdb
Ключи —user и —pass создают root-пользователя при первом старте. Пароль храните в менеджере секретов, а не в истории команд. В контейнере данные монтируют в том, а порт публикуют только на localhost.
Проверить, что процесс слушает нужный адрес, можно через ss. Если база работает на другой машине, сначала настройте TLS и ограничьте доступ по сети.
Первое подключение
Клиент surreal sql открывает интерактивную сессию и позволяет выполнять запросы по одному. Namespace и database задаются при подключении: это логические пространства, между которыми данные не пересекаются.
surreal sql --endpoint http://127.0.0.1:8000 \
--user root --pass 'Str0ngPass' \
--namespace app --database main
В продакшене root-пользователем не работают: приложению создают отдельного пользователя с ограниченными правами. Root нужен для миграций и резервного копирования, его доступ держат узким.
Документы и схема
Таблицу можно оставить schemaless, но для рабочего проекта лучше включить SCHEMAFULL: тогда база отклоняет поля неизвестного типа и проверяет ASSERT-условия.
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD name ON user TYPE string;
DEFINE FIELD email ON user TYPE string
ASSERT string::is::email($value);
DEFINE INDEX user_email ON user FIELDS email UNIQUE;
Индекс с UNIQUE не даст создать двух пользователей с одним адресом. Для частых выборок добавляют индексы по полям сортировки и фильтра. Не индексируйте всё подряд: каждый индекс замедляет запись и занимает место.
Графовые связи
Связь создаётся оператором RELATE и хранится как запись с собственными полями. Это удобно для подписок, тегов и отношений «многие ко многим». Ребро можно сразу дополнить датой, весом или статусом.
CREATE user:alice SET name = "Алиса", email = "alice@example.ru";
CREATE user:bob SET name = "Боб", email = "bob@example.ru";
RELATE user:alice->follows->user:bob SET since = time::now();
SELECT name, ->follows->user.name AS friends FROM user:alice;
Обход графа читается как путь: из user:alice по рёбрам follows в таблицу user. Результат приходит массивом. Для обратного направления используют <-follows<-, а для произвольной глубины — повторение шагов.
Запросы и индексы
SurrealQL похож на SQL, но вместо JOIN часто применяют вложенные выборки и FETCH: оператор подгружает связанную запись по ссылке. Для проверки плана используют EXPLAIN — он показывает, будет ли запрос использовать индекс. Если видно полное сканирование, проверьте тип и порядок полей в индексе.
Пользователи и права
Права задаются на уровне таблицы и могут учитывать текущего пользователя через $auth. Это позволяет отдавать приложению только опубликованные записи и запрещать прямое редактирование. Пользователя базы создают отдельно от учётных записей приложения.
DEFINE USER app ON DATABASE PASSWORD 'AppPass' ROLES EDITOR;
DEFINE TABLE post PERMISSIONS
FOR select WHERE published = true
FOR create, update, delete NONE;
Роль EDITOR разрешает чтение и запись, но не управление пользователями. Для фоновых задач иногда достаточно VIEWER. Пароль меняют при ротации секретов, старые записи удаляют через REMOVE USER.
Резервное копирование
Логический экспорт сохраняет схему и данные в файл SurrealQL. Его удобно хранить в системе резервных копий и проверять восстановлением. Для больших объёмов экспорт запускают по расписанию в окно низкой нагрузки.
surreal export --endpoint http://127.0.0.1:8000 \
--user root --pass 'Str0ngPass' \
--namespace app --database main backup.surql
surreal import --endpoint http://127.0.0.1:8000 \
--user root --pass 'Str0ngPass' \
--namespace app --database main backup.surql
Экспорт не заменяет снимок диска: для RocksDB можно периодически останавливать запись и копировать каталог данных. Проверяйте восстановление заранее — непроверенная копия не считается резервной.
Диагностика
Команда INFO FOR DB показывает таблицы, индексы, пользователей и права. Если запрос неожиданно медленный, смотрят EXPLAIN и размер таблицы. Для проверки соединения достаточно выполнить простой SELECT.
INFO FOR DB;
SELECT count() FROM post GROUP ALL;
SELECT * FROM user WHERE email = "alice@example.ru";
Ошибка «permission denied» обычно означает, что пользователь базы не имеет роли или сработала политика таблицы. Ошибка аутентификации — неверный namespace, database или пароль. Логи процесса содержат подробности при включённом журналировании.
Ограничения
SurrealDB моложе PostgreSQL и MySQL, поэтому вокруг меньше готовых ORM, миграционных инструментов и специалистов. Сложные аналитические запросы и оконные функции могут требовать иного подхода, а часть привычного SQL-синтаксиса отсутствует. Для отчётности с жёсткими требованиями к проверяемости иногда проще взять зрелую реляционную СУБД.
Кластерная конфигурация требует TiKV и отдельной эксплуатации, а не «включается галочкой». Перед переходом на мажорную версию читайте release notes: диалект и поведение прав могут меняться. Начинайте с небольшого сервиса и держите логический экспорт.
Чек-лист
- База слушает localhost, снаружи доступна только через TLS-прокси.
- Root-пароль уникален, приложение работает под отдельной ролью.
- Схема переведена в SCHEMAFULL, ключевые поля проверяются ASSERT.
- Индексы созданы под реальные запросы и проверены через EXPLAIN.
- Экспорт выполняется по расписанию, восстановление проверено.
Итог
SurrealDB интересна там, где данные естественно ложатся в документы и связи: каталоги, соцфункции, теги, рекомендации. Она сокращает число сервисов и позволяет описывать графы прямо в запросе. Но зрелость экосистемы и эксплуатации пока уступает PostgreSQL, поэтому начинать стоит с ограниченного проекта, внимательно следить за правами и регулярно проверять резервные копии.