引言
前幾天做了這么一個東西:一個游戲中有個活動頁面,活動頁面有個商品,商品下面要顯示該商品實瀏覽次數,就相當於是用戶每出發一次請求這個瀏覽總次數都會添加一次,這個問題很簡單,每次瀏覽的時候去數據庫中進行“+1”操作即可。但是做完之后想想,由於這個瀏覽總次數實時性要求不是那么高,我就可以對sql請求進行稀釋、減少“+1”的請求次數,這樣可以減少與數據庫交互時“寫操作”所浪費的資源。
實現
這種特殊環境下的sql請求是這樣的,每次要執行瀏覽次數“+1”操作時,我們產生一個1~N的隨機數R,如果R%N == 0則進行“+N”操作,N可以根據瀏覽總次數的實時性等級進行適當的調整,實時性越高,N越小,寫操作命中的幾率越大,否則反之,看看下面的示意圖:
下面是部分代碼(只是測試模擬的,重在說明意思):
1 class Addtimes{ 2 /** 3 * 假設這個是db對象 4 */ 5 private static $db; 6 7 /** 8 * 測試“瀏覽次數”稀釋 9 * int $hit 稀釋的倍率,平均$hit進行一次記錄 10 */ 11 public static function doadd($hit){ 12 $hit = intval($hit); 13 $r = rand(1,$hit); 14 $r % $hit == 0 && self::$db->query("update testtimes set times=times+{$hit}"); 15 } 16 }
這樣就從一定程度上面減少了每次進行寫操作,把N次寫操作合並為一次。
總結
這個是一個小小的優化,但他的局限性很大,使用的時候要注意下面幾點:
- 使用之前要考慮數據實時性的要求,實時性要求高的還是別用了。
- 這個預期總次數一定要大於N,最好是好多倍,由於是隨機數進行的,如果總次數太少會出現很大的誤差。
- 如果可以使用緩存的話,會更好,比如將次數存儲在memchached、redis、apc等緩存中,每次都進行“+1”操作,這樣就可以實現高實時性;命中次數邏輯依然存在,當命中時進行數據持久化(回寫db),這時候這個回寫次數N就可以適當的調大。
本文版權歸作者(luluyrt@163.com)和博客園共有,未經作者本人同意禁止任何形式的轉載,轉載文章之后必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。