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 社交系统中的"关注与被关注"这样一个小功能。