社交网站好友储存设计和实现(PHP+MySQL)

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

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

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']);//反序列化

  

 

 

posted @ 2013-10-17 11:58  nosqlcoco  阅读(4669)  评论(14编辑  收藏  举报