0

我有一个类似于 myspace 的社交网络,但我使用 PHP 和 mysql,我一直在寻找最好的方式来向用户展示仅由他们自己发布的公告以及来自与他们确认为朋友的用户。

这涉及3张桌子

friend_friend = 此表存储谁是谁的朋友的记录friend_bulletins = 此存储公告friend_reg_user = 这是包含所有用户数据(如姓名和照片网址)的主用户表

我将在下面发布公告和朋友表方案,我只会发布对用户表重要的字段。

-- 表的表结构friend_bulletin

CREATE TABLE IF NOT EXISTS `friend_bulletin` (
  `auto_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(10) NOT NULL DEFAULT '0',
  `bulletin` text NOT NULL,
  `subject` varchar(255) NOT NULL DEFAULT '',
  `color` varchar(6) NOT NULL DEFAULT '000000',
  `submit_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `status` enum('Active','In Active') NOT NULL DEFAULT 'Active',
  `spam` enum('0','1') NOT NULL DEFAULT '1',
  PRIMARY KEY (`auto_id`),
  KEY `user_id` (`user_id`),
  KEY `submit_date` (`submit_date`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=245144 ;

-- 表的表结构friend_friend

CREATE TABLE IF NOT EXISTS `friend_friend` (
  `autoid` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(10) DEFAULT NULL,
  `friendid` int(10) DEFAULT NULL,
  `status` enum('1','0','3') NOT NULL DEFAULT '0',
  `submit_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `alert_message` enum('yes','no') NOT NULL DEFAULT 'yes',
  PRIMARY KEY (`autoid`),
  KEY `userid` (`userid`),
  KEY `friendid` (`friendid`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=2657259 ;

将使用的friend_reg_user 表字段 auto_id = 这是用户 ID 号 disp_name = 这是用户名 pic_url = 这是缩略图图像路径

  • 公告应显示由我们朋友列表中的用户 ID 发布的所有公告
  • 还应该显示我们自己发布的所有公告
  • 需要很好地扩展,朋友表有几百万行

// 1 旧方法使用子选择

SELECT auto_id, user_id, bulletin, subject, color, fb.submit_date, spam
FROM friend_bulletin AS fb
WHERE (user_id IN (SELECT userid FROM friend_friend WHERE friendid = $MY_ID AND status =1) OR user_id = $MY_ID)
ORDER BY auto_id

// 我在有少量朋友的帐户上使用的另一种旧方法,因为这个方法使用另一个查询,它将以这种格式返回所有朋友的字符串 $str_friend_ids = "1,2,3,4,5,6 ,7,8"

select auto_id,subject,submit_date,user_id,color,spam
from friend_bulletin
where user_id=$MY_ID or user_id in ($str_friend_ids) 
order by auto_id DESC

我知道这些对性能不利,因为我的网站变得非常大,所以我一直在尝试 JOINS

我相信这得到了我需要的一切,除了它需要修改以让我自己发布公告,当我将它添加到 WHERE 部分时,它似乎打破了它并为每个发布的公告返回多个结果,我认为因为它试图返回我很喜欢的结果,然后我尝试将自己视为朋友,但效果不佳。

我对整篇文章的主要观点是,我对完成这项任务的最佳性能方式持开放态度,许多大型社交网络都有类似的功能,可以返回仅由您的朋友发布的项目列表。必须有其他更快的方法????我一直在阅读 JOINS 对性能不是很好,但我还能怎么做呢?请记住,我确实使用索引并拥有专用的数据库服务器,但我的用户群很大,没有办法解决这个问题

SELECT fb.auto_id, fb.user_id, fb.bulletin, fb.subject, fb.color, fb.submit_date, fru.disp_name, fru.pic_url
FROM friend_bulletin AS fb
LEFT JOIN friend_friend AS ff ON fb.user_id = ff.userid
LEFT JOIN friend_reg_user AS fru ON fb.user_id = fru.auto_id
WHERE (
ff.friendid =1
AND ff.status =1
)
LIMIT 0 , 30
4

1 回答 1

1

首先,您可以尝试对数据库进行分区,以便仅访问包含所需主行的表。将不常用的行移动到另一个表。

JOIN 会影响性能,但据我所见,子查询并没有更好。尝试重构您的查询,这样您就不会一次提取所有数据。似乎其中一些查询可以在您的应用程序的其他地方运行一次,并且这些结果要么存储在变量中,要么被缓存。

例如,您可以缓存为每个用户连接的朋友数组,并在运行查询时仅引用该数组,并且仅在添加/删除新朋友时更新缓存。

它还取决于您的系统结构和代码架构——您的瓶颈可能并不完全在数据库中。

于 2009-07-23T04:57:59.457 回答