Проектирование архитектуры базы данных для SaaS
Ошибки в проектировании базы данных на первой же неделе будут преследовать вас годами.
Основателю SaaS нужна схема, поддерживающая мультиарендность (multi-tenancy), биллинг и масштабирование. Если вы ошибетесь, вам придется переписывать всю систему через полгода.
Вот как построить готовую к эксплуатации (production-ready) схему.
1. Выберите стратегию управления арендаторами (Tenant Strategy)
Вы должны изолировать данные разных клиентов.
• Уровень строк (Shared DB): Низкая сложность. Лучший вариант для большинства стартапов. Используйте фильтр WHERE organization_id = ? в каждом запросе.
• Уровень схем (Separate Schemas): Средняя сложность. Подходит для соблюдения нормативных требований.
• Уровень баз данных (Separate DBs): Высокая сложность. Лучший вариант для корпоративных клиентов (enterprise).
Для 90% новых продуктов мультиарендность на уровне строк — правильный выбор.
2. Правильная иерархия сущностей
Не выставляйте счета напрямую пользователям. Пользователи приходят и уходят. Организации остаются.
Иерархия должна выглядеть так: User ── MemberOf ── Organization ── Subscription ── Invoice
• Users: Используйте эту таблицу только для идентификации. Используйте UUID, чтобы предотвратить атаки. • Organizations: Это граница вашего арендатора. Всегда привязывайте подписки к организации. • Memberships: Используйте связующую таблицу (join table) для связи пользователей с организациями. Храните роли здесь, а не в таблице пользователей.
3. Биллинг и подписки
Никогда не используйте простой булев тип вроде is_active. Это приводит к запутанным данным.
Используйте конечный автомат (state machine) для подписок. Распространенные состояния включают:
• trialing
• active
• past_due
• canceled
• expired
• incomplete
Это позволит вам обрабатывать сбои платежей и льготные периоды (grace periods) без ручного исправления данных.
4. Деньги и выставление счетов
Соблюдайте эти строгие правила, чтобы избежать финансовых ошибок:
• Никогда не используйте FLOAT или REAL для денег. Используйте целые числа (integers) для хранения центов. Например, $29.99 превращается в 2999.
• Используйте таблицу invoice_line_items. Она необходима для налоговой отчетности и возвратов.
• Используйте таблицу usage_events, если вы берете плату в зависимости от объема использования продукта клиентом.
5. Советы по производительности
• Индексируйте внешние ключи (foreign keys).
• Индексируйте колонки со статусами.
• Индексируйте колонки с временными метками (timestamps).
• Избегайте запросов N+1. Используйте JOIN, чтобы получить данные об организации и подписке за один запрос.
Хорошая схема незаметна, когда она работает. Но она становится катастрофой, когда дает сбой.
Проектируйте под организацию. Используйте конечные автоматы. Храните деньги в целых числах.
Optional learning community: https://t.me/GyaanSetuAi
