Планировщик событий для временных таблиц и строк с их именами - PullRequest
0 голосов
/ 12 октября 2018

У меня есть база данных со следующими таблицами: temp_1, temp_2 .... и cached_tbl.Внутри cached_tbl у меня есть столбец table_name и в соответствующих строках я храню все имена временных таблиц, которые я упоминал выше.Поэтому я хотел создать планировщик событий, который бы отбрасывал временные таблицы, созданные более суток назад ... Для этого я пишу что-то вроде

SELECT (DROP) 
    *
FROM
    information_schema.TABLES
WHERE 
    table_schema = 'db' and CREATE_TIME < (NOW()-INTERVAL 24 HOUR)

Но я также хотел удалитьстроки, содержащие только что удаленные имена таблиц внутри таблицы cached_tbl ... Посоветуйте, пожалуйста, как я могу это сделать ... В обычном программировании я бы просто просматривал все выбранные table_names из предыдущего скрипта в массиве и проходил цикл, сравнивая эти имена таблиц.к именам таблиц в cached_tbls ... Но я понятия не имею, как реализовать это в mysql

Ответы [ 2 ]

0 голосов
/ 17 октября 2018

Алиса, я предполагаю, что вы используете соглашение об именах temp_1, temp_2, чтобы указать, что вы намерены удалить эти таблицы только через короткое время и что это не ВРЕМЕННЫЕ таблицы, как предполагает @ anton.

Несколько замечаний ab: из приведенного ниже примера:

Он написан как событие, но вы можете легко превратить его в процедуру, которая позволит вам передавать различные значения интервала или имя базы данных.

Вам нужно будет использовать курсор для извлечения имен таблиц и динамического SQL, чтобы подготовить и выполнить операторы для удаления таблиц и удаления записей в cached_tbl.

Я сделал этонемного более сложный, чем строго необходимый, чтобы проиллюстрировать, как вы можете создать и заполнить таблицу TEMPORARY одним оператором, что было бы полезно, если бы вы превратили это в процедуру.Вы можете упростить его, объявив курсор как оператор в @ sql1 и удалив подготовку и выполнение в stmt1.

Возможно, вы хотите быть более ограничительным при выборе таблиц, в противном случае вы рискуете удалить cached_tbl или другие таблицы базы данных случайно.

DELIMITER //

CREATE EVENT prune
ON SCHEDULE
  EVERY 1 DAY
DO

  BEGIN
    DECLARE done BOOLEAN DEFAULT FALSE;
    DECLARE tname VARCHAR(64);
    DECLARE cur CURSOR FOR SELECT * FROM `tables_tmp`;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    SET @sql1 = 
      'CREATE TEMPORARY TABLE `tables_tmp`  
       SELECT `table_schema`,`table_name`  
       FROM `information_schema`.`tables`
       WHERE `table_schema` = ''db''
       AND `table_name` LIKE ''temp_%'' 
       AND `create_time` < (NOW() - INTERVAL 1 DAY)';

    PREPARE stmt1 FROM @sql1;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;

    OPEN cur;

    myloop:LOOP
      FETCH cur INTO tname;

      IF done = TRUE THEN
        LEAVE myloop;
      END IF;

      SET @sql2 = CONCAT('DROP TABLE IF EXISTS `db`.`', tname , '`;'); 
      PREPARE stmt2 FROM @sql2;
      EXECUTE stmt2;
      DEALLOCATE PREPARE stmt2;

      SET @sql3 = CONCAT('DELETE FROM `cached_tbl` WHERE `table_name` = ''', tname , ''';'); 
      PREPARE stmt3 FROM @sql3;
      EXECUTE stmt3;
      DEALLOCATE PREPARE stmt3;

    END LOOP;

  END //

DELIMITER ;
0 голосов
/ 12 октября 2018

Привет и добро пожаловать в ТАК.

Отвечая на ваш вопрос - вы не должны делать это таким образом (просматривая список временных таблиц и т. Д.).Вообще говоря, временные таблицы служат только для вашего текущего соединения (сеанса), а когда вы закрываете одну - все ваши временные таблицы исчезают.Это нормально.Временные таблицы должны служить вам своего рода дополнительным кешем для вашей логики - например, когда вам нужно экспортировать результаты из одной процедуры в другую.

Но вы должны помнить, что SQL используется для постоянного хранения данных и управления ими, а если вы хотите хранить данные - используйте обычные таблицы, а MySQL сделает все остальное.Используйте триггеры или хранимые процедуры для проверки / сброса данных из таблиц.

Более конкретно говоря об именах временных таблиц.Проверяя руководство - https://dev.mysql.com/doc/refman/5.7/en/innodb-information-schema-temp-table-info.html - вы увидите, что MySQL хранит имена временных таблиц самостоятельно

CREATE TEMPORARY TABLE t1 (c1 INT PRIMARY KEY) ENGINE=INNODB;

SELECT * FROM INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO\G
*************************** 1. row ***************************
            TABLE_ID: 194
                NAME: #sql7a79_1_0
              N_COLS: 4
               SPACE: 182
PER_TABLE_TABLESPACE: FALSE
       IS_COMPRESSED: FALSE

Это не таблица t1 ,но # sql7a79_1_0 .Вы можете сказать - подождите, я знаю, что имя таблицы t1 !- но вы должны помнить, что t1 - это просто некий указатель, который вы используете в своем текущем сеансе и в своих целях, MySQL полагается на свои собственные механизмы.

...