# 淺談CQRS

CQRS (**Command Query Responsibility Segregation**) 命令查詢職責分離模式，在談論這個之前必須要先談論OO(Object-Oriented)裡面的CQS(Command Query Separation)因為兩者的概念一樣，只是應用層級不太一樣。

### CQS

CQS 使用於寫程式層級，將Object主要分為兩種動作command、query:

* Command:  指的是改變物件狀態的動作，ex: Create, Update, Delete
* Query: 指的是不會改變物件狀態的動作，ex: Read.

舉個例子:

```javascript
function Array() {
    this.arr = []
}

// Insert 屬於 "Command" 因為所執行的事情是將element 存入 arr 中，改變了狀態
Array.prototype.Insert = function (element) {
    this.arr.push(element)
}

// Read 屬於 "Query" 因為只是讀取並未改變Array 整個物件的狀態
Array.prototype.Read = function (index) {
    return this.arr[index]
}
```

`其中CQS 有一個特性，`**`會改變狀態的方法不會回應物件狀態，反之不會改變狀態的回應物件狀態`**`。換句話說command 因為是改變狀態的動作，則會不會有Return ; Query 則會有Return。`

### CQRS

也別於CQS，CQRS 則是將 Command、Query的概念拉到系統層級，以資料庫中Create, Read, Update, Delete (CRUD) 四個動作為例，大多時候Read才是大量被使用的。而使用CQRS 就能夠輕易的增加Read 用的伺服器，為此增加彈性，並且能夠輕易的做出針對性的效能教調。

舉個例子:

如果將資料庫的存取拆分成Command、Query，資料庫的選擇上會有一些變化，如Command 換成寫入較快的，Query 則換成讀取較快的。透過資料庫本身的Master-slaves 模式就可以進而提昇效能。如下示意圖。

{% hint style="info" %}
master-slave pattern 指的是主動或者被動的方式將資料同步到其他資料庫&#x20;
{% endhint %}

![](/files/uEQw9oBn5ba1baM8r8ri)

### **參考資料**

\[1] <https://martinfowler.com/bliki/CQRS.html>\
\[2] <https://martinfowler.com/bliki/CommandQuerySeparation.html>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiang753017.gitbook.io/zixiang-blog/patterns/qian-tan-cqrs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
