【问题标题】:How can I partition a MySql table for use with 90 day rotating partitions?如何对 MySql 表进行分区以用于 90 天轮换分区?
【发布时间】:2013-06-25 11:56:58
【问题描述】:

我想创建一个分区表,该表将填充数亿条记录。使用分区,我怎样才能将特定日期的记录放入一个分区,然后将第二天的记录放入另一个分区,等等。然后在九十多天后,我可以从最旧的分区中删除旧数据。

我尝试了这个声明(哈希函数使用对分区数量取模来计算哪个分区获取数据)。这样可以确保每天使用 92 个分区中的不同分区;除非它不起作用。

CREATE TABLE records(
    id INT NOT NULL AUTO_INCREMENT,
    dt DATETIME,
    PRIMARY KEY (id)
)
PARTITION BY HASH((MOD(DAYOFYEAR(dt), 92) + 92))
PARTITIONS 92;

上述sn-p的问题是hash表达式中使用的列必须是表内的唯一键。

如何解决这个问题,以便根据每天的记录有九十个(ish)旋转分区?

如果我只是将dt 列添加到主键,如果选择日期范围,它似乎会命中所有分区,这不是我想要的。

有什么想法吗?

【问题讨论】:

    标签: mysql partitioning


    【解决方案1】:

    原因是要对日期字段进行分区并按范围查询,您必须在分区表达式中使用YEAR()TO_DAYS()

    这样的分区按预期工作:

    CREATE TABLE `alert` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `eventId` int(10) unsigned NOT NULL,
      `occurred` datetime NOT NULL,
      KEY `id` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
    /*!50100 PARTITION BY RANGE (TO_DAYS(occurred))
    (PARTITION 28_06 VALUES LESS THAN (735413) ENGINE = InnoDB,
     PARTITION 29_06 VALUES LESS THAN (735414) ENGINE = InnoDB,
     PARTITION 30_06 VALUES LESS THAN (735415) ENGINE = InnoDB,
     PARTITION 01_07 VALUES LESS THAN (735416) ENGINE = InnoDB,
     PARTITION 02_07 VALUES LESS THAN (735417) ENGINE = InnoDB,
     PARTITION 03_07 VALUES LESS THAN (735418) ENGINE = InnoDB,
     PARTITION 04_07 VALUES LESS THAN (735419) ENGINE = InnoDB,
     PARTITION 05_07 VALUES LESS THAN (735420) ENGINE = InnoDB,
     PARTITION 06_07 VALUES LESS THAN (735421) ENGINE = InnoDB,
     PARTITION 07_07 VALUES LESS THAN (735422) ENGINE = InnoDB) */
    
    mysql> explain partitions SELECT * FROM alert WHERE occurred >= '2013-07-02' and occurred <= '2013-07-04';
    +----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
    | id | select_type | table | partitions        | type | possible_keys | key  | key_len | ref  | rows | Extra       |
    +----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
    |  1 | SIMPLE      | alert | 02_07,03_07,04_07 | ALL  | NULL          | NULL | NULL    | NULL |    3 | Using where |
    +----+-------------+-------+-------------------+------+---------------+------+---------+------+------+-------------+
    

    然后您需要自己管理分区的删除和创建。

    【讨论】:

    • 所以这意味着如果我需要收集 30、60,90 天前的记录,那么我需要指定 to_days_value -90 等等,每月继续收集30 天前的记录,每次我们更改分区并创建新分区时。对吗?
    【解决方案2】:

    实际上,问题在于,如果键中的所有列都不包含在哈希函数中,则无法在分区表上定义 PRIMARY 或 UNIQUE 键。

    一种可能的“修复”是从 KEY 定义中删除“PRIMARY”关键字。

    问题是当你声明一个键为 UNIQUE 或 PRIMARY 时,MySQL 必须强制唯一性。为了强制执行,MySQL 需要能够检查键值是否已经存在。 MySQL 不是检查每个分区,而是使用分区函数来确定可以找到特定键的分区。

    【讨论】:

      猜你喜欢
      • 2012-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      • 2014-06-18
      • 2018-12-16
      • 1970-01-01
      相关资源
      最近更新 更多