CQRS 与 CQS 的区别

我正在学习什么是 CQRS模式,并开始知道还有 CQS模式。

当我试图搜索时,我发现了很多关于 CQRS的图表和信息,但是没有找到很多关于 CQS的信息。

CQRS模式的关键点

在 CQRS 中有一个模型要写(命令模型)和一个模型要读(查询模型) ,它们是完全独立的。

CQRS Diagram

CQS 和 CQRS 有什么不同?

32690 次浏览

CQS (Command Query Separation) and CQRS (Command Query Responsibility Segregation) are very much related. You can think of CQS as being at the class or component level, while CQRS is more at the bounded context level.

I tend to think of CQS as being at the micro level, and CQRS at the macro level.

CQS prescribes separate methods for querying from or writing to a model: the query doesn't mutate state, while the command mutates state but does not have a return value. It was devised by Bertrand Meyer as part of his pioneering work on the Eiffel programming language.

CQRS prescribes a similar approach, except it's more of a path through your system. A query request takes a separate path from a command. The query returns data without altering the underlying system; the command alters the system but does not return data.

Greg Young put together a pretty thorough write-up of what CQRS is some years back, and goes into how CQRS is an evolution of CQS. This document introduced me to CQRS some years ago, and I find it a still very useful reference document.

The biggest difference is CQRS uses separate data stores for commands and queries. A query store can use a different technology like a document database or just be a denormalized schema in the same database that makes querying the data easier.

The data between databases is usually copied asynchronously using something like a service bus. Therefore, data in the query store is eventually consistent (is going to be there at some point of time). Applications need to account for that. While it is possible to use the same transaction (same database or a 2-phase commit) to write in both stores, it is usually not recommended for scalability reasons.

CQS architecture reads and writes from the same data store/tables.

  • CQS is about Command and Queries. It doesn't care about the model. You have somehow separated services for reading data, and others for writing data.
  • CQRS is about separate models for writes and reads. Of course, usage of write model often requires reading something to fulfill business logic, but you can only do reads on read model. Separate Databases are state of the art. But imagine single DB with separate models for read and writes modeled in ORM. It's very often good enough.

I have found that people often say they practice CQRS when they have CQS.

Read the inventor Greg Young's answer

I think, like "Dependency Injection" the concepts are so simple and taken for granted that the fact that they have fancy names seems to drive people to think they're something more than they are, especially as CQRS is often quoted alongside Event Sourcing.

  • CQS is the separation of methods that read to those that change state; don't do both in a single method. This is micro level.

  • CQRS extends this concept into a higher level for machine-machine APIs, separation of the message models and processing paths.

So CQRS is a principle you apply to the code in an API or facade.

I have found CQRS to essentially be a very strong S in SOLID, pushing the separation deeply into the psyche of developers to produce more maintainable code.

I think web applications are a bad fit for CQRS since the mutation of state via representation transfer means the command and query are two sides of the same request-response. The representation is a command and the response is the query.

For example, you send an order and receive a view of all your orders.

Imagine if the code of a website was factored into a command side and query side. The route action handling code would need to fall into one of those sides, but it does both.

Imagining a stronger segregation, if the code was moved into two different compilable codebases, then the website would accept a POST of a form, but the user would have to browse to another website URL to see the impact of the action. This is obviously crazy. One workaround would be to always redirect, though this wouldn't really be RESTful since the ideal REST application is where the next representation contains hypertext to drive the next state transition and so on.

Given that a website is a REST API between human and machine (or machine and machine), this also includes REST APIs, though other types of HTTP message passing API may be a perfect fit for CQRS.

A service or facade within the bounds of the website may obviously work well with CQRS, though the action handlers would sit outside this boundary.

See CQS on Wikipedia

This is an old question but I am going to take a shot at answering it. I do not often answer questions on StackOverflow, so please forgive me if I do something outside the bounds of community in terms of linking to things, writing a long answer, etc.

There are many differences between CQRS and CQS however CQRS uses CQS inside of its definition! Let's start with defining the two and then we can discuss differences.

CQS defines two types of messages depending on their return value: no return value (void) specifies this is a Command; a return value (non-void) specifies this method is a Query.

  • Commands change information
  • Queries return information

Commands change state. Queries do not.

Now for CQRS, which uses the same definition as CQS for Commands and Queries. What CQRS says is that we do not want one object with Command and Query methods. Instead we want two objects: one with all the Commands and one with all the Queries.

The idea overall is very simple; it's everything after doing this where things become interesting. There are numerous talks online, of me discussing some of the attributes associated (sorry way too much to type here!).