JSON как база данных — плюсы, минусы и когда стоит остановиться

JSON как база данных: когда использовать, а когда это антипаттерн

Если вы спрашиваете, можно ли использовать JSON-файл как базу данных — короткий ответ: можно, но только для маленьких проектов с редкими записями и одним пользователем. Как только в проекте появляется конкурентный доступ, объём данных растёт выше 1 МБ или данные нужно часто обновлять — JSON-файл превращается в тикающую бомбу. Разберём всё по полочкам.


Что такое JSON как база данных

JSON-файл как база данных — это паттерн, при котором вместо реляционной или документной СУБД вы просто пишете и читаете структурированные данные из текстового файла формата .json. Никаких серверов, никаких подключений, никаких лицензий — просто файл на диске.

{
  "users": [
    { "id": 1, "name": "Иван", "email": "ivan@example.com" },
    { "id": 2, "name": "Мария", "email": "maria@example.com" }
  ],
  "settings": {
    "theme": "dark",
    "language": "ru"
  }
}

Этот подход используется повсеместно — в конфигурационных файлах (package.json, tsconfig.json), в простых CLI-инструментах, в быстрых прототипах и во фронтенд-моках. Проблемы начинаются, когда разработчик не видит границу между «хранить конфиг» и «хранить бизнес-данные».


Преимущества JSON-файла как хранилища данных

1. Нулевая настройка

Не нужно устанавливать PostgreSQL, настраивать пользователей, пробрасывать порты в Docker. Файл есть сразу. Это критически важно для прототипов, хакатонов и MVP за выходные.

2. Человекочитаемость

Открыл в VS Code — увидел все данные. Никакого pgAdmin, никаких SQL-клиентов. Для небольших проектов это огромное удобство.

3. Универсальная поддержка

Python, JavaScript, Go, PHP, Ruby — в любом языке парсинг JSON встроен в стандартную библиотеку. Данные портируются без конвертации.

4. Простота переноса и шэринга

Скопировал файл — скинул коллеге. Добавил в .zip с проектом — и всё работает на другой машине без единой дополнительной инструкции.

5. Гибкость схемы

В JSON нет жёсткой схемы. Добавил новое поле в одну запись — ничего не сломается. Идеально для фазы, когда структура данных ещё не устоялась.


Недостатки: почему JSON-файл — это не настоящая база данных

Каждый из этих недостатков в определённый момент становится критическим.

Нет транзакций (ACID)

Если ваше приложение упадёт посередине записи — файл будет повреждён. JSON нельзя сохранить «частично правильно». В SQLite или PostgreSQL незавершённая транзакция откатывается автоматически. В JSON-файле — нет.

Нет параллельного доступа

Два процесса пишут в файл одновременно? Данные перезапишут друг друга. Это называется race condition. В веб-приложении с 10 одновременными пользователями это случится в первый же день работы.

Производительность деградирует с ростом данных

Чтобы обновить одну запись, вам нужно:

  1. Прочитать весь файл в память
  2. Найти нужный объект
  3. Изменить его
  4. Полностью перезаписать файл на диск

При файле в 1 МБ это работает. При 10 МБ — заметно медленнее. При 100 МБ — невыносимо. Нет индексов, нет оптимизации поиска.

Нет индексации и запросов

В SQL вы пишете WHERE user_id = 42 — и БД использует индекс, чтобы найти запись мгновенно. В JSON-файле вам нужно перебрать все записи вручную (filter, find). O(n) на каждый запрос.

Нет разграничения прав

В PostgreSQL можно дать пользователю доступ только к чтению определённых таблиц. В JSON-файле — либо весь файл, либо ничего.

Проблемы с бинарными данными

Изображения и файлы нужно кодировать в Base64, что увеличивает их размер на ~33% и ещё сильнее нагружает операции чтения/записи.


Популярные библиотеки для работы с JSON как БД

Если вы всё же решили использовать JSON-файл — делайте это через специализированную библиотеку, а не через ручной JSON.parse/JSON.stringify. Библиотеки решают как минимум проблему атомарной записи.

Lowdb (Node.js / TypeScript)

Самая популярная библиотека для JSON-хранилища в экосистеме Node.js. Поддерживает TypeScript, работает синхронно и асинхронно, адаптеры для файловой системы и памяти.

npm install lowdb
import { Low } from 'lowdb'
import { JSONFile } from 'lowdb/node'

type Data = { users: { id: number; name: string }[] }

const adapter = new JSONFile<Data>('db.json')
const db = new Low(adapter, { users: [] })

await db.read()
db.data.users.push({ id: 1, name: 'Иван' })
await db.write()

Подходит для: Electron-приложений, CLI-инструментов, небольших локальных утилит.

TinyDB (Python)

«Маленькая» документная база данных для Python. Синтаксис похож на MongoDB. Проект находится в режиме поддержки (maintenance mode) с 2024 года — новых фич не планируется, но стабильность гарантируется.

pip install tinydb
from tinydb import TinyDB, Query

db = TinyDB('db.json')
User = Query()

db.insert({'name': 'Иван', 'role': 'admin'})
result = db.search(User.role == 'admin')
print(result)

Подходит для: небольших Python-скриптов, автоматизации, прототипов без внешних зависимостей.

JSON Server (Node.js)

Не база данных в строгом смысле, а инструмент для создания mock REST API на основе JSON-файла. Позволяет фронтенд-разработчикам работать без реального бэкенда.

npm install -g json-server
json-server --watch db.json --port 3001

После запуска автоматически доступны эндпоинты GET /users, POST /users, PUT /users/1, DELETE /users/1 и т.д. Версия 1.x активно поддерживается в 2026 году.

Подходит для: мокинг API при фронтенд-разработке, быстрые демо, интеграционное тестирование.


JSON vs SQLite: ключевое сравнение

Главная альтернатива JSON-файлу — SQLite. Оба подхода работают без отдельного сервера, но между ними огромная разница.

| Критерий | JSON-файл | SQLite | |---|---|---| | Установка | Ничего не нужно | Встроен в Python, Node, Go | | Транзакции | Нет | ACID-совместимые | | Индексы | Нет | Есть | | Параллельный доступ | Опасен | Поддерживается (WAL-mode) | | Производительность | O(n) для любого поиска | O(log n) с индексами | | Объём данных | До ~1-5 МБ комфортно | Терабайты | | Человекочитаемость | Да | Нет (бинарный формат) | | Бэкап | cp file.json | sqlite3 db.sqlite ".backup 'backup.db'" | | Использование в продакшене | Нет | Да (WhatsApp, Firefox, iOS) |

SQLite используют WhatsApp (хранение переписки на устройстве), Firefox (история браузера), iOS (большинство системных приложений). Это не учебная игрушка — это боевое решение.


JSON внутри реляционных баз данных: лучшее из двух миров

Современные СУБД позволяют хранить JSON как тип данных внутри реляционной таблицы. Это убирает основные недостатки чистого JSON-файла, сохраняя гибкость.

PostgreSQL JSONB

CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  attributes JSONB
);

INSERT INTO products (name, attributes)
VALUES ('Ноутбук', '{"brand": "Apple", "ram": 16, "tags": ["M3", "MacBook"]}');

-- Поиск по вложенному полю с использованием индекса
CREATE INDEX idx_products_brand ON products USING GIN (attributes);
SELECT * FROM products WHERE attributes->>'brand' = 'Apple';

JSONB — это бинарное представление JSON в PostgreSQL. Данные индексируются, запросы быстрые. Вы получаете гибкость документной модели и надёжность реляционной СУБД одновременно.

MySQL / MariaDB JSON

MySQL с версии 5.7 тоже поддерживает тип JSON с функциями JSON_EXTRACT, JSON_SET и автоматической валидацией структуры.


Когда JSON-файл — правильный выбор

Чёткие критерии, когда JSON оправдан:

  • Конфигурационные файлы приложения (настройки, переводы, темы)
  • Seed-данные для тестов (статические, редко меняются)
  • Mock API при фронтенд-разработке (JSON Server)
  • CLI-инструменты с локальным кэшем настроек пользователя
  • Electron-приложения с небольшим числом пользовательских данных
  • Хакатоны и прототипы, которые никогда не выйдут в продакшен

Когда JSON-файл — антипаттерн

  • Приложение с несколькими одновременными пользователями
  • Данных больше нескольких тысяч записей
  • Нужны запросы с фильтрацией, сортировкой, агрегацией
  • Данные часто обновляются
  • Приложение работает в продакшене
  • Нужна история изменений или откат транзакций

Бэкап JSON-файла: не забывайте о самом простом

Если вы используете JSON как хранилище данных — обязательно делайте бэкапы. JSON-файл так же уязвим, как и любой другой файл: случайное удаление, перезапись поломанными данными, сбой диска.

Для серьёзных проектов на SQLite или PostgreSQL стоит рассмотреть автоматизированное резервное копирование. Сервис dbsend.ru позволяет настроить бэкап базы данных в облако одной строкой — поддерживаются SQLite, PostgreSQL и NoSQL. Если вы уже «переросли» JSON-файл и перешли на нормальную СУБД, автоматический бэкап — следующий шаг к надёжности.


Миграция с JSON-файла на SQLite: пошаговый план

Если вы начали с JSON и поняли, что проект вырос — вот как мигрировать на SQLite без потери данных.

  1. Установите better-sqlite3 (Node.js) или используйте встроенный модуль sqlite3 (Python)
  2. Прочитайте JSON-файл целиком
  3. Создайте схему таблиц в SQLite, соответствующую вашей JSON-структуре
  4. Вставьте все записи через транзакцию (для скорости)
  5. Проверьте количество записей до и после миграции
  6. Обновите код приложения, заменив файловые операции на SQL-запросы
  7. Сделайте бэкап JSON-файла перед удалением (на всякий случай)
import json
import sqlite3

# Читаем JSON
with open('db.json') as f:
    data = json.load(f)

# Создаём SQLite
conn = sqlite3.connect('app.db')
conn.execute('CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)')

# Вставляем данные
with conn:
    for user in data['users']:
        conn.execute('INSERT INTO users VALUES (?, ?, ?)',
                     (user['id'], user['name'], user['email']))

print(f"Мигрировано {len(data['users'])} пользователей")
conn.close()

Итог: правило одной строки

Если данные меняются редко и их мало — JSON. Если данные меняются часто или их много — SQLite минимум, а лучше сразу PostgreSQL с JSONB для гибких полей.


FAQ

Можно ли использовать JSON-файл в продакшене? Только для конфигурационных файлов или очень маленьких объёмов редко меняемых данных. Для бизнес-данных приложения — нет. Используйте SQLite или PostgreSQL.

Чем JSON-файл отличается от SQLite? SQLite — это полноценная реляционная СУБД в одном файле. Она поддерживает транзакции, индексы, параллельный доступ и SQL-запросы. JSON — просто текстовый файл без каких-либо гарантий целостности.

Какие библиотеки лучше всего работают с JSON как БД? Для Node.js — Lowdb. Для Python — TinyDB (или просто встроенный модуль json). Для мокинга API — JSON Server. Все они решают проблему атомарной записи, которой нет при ручном JSON.stringify.

JSONB в PostgreSQL — это то же самое, что JSON-файл? Нет. JSONB — это тип данных внутри PostgreSQL, который хранится в бинарном формате, индексируется и поддерживает операторы поиска. Это совершенно другой уровень надёжности и производительности.

Что использовать для прототипа — JSON или SQLite? Если прототип точно не выйдет в продакшен — JSON подойдёт. Если есть хоть малейший шанс, что проект будет расти, сразу берите SQLite: в Python он встроен, в Node.js — better-sqlite3 устанавливается за секунду.

Как защитить JSON-файл от повреждения? Используйте библиотеки (Lowdb, TinyDB), которые пишут файл атомарно. Делайте регулярные копии. Никогда не пишите в JSON-файл из нескольких потоков или процессов одновременно.

Как делать бэкапы JSON-файла? Самый простой способ — скрипт, который копирует файл с датой в имени: cp db.json db.json.$(date +%Y%m%d_%H%M%S). Для автоматизации бэкапов реальных баз данных (SQLite, PostgreSQL) смотрите в сторону dbsend.ru.