for now I want to make snapshot or dump of my brain about CQRS, so beware from reading of it, because it can be confusing.
Very simple explanation of CQRS
As usually if you see some kind of application, you can expect that what you see on the screen, you'll see it in db. It means if you see on screen Order, and order details, you can expect to see in database tables order and OrderDetails, or “one to one” relation between screen and DB.
But with CQRS following changes can be applied:
Instead of two tables ( order and order details ), you will see three tables. Now make a pause and tell your assumption what can be their names? As one of the ways it can be Orders, OrdersDetails, ReadOrderDetails. And as you probably guessed ReadOrderDetails may represent whole screen of all of your order.
More detailed description of CQRS
So, what CQRS stands for? CQRS stands for Command/Query Responsibility sergregation.
What is command query?
Command = Writes of data
Queries = Reads of data.
First time when I heard it I was astouned, why??? Why to make the same entity so separated. But if to summarize it, you write infor in one part of db, but read from another part of db.
So, it gives you some side-effects. Consider some of them:
data which you read become old after getting it from db
number of reads > number of writes
reads and writes go in different places
commands modify data
queries just get data
read db as usually is not normalized
read db as usually without joined tables
ORM blur difference of what is in db.
CQRS as usually use something like event sourcing in order to track of what ever happened. As usually they work as append only table in db. In yet another words ES is recording of all state changes to the domain as series of events. Which give you following benefits:
a. detect bugs in domains
b. possibility to replay changes
c. current state always correct due to availability of known history of changes
If to summarize this part of my brain dump,
- huuuuge difference between reads and writes should be reflected in code
- domain model must be unbinded from data store
- single model can't represent all ( transactions, reporting, searching )