Ответ
Event Sourcing хранит состояние системы как последовательность событий, а CQRS разделяет операции на команды (изменяющие данные) и запросы (читающие данные). Их часто используют вместе, потому что:
-
Согласованность
Event Sourcing гарантирует, что все изменения проходят через события, а CQRS обеспечивает разделение чтения и записи, что упрощает масштабирование. -
Гибкость
CQRS позволяет иметь разные модели для чтения (проекции), которые можно перестраивать из событий Event Sourcing. -
Производительность
Запросы могут использовать оптимизированные представления данных, а команды работают с событиями, что снижает нагрузку.
Пример:
// Command (запись)
class CreateOrderCommand {
execute(data) {
const event = new OrderCreatedEvent(data);
eventStore.save(event); // Сохраняем событие
}
}
// Query (чтение)
class OrdersQuery {
getOrders() {
return readModel.getOrders(); // Читаем из проекции
}
} Ответ 18+ 🔞
А, слушай, вот эта ваша модная хуйня — Event Sourcing и CQRS. Ну, типа, чтобы не было как у нас в бухгалтерии: одна тётка пишет в журнал, а другая тут же пытается из него же прочитать, да ещё и исправить, и в итоге все друг другу мозги ебут, а журнал похож на помойку после пьянки.
Так вот, Event Sourcing — это когда ты не хранишь итоговую хуйню, а хранишь историю, как в уголовном деле. Не просто «Вася должен 100 рублей». А «1 января: Вася занял 100. 2 января: Вася вернул 50. 3 января: Вася снова занял 20, но уже под проценты, пидарас». Вся цепочка событий, блядь. И состояние системы в любой момент — это просто результат проигрывания всех этих событий с самого начала, как плёнку прокрутить.
А CQRS — это когда ты чётко разделяешь: вот тут мы меняем данные (пишем, командуем), а вот тут — читаем (запрашиваем). Как в армии: один приказывает, другой — исполняет и докладывает. И эти два процесса живут отдельно, не мешая друг другу. А то ведь как бывает: один запрос на чтение такой тяжёлый запустит, что всю систему на запись положит, и все начинают орать «бля, всё легло!».
Их вместе юзают, потому что:
-
Согласованность, ёпта.
Event Sourcing следит, чтобы любое изменение было событием — всё по честному, в лог. А CQRS делает так, что чтение и запись не путаются под ногами. Масштабируется проще — читающую часть можно в отдельную базу вынести, хоть на Луну. -
Гибкость, мать её.
CQRS позволяет на основе событий из Event Sourcing наделать кучу разных «представлений» (проекций) для чтения. Нужно тебе отчёт для начальства — одна проекция. Нужно для мобильного приложения — другая. Пересобрал из событий — и поехали. Не надо одну универсальную модель на все случаи жизни городить, которая всё равно никуда не годится. -
Производительность, ядрёна вошь.
Запросы (чтение) летают, потому что бьют в оптимизированную, простую проекцию, специально заточенную под этот конкретный запрос. А команды (запись) просто пишут события — это обычно быстрая операция. И они друг другу не мешают. Красота, блядь.
Вот смотри, как это выглядит в коде, простейший пример:
// Команда (это когда мы что-то меняем, пишем)
class CreateOrderCommand {
execute(data) {
// Рождается событие "ЗаказСоздан"
const event = new OrderCreatedEvent(data);
// И просто пихается в хранилище событий
eventStore.save(event); // Всё, записали историю, совесть чиста
}
}
// Запрос (это когда мы просто хотим посмотреть, что там у нас)
class OrdersQuery {
getOrders() {
// А тут мы уже не лезем в события, а читаем из готовой, быстрой проекции
return readModel.getOrders(); // Всё быстро, никто никому не мешает
}
}
Вот и вся магия. Не серем в общую кастрюлю, разделяем ответственность, и спим спокойно. А то ведь доверия к этим монолитным системам — ноль ебать.