nosqlcoco

     最近手头的一个网站新增社交功能,用户可以互加好友。

     通常,对好友列表设计是新增一个好友,就往好友列表新增一行,当要查询一个用户好友

SELECT  *  FROM WHERE userid="100"
userid nickname
100 小智
101  小苍
102 joker
103 JY

                                                                                                  table: users

user_id friend_id
100 101
100 102
100 103
101 102
101 103

                                                                                                    table:friendlist

我的思路是:

将所有好友以键值对(键=userid,值=昵称)添加到数组中,因为userid在users表中是唯一,所以不用担心键会重复,再把数组序列化(serialize)存入到friend_id中,

当读取好友表时反序列化得到数组,形如:array(\'101\'=>\'小苍\',\'102\'=>\'joker\',\'103\'=>\'JY\'),这表示用户100的好友,这样有一个好处是可以直接显示好友的昵称,而不用再查users表得到好友的昵称。

*这里强调一下,将数组插入数据库之前,一定要对数组序列化,否则当取出时,单个字符表示数组中的一个元素,而不是一组键值对。

userid friend_id
100 a:3:{i:101;s:4:"小苍";i:102;s:5:"joker";i:103;s:2:"JY";}
101 a:2:{i:102;s:5:"joker";i:103;s:2:"JY";}

                                                                                       table:friendlist

这样的好友存储设计在用户量百万级以上用户量效果很明显。

假设一个社交网站有110W用户,平均每个用户好友数为25,那么数据库就有110W * 25 = 2750W行,如果用户量和人均好友数上升,那么friendlist表行数超亿都是有可能的。

更如腾讯新浪用户亿级别的,好友数量几百上千,新增一个好友新加一行很显然是行不通的。

 

以数组形式存储好友,每个用户的好友列表只占一行,如果新增好友,只需往数组添加键值对就行了。这种方法有点事减少了数据库的开销,但是把添加键值对、序列化和反序列化的任务交给了web服务器,增加了服务器的开销,所以二者之间要有个权衡。

1.新增好友添加到数据库

                 //取出好友ID和名字 ,登录时已经把用户id和名称取出
                 $res = mysql_query("select friendList from friend where userid=\'$userid\'");
	             $row = mysql_fetch_assoc($res);
				
			 if($row == ""){ //如果好友列表为空
		 
	                          $arr = array($FromId[\'userid\']=>$FromId[\'username\']);
			          $friends = serialize($arr);
				  mysql_query("insert into friend values(\'$userid\',\'$friends\')");
	                 }else{

	           //如果好友列表不为空,将‘ID’=》\'用户名\',插入到数组当中
		                 $arr = unserialize($row[\'friendList\']);
				 if(array_keys($arr) == ""){//防止重复添加
                                              $arr[$FromId[\'userid\']] = $FromId[\'username\'];//添加到数组中
		                              $friends = serialize($arr);//插入数据库之前序列化
					      mysql_query("update friend set friendList = \'$friends\' where userid = \'$userid\'");
				  }
}

  2.读取好友

	         $friendSql = mysql_query("select * from friend where userid=\'$row[userid]\'");
		 $friendRow = mysql_fetch_array($friendSql);
		 $friendList = unserialize($friendRow[\'friendList\']);//反序列化

  

 

 

分类:

技术点:

相关文章: