我做了一個應用程序,其中多個用戶可以發表評論上方或下方的其他評論。這不是一個線程類型的結構。這更像是在Word文檔上進行合作。我無法設計這些條目的方法排序。如何對多個用戶插入不同位置的列表進行排序/排序?
使用mySQL和PHP,按輸入時間排序不起作用,也不按評論位置進行排序,因爲如果用戶在其他評論之間發帖,位置會發生更改。 我不想重新序列化每個新條目的評論位置(如果有成千上萬的條目和幾十個用戶做同樣的事情會怎麼樣)。
什麼是最好的設計方法?
我做了一個應用程序,其中多個用戶可以發表評論上方或下方的其他評論。這不是一個線程類型的結構。這更像是在Word文檔上進行合作。我無法設計這些條目的方法排序。如何對多個用戶插入不同位置的列表進行排序/排序?
使用mySQL和PHP,按輸入時間排序不起作用,也不按評論位置進行排序,因爲如果用戶在其他評論之間發帖,位置會發生更改。 我不想重新序列化每個新條目的評論位置(如果有成千上萬的條目和幾十個用戶做同樣的事情會怎麼樣)。
什麼是最好的設計方法?
我肯定會按位置排序。插入時,只是增加它下面的所有條目的問題 - 一個update
查詢。該實現的一個重要特徵是它很好地處理了併發性;如果有兩個併發插入,你不關心增加的順序是什麼(但是你確實需要一個非位置的pk,所以當插入發生在你上面時不會出現不安)。
另一種方法是將其建模爲樹,這意味着您只需更新分支下方的條目。但是,這將是一種罕見的情況,維護費用是合理的。 (妥協是將模型當成哭泣的柳樹 - 將總數分成組成分支的塊,但不允許從分支中分支;這樣可以避免必須更新每條記錄;但是我仍然猜測與第一種方法相比,這不值得花費開銷。)
請注意,古斯塔夫的方法是三個建議中表現最差的。您希望能夠將可能較大的結果集快速呈現到HTML中,因此請務必考慮性能。 – niczero
你所描述的是一個linked list。問題在於它們通常很難用SQL來檢索。我的解決方案是使用PHP在檢索時進行排序。
你的桌子會是這個樣子:
CREATE TABLE page {
page_id INT,
first_comment_id INT
}
CREATE TABLE comment {
comment_id INT PRIMARY KEY AUTOINCREMENT,
page_id INT,
next_comment_id INT
}
您的查詢很簡單:
SELECT comment_id, next_comment_id
FROM comment
WHERE page_id = $page_id
ORDER BY comment_id DESC
的重要一步就是按摩從mysql_fetch_assoc()的結果將是根據索引的數組to comment_id:
$result = mysql_query($sql);
$indexed_list = array();
while ($row = mysql_fetch_assoc($result))
{
$indexed_list[$row['comment_id']] = $row;
}
產生與此類似的數組:
$indexed_list = array(
1 => array("comment_id"=>1, "next_comment_id"=>2),
2 => array("comment_id"=>2, "next_comment_id"=>5),
3 => array("comment_id"=>3, "next_comment_id"=>4),
4 => array("comment_id"=>4, "next_comment_id"=>0),
5 => array("comment_id"=>5, "next_comment_id"=>3));
PHP函數將其分類成可顯示的順序很簡單:
function llsort($indexed_list, $first_comment_id)
{
$sorted_list = array();
$node = $indexed_list[$first_comment_id];
array_push($sorted_list, $node);
do
{
$node = $indexed_list[$node['next_comment_id']];
array_push($sorted_list, $node);
} while ($node['next_comment_id'] != 0
AND isset($indexed_list[$node['next_comment_id']]));
return $sorted_list;
}
您從頁表中獲取first_comment_id。當然,你仍然需要實現插入節點和刪除節點的功能,但這些功能仍然是讀者的練習。不要忘記使用事務來插入和刪除節點。
更多在MySQL上鍊表信息:
這聽起來像使用MPTT的好時機,修改預有序的樹Traversa l。它通常用於線程評論板和那種性質的東西。在RDBMS中保留層次結構的所有方法中,在修剪或向樹添加節點時,開銷最低。
這裏是good intro,and another。谷歌搜索它應該讓你更多的信息。一旦理解了這個概念,就不難實現。
請記住**接受**一個答案,如果它幫助你解決你的問題。 –