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