На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! информация о разделе
user posted imageДанный раздел предназначается исключительно для обсуждения вопросов использования языка запросов SQL. Обсуждение общих вопросов, связанных с тематикой баз данных - обсуждаем в разделе "Базы данных: общие вопросы". Убедительная просьба - соблюдать "Правила форума" и не пренебрегать "Правильным оформлением своих тем". Прежде, чем создавать тему, имеет смысл заглянуть в раздел "Базы данных: FAQ", возможно там уже есть ответ.

Модераторы: Akina
  
> подскажите с запросом
    Ребята, я с MYSQL особо не контактировал, подскажите пожалуйста как решить задачу правильно.
    Каждые 5 секунд я хочу записывать текстовые данные в таблицу+штамп времени например. но записывать к примеру не больше 24 записей.
    т.е. записать новые данные до тех пор пока их не станет 24, а потом удалять старую запись.
    как это лучше всего реализовать? можно ли это реализовать одним запросом?
    помогите примером пожалуйста.
      Цитата Emmys @
      можно ли это реализовать одним запросом?

      Можно. Заранее сделать 24 записи в таблице, и каждый раз перезаписывать запись с минимальным порядковым номером, присваивая ей номер max+1.
        Идея не плохая, но я заранее не буду знать минимальный порядковый номер, поэтому сначала должен сделать запрос? получается 2 запроса.
        особой разницы тогда нет в том что я добавлю 25тую запись и удалю старую запись по штампу времени. получится так же 2 запроса.
        и опять же создавать 25 пустых записей не входило в планы. это доп операции
        Сообщение отредактировано: Emmys -
          Цитата Emmys @
          Идея не плохая

          Идея отличная. Забудь об инсертах, только апдейт самой старой записи.
            Akina, только Update все равно не получится в рамках задачи. по сути это логи. где то на месяц, где то год, где то сутки. из за этого не буду же создавать пустые записи?.. т.е. я планировал записывать допустим раз в час. только 24 записи делать.
            просто я плоховато в запросах разбираюсь. думаю может подскажут как лучше это сделать в рамках задачи
            Сообщение отредактировано: Emmys -
              Цитата Emmys @
              из за этого не буду же создавать пустые записи?

              Что, ручки оборвутся?
              Надо будет - будешь создавать где надо и сколько надо.
              Цитата Emmys @
              Update все равно не получится в рамках задачи

              Порой лучше сначала подумать, что за совет тебе дали, а не бросаться отвечать.
              JoeUser абсолютно прав. А ты просто пока не понял до конца его совет.
                Цитата JoeUser @

                Можно. Заранее сделать 24 записи в таблице

                Если будет больше?

                Цитата JoeUser @
                каждый раз перезаписывать запись с минимальным порядковым номером, присваивая ей номер max+1.

                Решение хорошее, но временные таблицы "жрут" ресурсы....

                Решение? Кроме JoeUser?
                Цитата Akina @
                Порой лучше сначала подумать, что за совет тебе дали,

                Да...., не дочитал. Но варианты ....есть.
                  Цитата Emmys @
                  Идея не плохая, но я заранее не буду знать минимальный порядковый номер, поэтому сначала должен сделать запрос? получается 2 запроса.

                  На примере трех записей ...

                  Подготовка таблицы

                  ExpandedWrap disabled
                    CREATE TABLE `Logs` (
                     `Value` BIGINT NOT NULL,
                     `Path` VARCHAR(1024)
                    );
                    INSERT INTO `Logs` (`Value`,`Path`)
                    VALUES (1,"-empty-"),
                           (2,"-empty-"),
                           (3,"-empty-");

                  Проверяем (свежие логи выше):

                  ExpandedWrap disabled
                    SELECT * FROM `Logs` AS L
                    ORDER BY L.`Value`DESC

                  Видим:

                  ValuePath
                  3-empty-
                  2-empty-
                  1-empty-

                  Запись лога значением "new log"

                  ExpandedWrap disabled
                    UPDATE `Logs` AS Res
                    LEFT JOIN (
                      SELECT MIN(Tmp.`Value`) AS VMin, MAX(Tmp.`Value`) AS VMax
                      FROM `Logs` AS Tmp
                    ) AS Tmp ON Res.`Value` = Tmp.VMin
                    SET Res.`Value` = VMax+1, Res.`Path` = "new log"
                    WHERE VMin IS NOT NULL AND VMax IS NOT NULL

                  Проверяем (свежие логи выше):

                  ExpandedWrap disabled
                    SELECT * FROM `Logs` AS L
                    ORDER BY L.`Value`DESC

                  Видим:

                  ValuePath
                  4new log
                  3-empty-
                  2-empty-

                  Старая запись 1 - "исчезла", новая запись 4 - "появилась".
                  Q.E.D.

                  Добавлено
                  Цитата Bas @
                  Решение хорошее, но временные таблицы "жрут" ресурсы....

                  :scratch:
                    Цитата JoeUser @
                    Подготовка таблицы

                    Плохой пример, не учтены особенности, озвученные автором (типы данных):
                    Цитата Emmys @
                    я хочу записывать текстовые данные в таблицу+штамп времени

                    Соответственно:

                    1) Создание таблицы
                    ExpandedWrap disabled
                      CREATE TABLE logs (textdata TEXT, dt DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);

                    Т.е. а) Данные - текст без ограничения размера; б) Штамп времени с автоприсвоением значения при создании и корректировке.

                    2) Добавление необходимого количества "пустых" записей
                    ExpandedWrap disabled
                      INSERT INTO logs (textdata)
                      SELECT '' FROM (select 1 union select 2 union ... union 24) dummy;

                    Поле штампа времени будет заполнено автоматически текущим значением.

                    3)Добавление новых данных с уничтожением наиболее старых.
                    ExpandedWrap disabled
                      UPDATE logs
                      SET textdata = 'новые текстовые данные'
                      ORDER BY dt ASC
                      LIMIT 1

                    Сортировка обеспечит корректировку самой старой записи, ограничение количества обновит только одну запись. Полю штампа времени присваивается значение момента добавления записи - автоматически. Впрочем, если есть необходимость устанавливать это поле определённым, не текущим, значением, никто не мешает добавить в список полей это поле, и соответственно в список значений присваиваемое ему значение (нафига только такое надо?).

                    4) Корректировка количества записей при необходимости
                    4а) Добавление дополнительных записей
                    ExpandedWrap disabled
                      INSERT INTO logs (textdata, dt)
                      SELECT '', '2000-01-01' FROM (select 25 union select 26 union ... union select @max_count) dummy;

                    4б) Удаление избыточных записей
                    ExpandedWrap disabled
                      DELETE FROM logs ORDER BY dt ASC LIMIT @del_count;


                    И относительно типов данных в таблице лога. Если версия MySQL-сервера позволяет, я бы подумал не о текстовом формате хранения, а о JSON. Начиная с версии 5.7.8, MySQL поддерживает этот тип данных и структурированную работу с ним.
                      Цитата Akina @
                      Плохой пример, не учтены особенности, озвученные автором (типы данных):

                      Akina, да я только принцип "озвучил".
                      Но с штампом времени твое решение выглядит конечно гораздо по-симпатичнее.
                      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                      0 пользователей:


                      Рейтинг@Mail.ru
                      [ Script execution time: 0,0367 ]   [ 15 queries used ]   [ Generated: 29.03.24, 01:21 GMT ]