首页 > 解决方案 > 作为散列子分区的一部分,如何为键指定多个列?

问题描述

我正在创建一个具有复合分区的表 ( RANGE, then HASH)

我的实际桌子很大,所以这里有一张精简的虚拟桌子,它显示了重要的部分:

CREATE TABLE table1(
    id INT NOT NULL AUTO_INCREMENT,

    dtvalue DATETIME NOT NULL, -- Used for RANGE partitions

    v1 INT NOT NULL, -- Used for HASH partitions
    v2 INT NOT NULL,

    CONSTRAINT pk_table1 PRIMARY KEY(id),

    CONSTRAINT uk_table1 UNIQUE(v1,v2) -- Unique key for v1 and v2
)
ROW_FORMAT=COMPRESSED
PARTITION BY RANGE(dtvalue)
SUBPARTITION BY HASH(v1,v2) SUBPARTITIONS 32 -- Does this HASH subpartition work?
(PARTITION p20191101 VALUES LESS THAN('2019-11-01'),
 PARTITION p20191102 VALUES LESS THAN('2019-11-02'),
 PARTITION pMax VALUES LESS THAN MAXVALUE);

此表将经常被连接v1v2组合为唯一标识符,因此使用两个列作为HASH键是至关重要的。

我的问题是,您可以指定多个列作为HASH键的一部分吗?

或者您可以为密钥指定唯一密钥本身HASH吗?
例如SUBPARTITION BY HASH(uk_table1) SUBPARTITIONS 32

标签: mysqlsqlpartitioningunique-constraintdata-partitioning

解决方案


您可能需要重新考虑有关分区的方法。MySQL 非常挑剔——所以主键和唯一约束需要包括分区键。

并且,哈希分区采用整数,但允许的显式函数的曲目非常有限。令人高兴的是,您可以使用存储的生成列来解决这个问题。

因此,以下实现了您的既定目标:

CREATE TABLE table1 (
    id INT NOT NULL AUTO_INCREMENT,

    dtvalue datetime NOT NULL, -- Used for RANGE partitions

    v1 INT NOT NULL, -- Used for HASH partitions
    v2 INT NOT NULL,

    CONSTRAINT pk_table1 PRIMARY KEY(id, dtvalue, v1_v2),

    v1_v2 int generated always as (cast(conv(left(md5(concat_ws(':', v1, v2)), 8), 16, 10) as unsigned)) stored
)
ROW_FORMAT=COMPRESSED
PARTITION BY RANGE COLUMNS (dtvalue)
SUBPARTITION BY HASH (v1_v2) SUBPARTITIONS 32 -- Does this HASH subpartition work?
(PARTITION p20191101 VALUES LESS THAN ('2019-11-01'),
 PARTITION p20191102 VALUES LESS THAN ('2019-11-02'),
 PARTITION pMax VALUES LESS THAN MAXVALUE);

推荐阅读