我有一个类似于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 =这是缩略图图像路径
// 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
答案 0 :(得分:1)
首先,您可以尝试对数据库进行分区,以便您只访问具有所需主行的表。将不经常使用的行移动到另一个表。
JOIN会影响性能,但从我看到的情况来看,子查询并不是更好。尝试重构您的查询,以便您不会立即提取所有数据。似乎某些查询可以在应用程序的其他位置运行一次,并且这些结果可以存储在变量中或缓存。
例如,您可以缓存为每个用户连接的朋友数组,并在运行查询时仅引用该数组,并且仅在添加/删除新朋友时更新缓存。
它还取决于系统的结构和代码架构 - 您的瓶颈可能不完全在数据库中。