翻訳:CQRS - Simple architecture
READ model
In my first attempt to CQRS I have used WRITE model to build queries and … it was OK (or at least worked). After some time we reach the point in the project where some of our queries were taking a lot of time. Why? Because we are programmers and optimization is our second nature. We designed our model to be normalized, so our READ side were suffering from JOINs. We were forced to pre calculate some data for reports to keep it fast. That was an quite interesting, because in fact we have introduced a cache. And from my point of view this is the best definition of READ model: it is a legitimate cache. Cache that is there by design, and is not introduced because we have to release project and non-functional requirements are not met.
READモデル
私が初めてCQRSに挑戦した時、私はクエリを構築するのにWRITEモデルを利用しました。そしてそれは… とりあえずは上手くいきました(少なくとも動きはしました)。少し経って、プロジェクトではいくつかのクエリが遅くなるようになりました。なぜでしょうか?我々はプログラマであり、最適化は我々の第二の天命だからです。我々はモデルを正規化するように設計し、それゆえに読み取り側はJOIN処理で多くの時間を取られていました。我々は速度を保つために、幾らかのデータを事前計算する必要に迫られました。これは非常に興味深いことです。なぜならば、実際のところ、我々はキャッシュを導入したからです。そして、私の見立てでは、READモデルの最良の定義は「正当なキャッシュ」です。設計上そこに存在するキャッシュであり、プロジェクトをリリースするために非機能要件が満たされていないために導入されたものではないものです。
The label READ model can suggest that it is stored in a single database and that’s it. In fact READ model can be very complex, you can use graph database to store social connections and RDBMS to store financial data. This is the place where polyglot persistence is natural.
「READモデル」というラベルはそれが単一のデータベースに保存されることを示唆するように見えるかもしれませんが、実際のところ、READモデルは非常に複雑になり得るものです。ソーシャル・コネクションを保存するためにグラフ・データベースを使うこともできるし、金融データを保存するためにRDBMSを使うこともできます。ここでは、ポリグロット永続化が自然なものとして利用されます。
Designing good READ side is a series of trade offs, e.g. pure normalization vs pure denormalization. If your project is small and most of your reads can be efficiently made against WRITE model, it will be a waste of time and computing power to create copy. But if your WRITE model is stored as a series of events, it would be useful to have every required data available without replaying all events from scratch. This process is called Eager Read Derivation and from my point of view it is one of the most complex things in CQRS, this is a catch I have mentioned earlier. As I said before, READ side is a form of cache and as we know:
There are only two hard things in Computer Science: cache invalidation and naming things.
– Phil Karlton
I said that it is a „legitimate” cache, this word has also additional meaning for me that in our system we have obvious reasons to update the cache. Events produced by our Domain Model are natural reasons to update READ model.
良いREADモデルを設計することは一定のトレードオフ(e.g. 純粋な正規化 vs 純粋な非正規化)を伴います。もしプロジェクトが小さく、WRITEモデルを使った読み取り処理が効率的であるならば、時間とコピーの作成における計算力の無駄となるでしょう。しかし、WRITEモデルが一連のイベントとして保存されるならば、全てのイベントを最初から演算することなく必要なデータがすぐに利用できることは有益なことです。このプロセスはEager Read Derivationと呼ばれており、私の見立てでは、これはCQRSにおいてもっとも複雑な要素の一つで、前述の「落とし穴」です。先ほど言及したように、読み取り側はキャッシュの一形態であり、我々が知るように:
計算機科学の難題は二つのみであり、それはキャッシュの無効化と、命名である。ーフィル・カールトン
ということです。
「正当なキャッシュ」と言いましたが、この言葉には追加の意味があります。それは、私たちのシステムではキャッシュを更新する明確な理由が存在するということです。ドメインモデルが生成するイベントは、READモデルを更新する自然な理由となります。