Хранение telegram_user_id для рассылки в aiogram: Redis или база данных

    При разработке бота на aiogram часто возникает задача массовой рассылки уведомлений. Для этого необходимо где-то сохранять telegram_user_id пользователей, которые активировали бота (например, нажали кнопку «Начать»). Многие разработчики сомневаются, стоит ли использовать полноценную базу данных (даже лёгкую SQLite) или лучше взять Redis. Разберём оба подхода, их плюсы и минусы, чтобы вы могли принять взвешенное решение.

    Почему Redis может быть удобен для рассылки

    Redis - это быстрое in-memory хранилище, которое идеально подходит для кэширования и временных данных. Если ваш бот рассылает сообщения нечасто и количество пользователей не превышает нескольких тысяч, Redis обеспечит минимальную задержку. Однако у Redis есть важный недостаток: данные хранятся в оперативной памяти и могут быть потеряны при перезапуске сервера (если не настроена персистентность). Для критичных данных, таких как список пользователей для рассылки, это может стать проблемой.

    SQLite: простота и надёжность

    SQLite - это встраиваемая реляционная база данных, которая не требует отдельного сервера. Вопреки опасениям, SQLite работает очень быстро на небольших объёмах (десятки тысяч записей). Операции записи и чтения user_id занимают миллисекунды. SQLite гарантирует сохранность данных даже при аварийном завершении. Для хранения списка пользователей это более надёжный вариант, чем Redis без персистентности.

    Производительность SQLite в ботах

    Многие разработчики опасаются, что SQLite будет «слишком долго» работать при рассылке. На практике, если вы используете асинхронный драйвер (например, aiosqlite) и правильно индексируете таблицу, то выборка всех ID для рассылки занимает доли секунды. Проблема может возникнуть только при одновременной записи из нескольких потоков, но в aiogram запросы обычно последовательные.

    Когда Redis оправдан

    Redis стоит выбрать, если:

    • Вам нужно временное хранилище (например, для кэширования статусов подписки).
    • Планируется очень высокая частота операций чтения/записи (сотни в секунду).
    • Вы готовы мириться с риском потери данных при сбое.

    Если же ваша цель - сохранить список пользователей для будущих рассылок, лучше использовать SQLite. Это бесплатно, не требует установки дополнительных сервисов и даёт достаточную производительность.

    Практический пример: хранение ID в SQLite

    Вот минимальный код для сохранения user_id при нажатии кнопки «Начать»:

    import sqlite3
    import asyncio
    from aiogram import Bot, Dispatcher, types
    
    # Инициализация БД
    conn = sqlite3.connect('users.db')
    cursor = conn.cursor()
    cursor.execute('''CREATE TABLE IF NOT EXISTS users
                      (user_id INTEGER PRIMARY KEY)''')
    conn.commit()
    
    async def start_handler(message: types.Message):
        user_id = message.from_user.id
        cursor.execute('INSERT OR IGNORE INTO users (user_id) VALUES (?)', (user_id,))
        conn.commit()
        await message.answer('Вы подписаны на рассылку!')

    Для асинхронной работы используйте aiosqlite - это позволит не блокировать цикл событий.

    Итоговый совет

    Для хранения telegram_user_id в боте на aiogram я рекомендую использовать SQLite с асинхронным доступом. Это просто, надёжно и быстро для большинства сценариев. Redis оставьте для кэша или временных данных, если они действительно нужны. Не усложняйте архитектуру без необходимости - SQLite справится с задачей рассылки на тысячи пользователей.

    Часто задаваемые вопросы