# Idempotent key in database ## 什麼是Ideompotent key 從在HTTP/1.1 RFC-7321裡面給予了idempotent method的定義 ``` Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 dentical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also,the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent. ``` 我們可以看出 Idempotent Method的意思為當我們因為網路不穩時重複送出一個HTTP Request N次,得到的結果是否與只送出一次相同,舉例來說:重複送出N個PUT request對Server內部的資料而言並不會與只送出一次的PUT有不同的結果,但並非所有的HTTP method皆為idempotent method,例如POST Method使用兩次可能會造成同一筆資料在資料庫裡面有兩筆record,想像如果是一個與金流有關的系統,因為retry的行為造成同一筆交易被收費兩次,這聽起來就是很大的災難,因此在某些情況下我們便會要求client端在請求中帶入unique的idempotent key,透過檢查idempotent key是否存在的方式,由此判斷此request是第一個request還是retry的request,由此將POST也變成idempotent method。 ## 使用上的例子: 為了幫助大家理解,idempotent key的概念,我這邊來舉個例子,假設一家店需要傳送客戶交易資訊到server裡面,此時我們店內有3台裝置且分別為device01, device02, device03(device名稱為unique)能夠輸入交易資訊,並且把資料傳給server,那我們該怎麼確保POST method為idempotent method呢?其實很簡單,我們只要把device_id + timestamp當作idempotent key就好了,會需要加上device id是因為有可能兩個不同的device交易的timestamp相同,有我們只要確定這個idempotent key是否存在於database當中就可以知道這筆資料是不是retry request了,有了這樣的處理就不用擔心資料重複了,而這當中的關鍵大概就是要如何產生一個unique的idempotent key了,把兩個東西concate在一起來產生idempotent key可以說是一個不錯的選擇。 ## 理解何謂Idempotent 在CS的領域當中有很多的觀念其實都是從數學而來的,我們常常可以在名詞當中看到數學的影子,而idempotent其實也是借用數學的觀念,在abtraction algebra 的ring theory 當中idempotent定義為$x^2=x$ 由此我們可以推論$x=x^2=x^3=x^4....=x^n$舉個例子來說$1=1^2=1^3=1^4=1^n$或$0=0^2=0^3=0^4=0^n$, 由此可衍生出idempotent為當一個操作進行多次,結果依舊不便,因此如果以下程式不管執行幾次$f(f(x))$,或者所return的結果皆為a,也可以視為一種idempotent。 ```c int main(void) { x(x(x(x(3)))); return 0; } int x(int a) { return a; } ``` 就如同我們不管使用幾次SELECT * FROM (SELECT * FROM (SELECT * FROM tables)),所得到的結果接相同,有趣的是如果我們能夠找到在ring當中所有元素接符合idempotent的話我們則稱為boolean ring,且在這樣的ring當中,交換律:$a*b=b*a$成立,且doble negative law: $\neg(\neg x)=x$ 成立。。 參考資料: https://en.wikipedia.org/wiki/Idempotent_(ring_theory)