Динамическое разбиение MySQL на разделы на основе UnixTime

Мой дизайн БД включает несколько таблиц MYISAM с измерениями, собранными онлайн,

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

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

Скажите, что меня интересует, что каждый раздел будет представлять один месяц данных, последний раздел должен представлять 2 месяца, если записи поступают за следующий непредставленный месяц, раздел, представляющий 2 месяца, должен быть реорганизован, чтобы представлять один месяц, и новый раздел должен будет создан за 2 месяца (1 взят из последнего раздела и 1 для будущих измерений),

Кроме того, при создании нового раздела мне интересно, что самый старый раздел будет удален.

  1. Какой тип разделения я должен использовать (мой unixtime не является уникальным ключом, и как я могу использовать unixtime для целей разделения)?
  2. Как сделать разделение полностью динамическим на основе новых записей, добавленных в таблицы?

ОБНОВЛЕНИЕ 12.12.12

Я нашел интересную ссылку на аналогичный подход к тому, что я описал ваш-magical-range-partitioning-maintenance-query.


person Michael    schedule 12.12.2012    source источник


Ответы (1)


  1. Разделение не обязательно должно основываться исключительно на уникальном ключе. Однако, если уникальный ключ присутствует, его следует включить в столбцы, используемые для разделения таблицы. Чтобы разделить таблицу в столбце UNIXTIME, выполните:

    ALTER TABLE MyTable
    PARTITION BY RANGE COLUMNS (UNIX_TIMESTAMP(datetime_column))
    (
      PARTITION p01 VALUES LESS THAN (2),
      PARTITION p02 VALUES LESS THAN (3),
      PARTITION p03 VALUES LESS THAN (4),
      PARTITION p04 VALUES LESS THAN (MAXVALUE));
    

    Или вы можете разделить столбец datetime прямо в MySQL 5.5+:

    ALTER TABLE MyTable
    PARTITION BY RANGE COLUMNS (datetime_column)
    (
      PARTITION p01 VALUES LESS THAN ('2013-01-01'),
      PARTITION p02 VALUES LESS THAN ('2013-02-01'),
      PARTITION p03 VALUES LESS THAN ('2013-03-01'),
      PARTITION p04 VALUES LESS THAN (MAXVALUE));
    
  2. Полностью автоматизированная версия (каждый месяц хранится в отдельном разделе, данные хранятся за 5 месяцев):

    ALTER TABLE MyTable
    PARTITION BY RANGE COLUMNS (YEAR(datetime_column)*100 + MONTH(datetime_column))
    (
      PARTITION p201301 VALUES LESS THAN (201301),
      PARTITION p201302 VALUES LESS THAN (201302),
      PARTITION p201303 VALUES LESS THAN (201303),
      PARTITION p201304 VALUES LESS THAN (201304),
      PARTITION p201305 VALUES LESS THAN (201305),
      PARTITION p_MAXVALUE VALUES LESS THAN (MAXVALUE));
    
    
    
    DECLARE @Min_Part int
    DECLARE @Last_Part int
    DECLARE @SQL varchar (1000)
    
    If (select count (distinct MONTH(datetime_column)) from MyTable) > 5 THEN
        BEGIN
    
        select @Min_Part = (select min(year(datetime_column)*100 + month(datetime_column)) from MyTable),
        @Last_Part = (select max(year(datetime_column)*100 + month(datetime_column)) from MyTable)
    
        set @SQL = 'Alter table MyTable REORGANIZE PARTITION p_MAXVALUE (into partition p' +TO_CHAR (@Last_Part) + 'values less than (' + TO_CHAR (@Last_Part) + ')' 
    
        call common_schema.eval (@sql)
    
        set @SQL = 'Alter table MyTable DROP PARTITION p' + TO_CHAR (@Min_Part) 
    
        call common_schema.eval (@sql)
    
    
    END
    

P.S. Приносим извинения, если SQL не совсем правильный - сейчас не могу его разобрать.

person Stoleg    schedule 04.06.2013