MySQL 分区表举例
程序员文章站
2022-05-07 12:10:31
...
关于MySQL分区表的概念百度上一大堆,这里给出几个例子供参考,基本上一看就懂的。
Range类型
须要提供一个数字列作为判断依据
ALTER TABLE log_regist PARTITION BY RANGE (UNIX_TIMESTAMP(event_at))(
PARTITION P201702 VALUES LESS THAN (1485878400) ENGINE = InnoDB,
PARTITION P201703 VALUES LESS THAN (1488297600) ENGINE = InnoDB,
PARTITION P201704 VALUES LESS THAN (1490976000) ENGINE = InnoDB,
PARTITION P201705 VALUES LESS THAN (1493568000) ENGINE = InnoDB,
PARTITION P201706 VALUES LESS THAN (1496246400) ENGINE = InnoDB
)
注意红字必须是线性值,数字、时间戳都成(date需要使用 to_days(DATE)这种形式,5.5以后支持),核心思想就是比较指定列是否在某个区间(分区)内。问题就是分区随着时间推移会不断增加,所以一定要及时增加新的分区否则无法写入数据。另外,参照列必须列为复合主键(比如 PRIMARY KEY (`id`,`create_at`) )。
Hash类型
利用Hash函数获取某列的hash值,然后提供一个正数的分区数量。
ALTER TABLE log_order_finished PARTITION BY HASH(id) PARTITIONS 12;
核心思想就是根据一个HASH值判断指定的分区,与Range不同,这里直接给定了分区数量。话说MySQL分区数量上限是1024,超过了会有奇迹发生,具体参考MySQL5手册或百度。
List类型
List类型必须明确指定范围值,其不同于Range对连续的序列进行判断
假定有20个音像店,分布在4个有经销权的地区,如下表所示:
地区 | 商店ID 号 |
北区 | 3, 5, 6, 9, 17 |
东区 | 1, 2, 10, 11, 19, 20 |
西区 | 4, 12, 13, 14, 18 |
中心区 | 7, 8, 15, 16 |
要按照属于同一个地区商店的行保存在同一个分区中的方式来分割表,可以使用下面的“CREATE TABLE”语句:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY LIST(store_id)
PARTITION pNorth VALUES IN (3,5,6,9,17),
PARTITION pEast VALUES IN (1,2,10,11,19,20),
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
这段照搬了手册,我不用这种分区方式的理由是不可约定列的内容范围。
Key类型
它们唯一的区别在于使用的关键字是KEY而不是HASH,并且KEY分区只采用一个或多个列名的一个列表
通过线性KEY分割一个表也是可能的。下面是一个简单的例子:
CREATE TABLE tk (
col1 INT NOT NULL,
col2 CHAR(5),
col3 DATE
)
PARTITION BY LINEAR KEY (col1)
PARTITIONS 3;
这段很诡异,手册上说明了是基于MySQL内部的hash方法,类似于password()函数。
删除分区
ALTER TABLE tr DROP PARTITION p2;
增加分区
ALTER TABLE members ADD PARTITION (PARTITION p3 VALUES LESS THAN (1960));
for ($i = 1; $i <= 36; $i++) {
$ts = mktime(0, 0, 0, $i + 1, 1);
$p = 'P' . date('Ym', $ts);
$d = date('Y-m-01', $ts);
echo "PARTITION $p VALUES LESS THAN ($ts) ENGINE = InnoDB,", '<br/>';
}
另外,为了方便的生成SQL语句,可以参考以下PHP代码:
function makePartition(){ echo "ALTER TABLE log_mobi_regist PARTITION BY RANGE (UNIX_TIMESTAMP(event_at)) \r\n<br/>"; $partitions = []; for ($i = 1; $i <= 36; $i++) { $ts = mktime(0, 0, 0, $i + 1, 1); $p = 'P' . date('Ym', $ts); $d = date('Y-m-01', $ts); $partitions[] = "PARTITION $p VALUES LESS THAN ($ts) ENGINE = InnoDB\r\n".'<br/>'; } echo '(', join(',', $partitions), ')'; }此段是我常用于生成日志SQL的代码,仅供参考。
另外可以看看这边分区性能测评的文章会有帮助:http://blog.****.net/jhq0113/article/details/44593511
吐槽一句,这个编辑器越来越烂了
推荐阅读