Как заказать / отсортировать список, где несколько пользователей вставляют в разные позиции? - PullRequest
5 голосов
/ 04 ноября 2011

Я создаю приложение, в котором несколько пользователей могут оставлять комментарии выше или ниже других комментариев.Это не структура типа потока.Это больше похоже на сотрудничество в документе Word.У меня возникли проблемы при разработке метода, эти записи сортируются.

При использовании MySQL и PHP сортировка по времени записи не работает, а также сортировка по позиции комментария не происходит, поскольку позиция изменяется, если пользователь публикует записи между другими комментариями.Я не хочу повторять сериализацию позиций комментариев для каждой новой записи (что если тысячи записей и десятки пользователей делают одно и то же).

Каков наилучший способ создать это?

Ответы [ 3 ]

1 голос
/ 08 ноября 2011

То, что вы описываете, представляет собой связанный список . Проблема в том, что их обычно трудно получить, используя только 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:

0 голосов
/ 08 ноября 2011

звучит как хорошее время для использования MPTT, Модифицированный Предзаказ Обход дерева . Он часто используется для многопоточных комментариев и тому подобного. Из всех способов сохранить иерархические структуры в СУБД, он имеет самые низкие издержки при сокращении или добавлении узлов в дерево.

вот хорошее вступление , и еще одно . Погуглите, чтобы получить больше информации. Это совсем не сложно реализовать, если вы понимаете концепцию.

0 голосов
/ 08 ноября 2011

Я бы определенно пошел с упорядочением по позиции.При вставке, это просто вопрос увеличения всех записей под ним - один update запрос.Важной особенностью этой реализации является то, что она очень хорошо справляется с параллелизмом;если есть две одновременные вставки, вам все равно, в каком порядке выполняется инкремент (но вам нужен непозиционный pk, поэтому нет проблем, когда вставка происходит над вами).

Альтернативой является его моделирование в виде дерева, что означает, что вам нужно только обновить записи под вами в ветке.Но это будет редкая ситуация, когда затраты на обслуживание оправданы.(Компромисс состоит в том, чтобы моделировать как плачущую иву - вы делите общее количество на куски, которые формируют ветви, но вы не допускаете ветви из ветвей; это избавляет от необходимости когда-либо обновлять каждую отдельную запись; однако я все еще предполагаюэто не стоит накладных расходов по сравнению с первым подходом.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...