Динамично MySQL разделяне, базирано на UnixTime

Моят дизайн на DB включва множество таблици MYISAM с измервания, събрани онлайн,

Всеки запис на ред съдържа автоматично увеличаващ се id, някои данни и цяло число, представляващо unixtime.

Проектирам механизъм за стареене и се интересувам да използвам MySQL разделяне за динамично разделяне на всяка такава таблица въз основа на unixtime.

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

Освен това, когато се създаде нов дял, ме интересува най-старият дял да бъде премахнат.

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

АКТУАЛИЗАЦИЯ 12.12.12

Намерих интересна връзка към подход, подобен на описания от мен вашата-заявка за поддържане-разделяне-на-магически диапазон.


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));
    

    Или можете да разделите колона за дата и час веднага в 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