我想在我的网站上创建会员墙(Facebook风格)。 基于:
表格结构:
friendship
userid | friendid | status
---------------------------------
user_table
userid | username
---------------------------------
files_table
file_id | file_title | file_desc | dl_date
---------------------------------
comments_table
comid | userid | file_id | com_date
这是我的mysql查询,它的工作原理。但我想知道你的想法,以使其更好。
--Last files of member's friends
-- Find files of friendship.friendid=$userid
SELECT files_table.file_id AS c1, files_table.file_title AS c2, files_table.file_desc AS c3, files_table.dlauthor AS c4, files_table.dl_date AS date, IF(files_table.file_id IS NOT NULL, 'Friends_eBooks',FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.userid = user_table.userid
LEFT JOIN files_table ON files_table.dlauthor = user_table.username
WHERE friendship.friendid = $userid
AND friendship.STATUS = '1'
-- Find files of friendship.userid=$userid
UNION
SELECT files_table.file_id AS c1, files_table.file_title AS c2, files_table.file_desc AS c3, files_table.dlauthor AS c4, files_table.dl_date AS date, IF(files_table.file_id IS NOT NULL, 'Friends_eBooks',FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.userid = user_table.userid
LEFT JOIN files_table ON files_table.dlauthor = user_table.username
WHERE friendship.userid = $userid
AND friendship.STATUS = '1'
UNION ALL
-- Last comments of member's friends
-- Find comments of friendship.friendid=$userid
SELECT comments_table.comid AS c1, user_table.username AS c2, comments_table.dl_comment AS c3, comments_table.file_id AS c4, comments_table.com_date AS date, IF(comments_table.comid IS NOT NULL, 'Friends_Comments', FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.userid = user_table.userid
LEFT JOIN comments_table ON user_table.userid = comments_table.userid
WHERE friendship.friendid = $userid
AND friendship.STATUS = '1'
UNION
-- Find comments of friendship.userid=$userid
SELECT comments_table.comid AS c1, user_table.username AS c2, comments_table.dl_comment AS c3, comments_table.file_id AS c4, comments_table.com_date AS date, IF(comments_table.comid IS NOT NULL, 'Friends_Comments', FALSE) as Type
FROM friendship
LEFT JOIN user_table ON friendship.friendid = user_table.userid
LEFT JOIN comments_table ON user_table.userid = comments_table.userid
WHERE friendship.userid = $userid
AND friendship.STATUS = '1'
-- Last comments on member's files
UNION ALL
SELECT comments_table.comid AS c1,user_table.username AS c2,comments_table.dl_comment AS c3, files_table.file_id AS c4,comments_table.com_date AS date, IF(comments_table.comid IS NOT NULL, 'My_Comments', FALSE) as Type
FROM files_table
LEFT JOIN comments_table ON files_table.file_id = comments_table.file_id
LEFT JOIN user_table ON comments_table.userid = user_table.userid
WHERE
(files_table.status=1) AND
(files_table.dlauthor=$userid)
ORDER by date DESC
说明:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY friendship ref friendid friendid 3 const 22 Using where
1 PRIMARY user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.friendship.userid 1
1 PRIMARY files_table ref dlauthor dlauthor 92 func 10
2 UNION friendship ref PRIMARY PRIMARY 3 const 11 Using where
2 UNION user_table const PRIMARY PRIMARY 4 const 1
2 UNION files_table ref dlauthor dlauthor 92 func 10
3 UNION friendship ref friendid friendid 3 const 22 Using where
3 UNION user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.friendship.userid 1
3 UNION comments_table ref userid userid 3 ketabnak_ebooks.user_table.userid 6
4 UNION friendship ref PRIMARY PRIMARY 3 const 11 Using where
4 UNION user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.friendship.friendid 1
4 UNION comments_table ref userid userid 3 ketabnak_ebooks.user_table.userid 6
5 UNION files_table ref dlauthor dlauthor 92 const 294 Using where
5 UNION comments_table ref file_id file_id 3 ketabnak_ebooks.files_table.file_id 11
5 UNION user_table eq_ref PRIMARY PRIMARY 4 ketabnak_ebooks.comments_table.userid 1
NULL UNION RESULT <union1,2,3,4,5> ALL NULL NULL NULL NULL NULL Using filesort
弱点:
查询耗费了大量时间。
所有表的列数应相等。
我使用Friendship
表来查找所有成员的朋友。
当成员的朋友被接受为友情请求时,Status
为1。
首先,Userid = Memberid:
Userid | Friendid | Status
1 | 4 | 0
1 | 8 | 1
1 | 9 | 1
然后,我使用了UNION来合并Friendid = Memberid:
Userid | Friendid | Status
2 | 1 | 0
3 | 1 | 0
5 | 1 | 1
答案 0 :(得分:3)
让它变得更好的一个想法是停止认为你必须在一个查询中做所有事情。
答案 1 :(得分:0)
可能有人有更好的想法,当然,总会有人比你更聪明,无论如何我想分享这种方法,这是我1年前做的并为我工作的,这是为symfony 1.4做的,不需要知道symfony 1.4,这是不言自明的。
public function getAllEvents($uid) { $result = Doctrine_Query::create()->from('AquilaWall w')->where('w.uid = ? && w.is_public=1 ', $uid)->execute(); $array_uids = array(); foreach ($result as $uid_record){ array_push($array_uids, $uid_record->getUid()); array_push($array_uids, $uid_record->getUids()); } $array_uids = array_unique($array_uids); $array_uids = array_filter($array_uids); $array_uids = implode(",",$array_uids); $mdarray=array(); $flagg=0; $rowcount= $result -> count(); if ($rowcount>0) { // init arrays $arr_wall_videos = $arr_wall_comments = $arr_wall_news = $arr_wall_faqs =array(); $num_videos = $this->getNumberOf("AquilaVideos", $uid); if ($num_videos>0) { $query = "SELECT * FROM aquila_videos WHERE uid IN ($array_uids) "; $arr_wall_videos = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query); $flagg=1; } $num_news = $this->getNumberOf("AquilaNews", $uid); if ($num_news>0) { $query = "SELECT * FROM aquila_news WHERE uid IN ($array_uids) "; $arr_wall_news = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query); $flagg=1; } $num_faqs = $this->getNumberOf("sfFaqFaq", $uid); if ($num_faqs>0) { $query = "SELECT faq.uid, faq.id, faq.created_at, faq.question, faq.slug, cat.name FROM sf_faq_faq faq INNER JOIN sf_faq_category cat on cat.id=faq.category_id WHERE faq.uid IN ($array_uids)"; $arr_wall_faqs = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query); $flagg=1; } $num_comments = $this->getNumberOf("Comment", $uid); if ($num_comments>0) { $query = "SELECT * FROM comment WHERE user_id IN ($array_uids) "; $arr_wall_comments = Doctrine_Manager::getInstance()->getCurrentConnection()->fetchAssoc($query); $flagg=1; } if ($flagg) { $mdarray = array_merge((array)$arr_wall_videos, (array)$arr_wall_faqs); $mdarray = array_merge((array)$mdarray, (array)$arr_wall_news); $mdarray = array_merge((array)$mdarray, (array)$arr_wall_comments); foreach ($mdarray as $key => $row) { $dates[$key] = $row['created_at']; } array_multisort($dates, SORT_DESC, $mdarray); } } return $mdarray; }