우아한테크코스에서 많이 배우던 것이다. 수정과 조회가 동시에 일어나면 안된다는 것, 만일 이가 일어나게 된다면 소프트웨어의 3가지 원칙 중 복잡하지 않아야 한다는 KISS 가 지켜지지 않은 것이다.
이를 명시적으로 나오게 된 개념이 바로 위와 같은 개념이다.

다음과 같이, 두개의 어플리케이션이 있고, Service Interface가 이를 Query, Command로 나누어준다.

이가 왜 필요한지, 그림으로 나타내면 다음과 같다. 동일한 Domain Model 내부에 정답인지 판단하는 것과, 랭킹 뷰를 확인하는 것이 있다. 이는 통째로 큰 Domain Model 에서 보면 위에서 언급한 3원칙이 지켜지지 않는 것이다. 이렇기 때문에 CQRS 가 필요한 것이다.
그래서, 위와 같이 되면 어떠한 단점이 존재할까?
이 떨어지게 된다.
지금부터 하나씩 잡아보자.
도메인이란 곧 비즈니스이고, 이는 독립적으로 지켜져야한다. 화면딴의 변화가 발생했다고해서, 즉 Query와 관련된 변경사항이 생겨서 도메인의 변경사항이 생겨서는 안된다. 도메인이 이러한 부분을 신경쓰기 시작하면 수정사항이 굉장히 잦아지게 될 것이고, 또한, 계속된 추가/수정으로 인해도메인 자체가 더욱 비대해지게 될 것이다.
대부분의 write 연산에서 우리는 일관성에 대해 많은 신경을 쓴다. 그렇기 때문에 Lock 기법을 많이 사용하는데, 문제점이 Lock 으로 인해서 Read에도 영향이 간다는 것이다. 그렇기 때문에, 이를 분리하여 둘을 독립적으로 만들고 성능을 높일 수 있다.
쓰기 작업, 읽기 작업의 비율차는 엄청나다. 그렇기 때문에, 둘의 설계에는 분명한 차이가 존재한다. 그렇기 때문에 Command,Query를 서로 분리하게되면 각각의 영역에 대한 설계를 독립적으로 진행할 수 있고, 이는 추후 확장성에도 영향을 줄 수 있다는 것을 의미하게 된다.
그래서 위에서 나왔던 구조를 CQRS 형식으로 분리하게 되면 다음과 같은 구조가 된다.

이렇게 되면 어떠한 장점이 있을까 생각해볼 때, 가장 단순하게는 서로 다른 Persistence module을 사용할 수 있다. command에는 MyBatis, Read 에는 JPA를 쓸 수 있는 것이다.

그렇게 되면 다음과 같이 구조를 변경해볼 수 있는 것이다. 이전과 다르게 DB를 나누고 Stream으로 연결해준 것을 볼 수 있다. 그렇기 때문에 각각의 Command, Query 에 더 유리한 DB를 사용할 수 있게된다.
그래서 CQRS의 장점과 단점을 정리해보면 다음과 같을 것이다.
또한 데이터에 병렬로 접근하는 경우나 read 연산이 write 연산보다 많은 경우는 CQRS 를 사용하는 것이 효과적이다.
또한 마치면서 필자는 이렇게 이야기 한다. 사실 CQRS 는 의미와 같이 Command, Query 와 연관된 기술이라고, 그렇기 때문에 Data Source, Event Sourcing 과 연관된 것이 아니라, 실제로는 도메인 로직에 조금 더 집중하기 위한, 프로그래밍의 기본원칙을 준수한 구조라고 설명하고 있다.