redis 是非關系型數據庫的一個代表。當前互聯網項目中應用十分的廣泛。
談到redis就不得不談memcahced:
memcached是高性能的分布式內存緩存服務器。一般的使用目的是,通過緩存數據庫查詢結果,減少數據庫訪問次數,以提高動態Web應用的速度、提高可擴展性。是key/value類型緩存服務器,支持的數據類型比較單一。
redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。Redis的速度非常快,每秒能執行約11萬集合,每秒約81000+條記錄。
當前互聯網項目需求越來越復雜,而且性能要求也非常高,關系型數據庫越來越難以滿足這些要求。應運而生的非關系型數據庫越來越受到重視。
據了解:新浪微博,淘寶,facebook,instagram都用到了redis數據庫,並相應作了集成。
ps:關於redis的知識可以參見:http://www.yiibai.com/redis/redis_sorted_sets.html
下面我重點分析一個常見的應用場景:
微博中的關注與被關注(粉絲)的實現。
分析:微博我們都用過,一個用戶可以關注任意n個用戶。當然這個用戶也可以被任意n個用戶關注。若在關系型數據庫中,這類的問題處理起來比較麻煩。
如果我們利用redis來實現,相對來說應該會簡單不少。
這里我們使用Set有序集合數據類型來進行存儲。
實現思路:每個用戶有兩個有序集合,一個用來儲存該用戶關注的用戶ID,另一個用來存儲該用戶粉絲的ID。每個用戶在"關注/取消關組"操作的時候均會更行這兩個表。
比如:用戶id為001的用戶 user:001:following 保存的是其關注人的列表,user:001:followed_by 保存的是關注他的人的列表
ok
下面用php實現了一個類,主要完成了:關注,取消關注,我關注的用戶,我的粉絲,是否關注某用戶,是否被某用戶關注,互粉(互相關注),關注的用戶數目,粉絲數,
共同關注的用戶,共同的粉絲。
看代碼:

<? class UserFollow{ // 用戶ID private $id; //配置 private $redis_config = array( array('host' => 'localhost', 'port' => 6379 ) ); private $redis; public function __construct($userID) { $this->id = $userID; } private function redis() { if (!$this->redis) { $this->redis = new Predis\Client($redis_config); } return $this->redis; } /* 關注操作 */ public function follow($user) { $this->redis()->sadd("user:{$this->id}:following", $user); $this->redis()->sadd("user:$user:followed_by", $this->id); } /* 取消關注操作 */ public function unfollow($user) { if ($this->is_following()) { $this->redis()->srem("user:{$this->id}:following", $user); $this->redis()->srem("user:$user:followed_by", $this->id); } } /* * 我關注的用戶 */ public function following() { return $this->redis()->smembers("user:{$this->id}:following"); } /* * 我的粉絲 */ public function followed_by() { return $this->redis()->smembers("user:{$this->id}:followed_by"); } /* *是否關注某用戶 */ public function is_following($user) { return $this->redis()->sismember("user:{$this->id}:following", $user); } /* *是否被某用戶關注 */ public function is_followed_by($user) { return $this->redis()->sismember("user:{$this->id}:followed_by", $user); } /* *互粉(互相關注) */ public function is_mutual($user) { return ($this->is_following($user) && $this->is_followed_by($user)); } /* * 關注的用戶數目 */ public function follow_count() { return $this->redis()->scard("user:{$this->id}:following"); } /* *粉絲數 */ public function follower_count() { return $this->redis()->scard("user:{$this->id}:followed_by"); } /* * 共同關注的用戶 */ public function common_following($users) { $redis = $this->redis(); $users[] = $this->id; $keys = array(); foreach ($users as $user) { $keys[] = "user:{$user}:following"; } return call_user_func_array(array($redis, "sinter"), $keys); } /* * 共同的粉絲 */ public function common_followed_by($users) { $redis = $this->redis(); $users[] = $this->id; $keys = array(); foreach ($users as $user) { $keys[] = "user:{$user}:followed_by"; } return call_user_func_array(array($redis, "sinter"), $keys); } }
這樣使用:

<? // 創建兩個用戶user1,user2 $user1 = UserFollow(1); $user2 = UserFollow(2); //user1關注的為空 $user1->following(); // array() // 為user1添加關注用戶2,3 $user1->follow(2); $user1->follow(3); // 查看user1關注了哪些用戶 :2,3 $user1->following(); // array(2, 3) // 查看user2的粉絲 :1 $user2->followed_by(); // array(1) // 為user2添加關注用戶3 $user2->follow(3); // 查看user1和user2共同關注的用戶:3 $user1->common_following(2); // array(3) ?>
這樣就簡單的實現了日常WEB 社交系統中的"關注與被關注"這樣一個小功能。