Что такое InMemory Database?

Ответ

InMemory Database (База данных в памяти) — это СУБД, которая хранит все данные исключительно в оперативной памяти (RAM) процесса приложения, не используя постоянное хранилище (диск). Это временная, высокопроизводительная БД, которая обнуляется при остановке приложения.

Основные сценарии использования:

  1. Модульное и интеграционное тестирование:

    // Пример с Entity Framework Core
    [Test]
    public void Service_Adds_User_To_Database()
    {
        // 1. Создаем уникальное имя БД для изоляции теста
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
            .Options;
    
        // 2. Используем контекст с InMemory
        using (var context = new AppDbContext(options))
        {
            var service = new UserService(context);
            service.CreateUser("John Doe");
    
            // 3. Проверяем результат в памяти
            Assert.That(context.Users.Count(), Is.EqualTo(1));
            Assert.That(context.Users.First().Name, Is.EqualTo("John Doe"));
        }
        // 4. После using БД автоматически уничтожается
    }

    Преимущество: Тесты становятся быстрыми, изолированными и не требуют развертывания реальной СУБД.

  2. Кэширование и временные данные: Для хранения сессий, результатов сложных вычислений или данных, актуальных только во время работы приложения.

Важные ограничения (почему не для продакшена):

  • Волатильность: Все данные теряются при перезапуске процесса.
  • Ограниченный объем: Размер БД ограничен доступной оперативной памятью.
  • Неполная эмуляция: InMemory-провайдеры (как в EF Core) часто не поддерживают все функции реальных СУБД (сложные транзакции, ограничения внешних ключей, специфичные типы данных). Это может маскировать ошибки, которые проявятся только на реальной базе.

Ответ 18+ 🔞

Слушай, давай про базу данных в оперативке, чтобы было понятно, как она работает и где её можно применить. Это такая штука, которая живёт только пока твоё приложение дышит. Вырубил программу — всё, пиши пропало, данные испарились. Никаких файлов на диске, всё крутится прямо в RAM.

Где это может пригодиться на практике?

  1. Для тестов — просто идеально. Когда пишешь автотесты, тебе же не нужно, чтобы они лезли в реальную продакшен-базу и там всё похерили. Ты создаёшь изолированную песочницу в памяти, накрутил туда данных, проверил логику и выкинул. Быстро, чисто, и соседним тестам не мешаешь.

    Вот смотри, как это примерно выглядит на C# с Entity Framework Core:

    [Test]
    public void Service_Adds_User_To_Database()
    {
        // 1. Генерим уникальное имя для БД, чтобы тесты не пересекались
        var options = new DbContextOptionsBuilder<AppDbContext>()
            .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
            .Options;
    
        // 2. Работаем с контекстом в памяти
        using (var context = new AppDbContext(options))
        {
            var service = new UserService(context);
            service.CreateUser("John Doe");
    
            // 3. Проверяем, что там в памяти накопилось
            Assert.That(context.Users.Count(), Is.EqualTo(1));
            Assert.That(context.Users.First().Name, Is.EqualTo("John Doe"));
        }
        // 4. Всё, контекст уничтожен — память чиста
    }

    Главный плюс — скорость. Тесты летают, и не надо заморачиваться с поднятием настоящей PostgreSQL или SQL Server.

  2. Кэш или временное хранилище. Допустим, тебе нужно погонять какие-то промежуточные данные, которые актуальны только пока пользователь в сессии, или держать горячий кэш, к которому нужен мгновенный доступ. В оперативке — самое то.

Но есть, блядь, важные подводные камни (почему это не для продакшена):

  • Всё летит в тартарары при перезапуске. Сервер упал? Приложение обновили? Всё, данных нет. Это временное хранилище, а не постоянное.
  • Объём ограничен твоей оперативкой. Попробуй засунуть туда терабайты данных — ну удачи, конечно. Сожрёт всю память и приложение рухнет.
  • Она не полностью повторяет поведение настоящей СУБД. Это, пожалуй, самый опасный момент. Провайдер вроде того, что для EF Core, может игнорировать некоторые ограничения целостности, не поддерживать сложные транзакции или специфичные типы данных. Получается, у тебя тесты проходят на ура, а когда выкатываешь на реальную базу — пиздец, всё падает из-за какого-нибудь FOREIGN KEY CONSTRAINT, который в памяти просто не проверялся. Доверия к такой эмуляции, блядь, ноль.

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