如果在 MySQL 中使用了 InnoDB 引擎,那么對于常規(guī)的 COUNT (id) 等操作非常耗費資源,速度比較慢,為了保持效率,需要將這些數據行的統(tǒng)計值保存起來,使用的時候直接查詢獲取就可以了。比如一個 BBS 系統(tǒng)中需要將每個論壇板塊的主題數量和回復數量作為一個字段保存到相應的板塊信息表中;如果主題和回復變動不頻繁,那么對這個統(tǒng)計值的操作也不頻繁,每次使用 COUNT (id) 重新查詢還是可行的,但如果面對的是一個大型 BBS,不僅數據量巨大,而且用戶數巨大引起主題和回復更新非常快,頻繁的對巨量數據調用 COUNT (id) 查詢,在性能上是不太現實的;所以,對于頻繁更新的統(tǒng)計值,我們可以采用另外一種方法:直接加減。也就是說,如果增加了新主題,針對主題的統(tǒng)計值進行加一操作,反過來,刪除主題,進行減一操作。
在 實際使用加減法更新統(tǒng)計值的時候,總有可能會發(fā)生統(tǒng)計值不正確的時候,特別是當統(tǒng)計值已經是零的時候如果再次減一,就會變成無法接受的錯誤:負值;如果你 將統(tǒng)計值字段定義了 unsigned,-1 會變成該字段的最大值(二進制取反引起的),也是無法接受的。這個時候,我們需要一個 SQL 函數,實現類似編程語言中 Max() 函數的功能,將這個統(tǒng)計值最小控制在 0。
在 PostgreSQL 中,有一個叫 greatest 的條件函數,可以讓我們通過以下 SQL 語句避免統(tǒng)計值出現負值:
UPDATE dd_stml_stat SET stat_value=GREATEST(stat_value-1,0) WHERE stat_id=10;
可惜的是,在 MySQL 中并沒有對應的函數,不過 MySQL 有一個叫 IF() 的特殊 Control Flow Function,可以使用它來實現我們的目標:
UPDATE dd_stml_stat SET stat_value=(IF(stat_value>1,stat_value-1,0)) WHERE stat_id=10;
其實這個 IF() 函數就是一個簡單的判斷器,它會判斷第一個參數是否成立,如果是 True,就會返回第二個表達式的值,如果是 False,會返回第三個表達式的值;從而變相的在 MySQL 中實現了大小值比對函數。