@Elnurhan

Как добавить отношения «многие-ко-многим» между таблицами из разных баз данных?

Пишу пет-проект интернет-магазин на голанг. Разбил монолитную архитектуру на микросервисную и для каждого микросервиса использую отдельную БД postgres.
У меня есть два микросервиса: микросервис продуктов и микросервис категорий
Таблицы для них выглядят так:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

create table if not exists products
(
    id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    name TEXT NOT NULL,
    description TEXT NOT NULL,
    price NUMERIC NOT NULL,
    created_at TIMESTAMP NOT NULL DEFAULT now(),
    updated_at TIMESTAMP
);
create table categories
(
    id serial primary key,
    name text not null,
    slug text not null,
    created_at timestamp not null default now(),
    updated_at timestamp
);


Как я могу добавить поле категория в таблицу продукта, если они находятся в разных базах данных? Есть ли такая возможность, либо эти таблицы должны быть в одной базе данных?
  • Вопрос задан
  • 281 просмотр
Решения вопроса 2
@nApoBo3
Первое. Обеспечение целостности данных в микросервисной архитектуре по большей части переходит в слой приложения. И это одна из самых сложных задач во всем микросервисном подходе. Так или иначе приходится реализовывать какой-то механизм, обычно приходят к подходу eventual consistency, когда в каждый момент времени какая-то часть данных может быть не согласована, но в итоге все данные будут приведены к согласованному виду.
Второе, где проводить границу между сервисами.

В данном конкретном случае, таблица категорий продуктов может быть как частью сервиса продуктов, так и внешней сущностью по отношению к нем. Если таблица категорий является внешней сущностью, то самому сервису продуктов должно быть абсолютно без разницы что содержится в этом поле, он внутри себя сохраняет функциональность и целостность своих данных даже если записать в это поле произвольный набор.
Обеспечение не противоречивости данных в этом случае может быть реализовано множеством способов. Как один из самых простых, падение и мониторинг в том месте где эти данные будут агрегироваться.
Ответ написан
Комментировать
ky0
@ky0
Миллиардер, филантроп, патологический лгун
для каждого микросервиса использую отдельную БД postgres

Напрасно, это в вашем случае не добавляет "микросервисности".
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Если вы разделяете проект на микросервисы, но связываете при этом их данные, то вы просто делаете распределённый монолит. А когда вы ещё и базу разрываете на два куска, при этом пытаясь сохранить между ними традиционные связи, как внутри одной базы данных, то вы:
1. Не решаете абсолютно ни одной из задач микросервисов, т к. сервисы остаются жёстко связанными. Всё можно было бы решить просто при помощи "Clean architecture", DDD и т.д.
2. Вы добавляете себе невероятное количество головной боли, связанной с самой микросервисной архитектурой, но и плюс все прелести из п.1.
3. И тогда нафига козе баян?

- Микросервисы должны иметь полностью независимые базы данных
- Все взаимодействия должны осуществляться исключительно по API (это мой ответ на ваш вопрос). Как только вы связываете схемы данных, вы теряете весь смысл микросервисов.
- Вы должны обязательно реализовать распределенные транзакции. Вы должны сами писать код для таких транзакций. А вспомните, как приятно и просто делать транзакции в монолите с одной базой данных.
- Взаимодействие между микросервисами должно осуществляться на базе строжайших контрактов, которые можно менять только после обсуждения со всеми людьми, разрабатывающими данные микросервисы. Вам неплохо было бы выдумать или позаимствовать какой-то фреймворк, где четко будут описаны общие и частные принципы общения микросервисов.
- Вы должны обеспечить мониторинг всего и вся, оповещение об отказах и деградации микросервисов
- Вы должны обеспечить распределенное логирование, чтобы уметь отслеживать даже, например, простые запросы между логами из нескольких независимых систем.
- И т.д. и т.п.

Оно вам надо?
Ответ написан
Комментировать
@rPman
Если это сделано специально то не надо так делать.

Одновременная работа с двумя базами данных лишает пользователя встроенного механизма транзакций и заставляет самому следить за согласованностью данных.

Если прямо очень надо, то для начала нужно понять, какая сторона будет 'главной', кто будет выдавать идентификаторы и следить за их согласованностью. Если главного выбрать не получается, то идентификаторы можно создавать двумя способами:
- генерация GUID, который специально разработан быть статистически уникальным, на чьей бы стороне он не был создан (128бит)
- добавление в идентификатор объекта идентификатора ноды, алгоритмы бывают разные, самый простой, определить максимальное количество нод и выделить в идентификаторе несколько бит для их номера (например максимальное количество нод 256, это 8бит в идентификаторе, пусть будут младшие)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы