【问题标题】:How to order/sort a list where multiple users insert into different positions?如何对多个用户插入不同位置的列表进行排序/排序?
【发布时间】:2011-12-21 18:07:42
【问题描述】:

我正在制作一个应用程序,其中多个用户可以在其他 cmets 上方或下方发布 cmets。这不是线程类型的结构。这更像是在 Word 文档上进行协作。我在设计这些条目的排序方法时遇到了问题。

使用 mySQL 和 PHP,按进入时间排序不起作用,按评论位置排序也不起作用,因为如果用户在其他 cmets 之间发帖,则位置会发生变化。 我不想为每个新条目重新序列化评论位置(如果有数千个条目和数十个用户在做同样的事情怎么办)。

最好的设计方法是什么?

【问题讨论】:

  • 记得接受一个答案,如果它帮助你解决了你的问题。

标签: php mysql sorting linked-list


【解决方案1】:

您所描述的是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() 的结果按摩到一个根据 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 中链表的更多信息:

【讨论】:

    【解决方案2】:

    这听起来是使用MPTT,修改的预排序树遍历的好时机。它通常用于线程评论板和那种性质的东西。在 RDBMS 中保持层次结构的所有方法中,修剪或向树添加节点时开销最低。

    这里是good introand another。谷歌搜索它应该可以为您提供更多信息。一旦你理解了这个概念,实现起来一点也不难。

    【讨论】:

      【解决方案3】:

      我肯定会按位置排序。插入时,只需增加它下面的所有条目——单个update 查询。该实现的一个重要特征是它可以很好地处理并发性。如果有两个并发插入,您不关心递增的顺序(但您确实需要一个非位置 pk 所以当插入发生在您上方时不会感到不安)。

      另一种方法是将其建模为树,这意味着您只需更新分支中您下方的条目。但这将是一种罕见的情况,维护开销是合理的。 (折衷方案是将模型建模为垂柳——你将总数分成形成分支的块,但你不允许分支中的分支;这避免了更新每条记录;但是我仍在猜测与第一种方法相比,这不值得开销。)

      【讨论】:

      • 请注意,Gustav 的方法在三个建议中性能最差。您希望能够将可能很大的结果集快速呈现为 HTML,因此请务必考虑性能。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多