Найти в Дзене

📦 Хватит плодить KV-базы! Почему миру нужна новая парадигма хранения данных

Каждые несколько лет мир разработки увлекается новой волной идей, которые, как кажется, решат все проблемы. Ключ-значение (Key-Value) базы данных — одна из таких волн. Простые, универсальные и быстрые — кажется, чего ещё желать? Но недавняя статья Джастина Джаффрея заставила задуматься: может быть, пора остановиться и перестать делать очередной «идеальный KV-движок»? На первый взгляд всё просто и красиво: данные хранятся в виде пар ключ-значение, а приложение уже само решает, как именно использовать эти байты. Но, копнув глубже, мы сталкиваемся с серьёзными ограничениями: Многие избегают SQL-баз данных именно из-за сложности и непредсказуемости планировщика запросов. Программистам хочется знать, что запрос выполнится именно так, как задумано, без сюрпризов оптимизации. Автор статьи предлагает компромиссную модель, сочетающую преимущества SQL и простоту KV: Приведём простой пример реализации такой модели данных: -- Логическая схема (что хранить)
CREATE TABLE logs (
timestamp TIMESTAMP
Оглавление

Каждые несколько лет мир разработки увлекается новой волной идей, которые, как кажется, решат все проблемы. Ключ-значение (Key-Value) базы данных — одна из таких волн. Простые, универсальные и быстрые — кажется, чего ещё желать?

Но недавняя статья Джастина Джаффрея заставила задуматься: может быть, пора остановиться и перестать делать очередной «идеальный KV-движок»?

🔍 В чём же проблема с KV?

На первый взгляд всё просто и красиво: данные хранятся в виде пар ключ-значение, а приложение уже само решает, как именно использовать эти байты. Но, копнув глубже, мы сталкиваемся с серьёзными ограничениями:

  • 🛠 Ручная работа вместо творчества
    KV-хранилища дают лишь «строительные блоки», из которых каждый раз нужно вручную собирать нужную модель данных. Каждый разработчик, используя RocksDB или LevelDB, вынужден писать свой велосипед — свою систему сериализации, компрессии и индексации данных.
  • 🔗 Ненужные зависимости и технический долг
    Конечно, можно использовать чужие библиотеки поверх KV, но готовы ли вы добавить к своему проекту 300 зависимостей и код с аниме-логотипом от незнакомого автора на Rust? Вряд ли.
  • 🌫 Отсутствие разделения логической и физической схемы
    Ключевая идея реляционных баз данных, сформулированная Эдгаром Коддом, — это
    независимость данных. Реляционные базы позволяют изменять физическую схему хранения данных (например, добавлять индексы), не переписывая код приложений. KV-базы такого не умеют.

🎯 Идеальное решение: не KV и не SQL

Многие избегают SQL-баз данных именно из-за сложности и непредсказуемости планировщика запросов. Программистам хочется знать, что запрос выполнится именно так, как задумано, без сюрпризов оптимизации.

Автор статьи предлагает компромиссную модель, сочетающую преимущества SQL и простоту KV:

  • 📐 Чёткое разделение схем
    Иметь отдельную
    логическую схему (что хранить) и физическую схему (как именно хранить и по каким полям искать).
  • 🗃 Отказ от «умного» планировщика
    Запросы всегда выполняются именно так, как написаны, без дополнительной магии.
  • 🔄 Асинхронные изменения схемы
    Возможность безболезненно добавлять новые поля и индексы на лету, без остановки системы и миграций вручную.
  • 📑 Переключение между столбцовым и построчным хранением
    Например, одни данные эффективнее хранить построчно (для OLTP-задач), другие — столбцово (для аналитики). И хорошо, если база сама позволяет легко выбирать и менять формат хранения.

🧩 Как это выглядит на практике?

Приведём простой пример реализации такой модели данных:

-- Логическая схема (что хранить)
CREATE TABLE logs (
timestamp TIMESTAMP NOT NULL,
event_id INT NOT NULL,
user_id INT NOT NULL,
event_type TEXT NOT NULL
);

-- Физическая схема (как хранить и искать)
CREATE UNIQUE INDEX ON logs primary_idx (timestamp, event_id);
CREATE INDEX ON logs user_idx (user_id, timestamp);

Запросы явно указывают, какой индекс использовать и как данные извлекать, что даёт контроль и предсказуемость:

SELECT * FROM logs USING user_idx
WHERE user_id = 123 AND timestamp BETWEEN X AND Y;

Нет никакой магии — только то, что нужно.

🚧 Чем это лучше, чем просто KV или SQL?

  • 🎛 Баланс контроля и удобства
    Эта модель позволяет избежать сюрпризов планировщика запросов, но при этом не требует писать вручную сериализацию и индексацию данных.
  • ⚙️ Гибкость
    Вы можете менять физическую схему, добавлять или удалять индексы, не ломая работу приложения.
  • 🚀 Эффективность
    Запросы всегда выполняются линейно и предсказуемо по ресурсам.

💡 Личное мнение автора статьи

Как разработчик, я не раз сталкивался с ограничениями KV-баз. Они требуют огромного количества шаблонного кода и лишают нас возможности быстро менять структуру данных на лету. С другой стороны, классический SQL тоже не всегда удобен из-за непредсказуемого поведения планировщика запросов.

Предложенный подход кажется идеальным балансом. Он особенно ценен для небольших встроенных решений, IoT-устройств или мобильных приложений, где важна предсказуемость и минимальное потребление ресурсов. Возможно, именно такая модель и станет новой точкой роста в мире встроенных баз данных.

🌐 Что дальше?

Сегодня мы имеем отличные инструменты: RocksDB, SQLite, LevelDB. Но пришло время идти дальше, создавая что-то более удобное, понятное и эффективное. Нам нужен не очередной форк RocksDB, а совершенно новая философия хранения данных, освобождающая разработчиков от лишней работы и дающая контроль одновременно.

Возможно, именно кто-то из вас создаст следующую базу данных, которая изменит рынок и принесёт в разработку настоящую революцию.

📌 Полезные ссылки и ресурсы: