Tôi đang xây dựng hệ thống trả lời bình luận lồng nhau trong ứng dụng của mình.Cách kết hợp các truy vấn MySQL này và sau đó truy cập dữ liệu chính xác
Mọi thứ hiện đang hoạt động như dự định tuy nhiên tôi thấy mình phải sử dụng một số truy vấn MySQL để truy xuất dữ liệu cần thiết. Và thậm chí tệ hơn truy vấn cho 'trả lời' nằm trong vòng lặp foreach. Có nghĩa là mặc dù nó thực hiện đáng ngưỡng mộ cho bây giờ, nó là xa tối ưu và sẽ gây ra vấn đề như tập dữ liệu phát triển.
Vì vậy, tôi muốn giải quyết vấn đề này trước khi tôi phát triển sâu hơn.
Vì các bảng cho ứng dụng này giống như blog wordpress cho trang web tôi đang sử dụng viết tắt wordpress cho các truy vấn.
Cách hiện tại trang web được tạo ra như sau:
Một bảng bình luận được truy vấn và tất cả các kết quả liên quan đến một projectid được lấy ra: -
$commentquery = "select projects_comments.*, users.user_url, users.display_name
from ".$wpdb->prefix."projects_comments projects_comments
left join ".$wpdb->prefix."users users on users.ID=projects_comments.userid
where projectid = '$projectid'
order by projects_comments.commentid desc
";
$comments = $wpdb->get_results($commentquery);
sau đó tôi thực hiện một vòng lặp foreach như sau : -
if($comments) {
foreach ($comments as $c)
{
$replyquery = "select project_replies.*, users.user_url, users.display_name
from ".$wpdb->prefix."project_replies project_replies
left join ".$wpdb->prefix."users users on users.ID=project_replies.uid
where project_replies.cid = '$c->commentid'
order by project_replies.id desc
limit 2
";
$replies = $wpdb->get_results($replyquery);
asort($replies);
$countquery = "select count(*)
from ".$wpdb->prefix."project_replies project_replies
where project_replies.cid='".$c->commentid."'
";
$replycount = $wpdb->get_var($countquery);
//generate html here
}
}
Bên trong vòng lặp này là hai truy vấn nữa. Đầu tiên nhận được câu trả lời cho mỗi nhận xét nhưng giới hạn kết quả thành 2 (Tôi muốn thực hiện việc này để có nút "xem tất cả câu trả lời" sau đó truy vấn DB cho phần còn lại nếu người dùng yêu cầu), số truy vấn thứ hai tổng số câu trả lời.
Các html sau đó cũng tạo ra cho mỗi câu trả lời trong vòng lặp sử dụng một foreach lồng thứ hai trong vòng lặp ở trên (nơi nó nói tạo mã html ở đây) như sau: -
if ($replies){
foreach ($replies as $r){
// generate each reply
}
}
Tất cả dữ liệu được kéo từ các mảng này theo cách sau:
$c->userid, $c->body etc... For the comments
$r->userid, $r->body etc... For the replies.
Tôi muốn giữ định dạng này nếu có thể. Vì vậy, như đã nêu ở phần đầu của câu hỏi, tất cả điều này hoạt động hoàn hảo tuy nhiên tôi biết rằng bằng cách lồng trả lời và đếm truy vấn, tôi đang thực hiện nhiều truy vấn hơn mức cần thiết. 100 nhận xét sẽ tạo ra 100 truy vấn trả lời và 100 truy vấn trả lời tính, v.v.
Nhờ một số người hữu ích trên trang web này, tôi đã xem xét sử dụng tham gia để nhận tất cả dữ liệu gốc một lần cho nhận xét và trả lời. Giống như vậy ...
$commentquery2 = "SELECT c.commentid, c.userid, c.body as cbody, c.projectid, c.posttime, cu.user_url AS cu_url, cu.display_name AS cu_name,
r.*, ru.user_url AS ru_url, ru.display_name AS ru_name
FROM ".$wpdb->prefix."projects_comments AS c
LEFT JOIN ".$wpdb->prefix."users AS cu ON cu.ID = c.userid
LEFT JOIN ".$wpdb->prefix."project_replies AS r ON r.cid = c.commentid
LEFT JOIN ".$wpdb->prefix."users AS ru ON ru.ID = r.uid
WHERE c.projectid = $projectid
ORDER BY c.commentid DESC, r.id DESC";
Mặc dù điều này thực sự hiệu quả (và đủ để tôi đánh dấu câu hỏi đó là đã trả lời), khi đưa vào thực tế, tôi đã gặp nhiều khó khăn. Trước tiên, việc này lấy tất cả dữ liệu dưới dạng các hàng riêng biệt có nghĩa là nếu tôi có 5 nhận xét với 3 câu trả lời, tôi thực sự nhận được 15 hàng trả về chứ không phải đối tượng dữ liệu lồng nhau với các câu trả lời được lồng trong mỗi hàng nhận xét.
Để giải quyết vấn đề này, tôi đã cố gắng một số thao tác mảng như:
$old_id=NULL;
$comments=array();
foreach($getcomments as $c){
if($c->commentid !== $old_id){
$comments[$old_id] = $c;
$old_id = $c->commentid;
}
$comments[$old_id]['replies'][] = $c;
}
Việc làm này mang lại cho tôi một đối tượng dữ liệu lồng nhau theo yêu cầu.Tuy nhiên, nó không bao gồm truy vấn đếm trả lời và nó không giới hạn mỗi bộ trả lời thành 2 như dự định, nó truy lục tất cả chúng.
Và cuối cùng với mã thế hệ html hiện tại của tôi trong vòng foreach:
foreach($comments){
//generate comment html
foreach($replies) {
//generate replies html
}
}
tôi dường như không thể có được nó để làm việc một cách chính xác với các đối tượng dữ liệu lồng nhau. Truy cập các câu trả lời sâu chính xác dường như khiến tôi bối rối. Vì vậy, để tóm tắt, tôi muốn có thể xóa các truy vấn lặp lại, kết hợp chúng thành một truy vấn lớn và hiệu quả hơn hoặc tệ nhất trong truy vấn dữ liệu và truy vấn đếm riêng, sau đó tạo đối tượng dữ liệu lồng nhau gọn gàng, với các nhận xét dưới dạng hàng và bất kỳ câu trả lời nào được lồng vào bên dưới tiêu đề 'trả lời'
Sau đó, tôi cần có khả năng lặp qua các mã này một cách chính xác trong mã php của mình để tạo html bắt buộc.
Tôi xin lỗi về độ dài của câu hỏi này và nhận ra rằng nó có thể khiến nhiều bạn trả lời, Nhưng tôi đã chiến đấu với điều này trong 19 giờ liền và thực sự cần sự giúp đỡ.
Rất cám ơn bất kỳ ai đề xuất bất kỳ đề xuất nào.
Có lẽ chỉ cần thêm bảng của bạn với dữ liệu ví dụ và bảng kết quả bạn mong đợi sẽ trở nên hữu ích hơn. –
Khá có thể Mosty, lấy điểm. Nếu tôi không vội vàng như tôi có một ổ đĩa 2 giờ trước tôi bắt đầu 10 phút, tôi sẽ chỉnh sửa câu hỏi như bạn đã đề xuất. – gordyr
Điều này đã được đề cập một vài lần, bao gồm bài viết này: http://stackoverflow.com/questions/317322/optimized-sql-for-tree-structures – crafter