Реализация твиттер-подобного запроса временной шкалы на основе даты и времени для приложения для событий

Я строю приложение для обмена событиями в Android с Codeigniter и MySQL. То, что я пытаюсь сделать, это отобразить список событий в приложении для Android с ограничением, скажем, только 10 результатов для каждого запроса, и позже я могу выполнить задачу "загрузить больше".

Если мы говорим о временной шкале Твиттера, допустим, что в таблице состояния есть следующие столбцы (PS, я их составил):

  • id (считайте, что это первичный ключ с автоинкрементом)
  • date_post
  • чирикать

Если пользователь публикует твит, идентификатор автоматически присваивается со следующим значением автоматического приращения, а столбец даты и времени назначается с текущим временем, поэтому твит упорядочен правильно, более новый твит будет вставлен с большим идентификатором. При этом, чтобы отображать временную шкалу с результатом 20 каждый раз при загрузке, и мы загружаем ее из старого твита в новый, мы можем использовать следующий запрос (CMIIW):

SELECT * FROM TWEETS WHERE ID > last_id_loaded AND date_post >= last_date_loaded ORDER BY ID ASC LIMIT 20;

с параметром last_id_loaded, который мы отправляем на основе последнего загруженного твита, или 0, если это первый раз, то же самое с параметром last_date_loaded.

Теперь вернемся к моему приложению. У меня есть таблица с именем events со следующим столбцом:

  • id (первичный ключ, автоинкремент)
  • имя (название мероприятия)
  • date_start (дата и время проведения мероприятия)
  • так далее

Когда пользователь создает событие, идентификатору присваивается следующее значение автоинкремента, но в отличие от таблицы твитов, о которой я упоминал ранее, событие не упорядочено по дате и времени, поскольку больший идентификатор не означает более новое событие и наоборот. Например:

----- | ----------- | -------------
id    | name        | date_start
----- | ----------- | -------------
1       Event A       2013-05-26 13:13:00
2       Event B       2013-05-23 09:00:00
3       Event C       2013-05-27 10:00:00
4       Event D       2013-05-27 10:00:00
5       Event E       2013-05-27 10:00:00
6       Event F       2013-05-28 08:00:00
7       Event G       2013-05-31 13:13:00
8       Event H       2013-05-29 09:00:00
9       Event I       2013-05-29 08:00:00
10      Event J       2013-05-30 13:13:00

Если мы заказываем на основе столбца date_start, это должно быть: событие B, событие A, событие C, событие D, событие E, ...., событие G.

Как мы видим, есть 3 столбца с одинаковым значением date_start: Событие C, D и E. Если я хочу загрузить событие из более старого в более новое событие с ограничением только 3 для каждого запроса, то есть я ожидаю возврата события B, A, C, в настоящее время я использую этот следующий запрос:

SELECT * FROM EVENTS WHERE DATE_START >= last_date_retrieved ORDER BY DATE_START ASC, ID ASC

Но тогда как я могу убедиться, что следующий запрос приведет к следующему значению после этого? Я имею в виду предыдущий запрос: B, A, C с последним date_start 2013-05-27 10:00:00

Если я воспользуюсь предыдущим запросом, то получится C, D, E, а не D, E и F, как я ожидал.

Что мне здесь не хватает? Я готов получить несколько советов. Спасибо.

1 ответ

Безусловно, я придумаю это решение. Я добавляю новый столбец в таблицу событий под названием "counter", который будет использоваться как счетчик для событий с той же датой-временем. Например, если мы вставим новые данные о событии, он проверит недавно вставленное событие datetime с другим. Например, если в таблице существует такое же время и дата с максимальным значением 5, значение счетчика для вновь вставленного события будет присвоено с 5+1 = 6. Я использую триггер для этого

    CREATE TRIGGER `events_BINS` BEFORE INSERT ON events FOR EACH ROW
    BEGIN 
       SET @cnt = NULL;
       IF EXISTS (SELECT 1 FROM events where date_start = new.date_start)  THEN 
           SELECT MAX(counter) into @cnt FROM events where date_start = new.date_start;
           SET new.counter = @cnt + 1;
       ELSE
           SET new.counter = 1;
       END IF;
    END;

Я тоже создаю триггер перед обновлением:

CREATE TRIGGER `events_BUPD` BEFORE UPDATE ON events FOR EACH ROW
BEGIN
  SET @cnt = NULL;
IF old.date_start != new.date_start THEN 
  IF EXISTS (SELECT 1 FROM events where date_start = new.date_start)  THEN
    SELECT MAX(counter) into @cnt FROM events where date_start = new.date_start;
    SET new.counter = @cnt + 1;
  ELSE
    SET new.counter = 1;
  END IF;
END IF;
END;

При таком подходе я смогу сделать запрос с помощью следующего предложения:

WHERE (date_start = last_date_retrieved AND counter > last_counter_retrieved) 
OR (date_start > last_date_retrieved)
ORDER BY date_start, counter asc

Пожалуйста, дайте мне знать, если у кого-то из вас есть лучший подход к этому. Спасибо:)

Другие вопросы по тегам