Принцип «база даних на сервіс»: кожен сервіс сам володіє своїми даними. Інші сервіси не читають і не пишуть його таблиці напряму - лише через його API чи події.
Чому не спільна база:
- прихована зв'язаність: сервіс B читає таблицю сервісу A. Тепер A не може змінити схему (перейменувати колонку, розділити таблицю), не зламавши B. Незалежні релізи - головна перевага мікросервісів - зникають;
- порушення інваріантів: B пише в таблиці A в обхід його бізнес-логіки й валідації;
- спільна точка відмови й навантаження: важкий звіт B гальмує всі сервіси;
- неможливо обрати сховище під задачу (пошук, графи, часові ряди).
Ізоляція може бути на різних рівнях: окремий сервер бази, окрема схема чи окремі таблиці з правами доступу лише для власника. Головне - дисципліна, що чужі таблиці не чіпають.
Як отримати чужі дані:
1. Запит до API власника - коли потрібні актуальні дані в момент запиту:
Замовлення → GET /customers/42 → Клієнти
Мінус - синхронна залежність і затримка.
2. Локальна копія через події - сервіс зберігає потрібну частину чужих даних, оновлюючи її з подій:
Клієнти: CustomerRenamed → Замовлення оновлює customer_name у своїй таблиці
Швидке читання без залежності від доступності іншого сервісу, але дані кінцево узгоджені.
3. API-композиція / BFF - окремий шар збирає дані з кількох сервісів для екрана.
4. CQRS-проєкції - окрема модель читання, що агрегує події кількох сервісів для звітів і пошуку.
Складності, які з'являються:
- немає JOIN між сервісами - об'єднання даних у коді чи проєкціях;
- немає транзакцій між сервісами - саги й кінцева узгодженість;
- дублювання даних - свідоме, з відомим власником і способом оновлення;
- звітність - зазвичай окреме аналітичне сховище, куди дані збираються з усіх сервісів.
Аналог у модульному моноліті: модуль не звертається до моделей і таблиць іншого модуля - лише через його публічний сервіс чи події. Це готує до можливого розділення без переписування.
Докладніше в документації: Microservices.io: Database per Service