7

我的数据库设计包括多个 MISAM 表,其中包含在线收集的测量值,

每行记录都包含自动递增的 id、一些数据和一个表示 unixtime 的整数。

我正在设计一种老化机制,并且我有兴趣使用 MySQL 分区来动态地基于 unixtime 对每个这样的表进行分区。

假设我对每个分区将代表单月数据感兴趣,最后一个分区应该代表 2 个月,如果记录到达下一个未表示的月份,则表示 2 个月的分区应重新组织以表示单月,新分区应创建代表 2 个月(1 个取自最后一个分区,1 个用于未来测量),

此外,当创建一个新分区时,我感兴趣的是最旧的分区将被删除。

  1. 我应该使用什么类型的分区(我的 unixtime 不是唯一键,我将如何使用 unixtime 进行分区)?
  2. 我将如何根据添加到表中的新记录将分区设计为完全动态的?

更新 12.12.12

我发现了与我所描述的类似方法的有趣链接your-magical-range-partitioning-maintenance-query

4

1 回答 1

10
  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+ 中立即对 datetime 列进行分区:

    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
    

PS 抱歉,如果 SQL 不完全正确 - 现在无法解析它。

于 2013-06-04T21:08:01.973 回答