Я щойно прочитав статтю про мікросервіси та архітектуру PaaS . У цій статті, приблизно на третині шляху вниз, автор стверджує (під Денормалізуй як Шалений ):
Створюйте схеми бази даних рефактора та денормалізуйте все, щоб забезпечити повне відокремлення та розділення даних. Тобто не використовуйте базові таблиці, які обслуговують кілька мікросервісів. Не повинно бути спільного використання базових таблиць, що охоплюють декілька мікросервісів, і спільного використання даних. Натомість, якщо декілька служб потребують доступу до одних і тих самих даних, їх слід надавати через службовий API (наприклад, опублікований REST або інтерфейс служби обміну повідомленнями).
Хоча це теоретично звучить чудово, на практиці це має кілька серйозних перешкод, які потрібно подолати. Найбільший з них полягає в тому, що часто бази даних тісно пов’язані, і кожна таблиця має певний зв’язок із зовнішнім ключем принаймні з однією іншою таблицею. Через це може бути неможливо розділити базу даних на n підбаз даних, керованих n microservices.
Тож я запитую: з огляду на базу даних, яка повністю складається із пов’язаних таблиць, як можна денормалізувати її на менші фрагменти (групи таблиць), щоб фрагменти могли контролюватися окремими мікросервісами?
Наприклад, враховуючи таку (досить невелику, але прикладну) базу даних:
[users] table
=============
user_id
user_first_name
user_last_name
user_email
[products] table
================
product_id
product_name
product_description
product_unit_price
[orders] table
==============
order_id
order_datetime
user_id
[products_x_orders] table (for line items in the order)
=======================================================
products_x_orders_id
product_id
order_id
quantity_ordered
Не витрачайте занадто багато часу на критику мого дизайну, я зробив це на льоту. Справа в тому, що для мене логічним є сенс розділити цю базу даних на 3 мікросервіси:
UserService
- для користувачів CRUDding в системі; в кінцевому рахунку повинен керувати[users]
таблицею; іProductService
- для продуктів CRUDding в системі; в кінцевому рахунку повинен керувати[products]
таблицею; іOrderService
- для CRUDding замовлень у системі; в кінцевому рахунку слід керувати таблицями[orders]
та[products_x_orders]
Однак усі ці таблиці мають взаємозв'язок між зовнішніми ключами. Якщо ми денормалізуємо їх і поводимося з ними як з монолітами, вони втрачають все своє семантичне значення:
[users] table
=============
user_id
user_first_name
user_last_name
user_email
[products] table
================
product_id
product_name
product_description
product_unit_price
[orders] table
==============
order_id
order_datetime
[products_x_orders] table (for line items in the order)
=======================================================
products_x_orders_id
quantity_ordered
Тепер неможливо дізнатись, хто що замовляв, у якій кількості або коли.
Тож чи є ця стаття типовим академічним шумом, чи існує реальна практичність цього підходу до денормалізації, і якщо так, то як це виглядає (бонусні бали за використання мого прикладу у відповіді)?