MySQL分区表在实际生产环境使用不多,更多是通过分库分表的方法来缓解数据库压力,这里作为梳理进行简单总结。
一、查看MySQL版本是否支持分区表
mysql> SHOW PLUGINS;
+----------------------------+----------+--------------------+---------+---------+ | Name | Status | Type | Library | License |
+----------------------------+----------+--------------------+---------+---------+ | partition | ACTIVE | STORAGE ENGINE | NULL | GPL |
+----------------------------+----------+--------------------+---------+---------+
MySQL逻辑上为一个表,物理上存储在多个文件中。修改SQL建表语句成功建立分区表后,可以在data目录看到多个idb文件(物理存储)。
二、分区类型
A、HASH分区
根据MOD(分区键)的值,把数据行存储到表的不同分区中,键值必须为INT类型的值,或者转换为INT类型进行HASH函数运算。
CREATE TABLE `order` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`partner_id` int(11) DEFAULT '0' COMMENT '合作方编号(partner表字典)',
`outer_code` varchar(255) DEFAULT '' COMMENT '外部订单编号',
`order_id` bigint(20) DEFAULT NULL COMMENT '订单号',
`cust_id` bigint(20) DEFAULT NULL COMMENT '用户ID',
`payment_method_type` int(11) DEFAULT NULL COMMENT '支付类型',
`receiver_name` varchar(255) DEFAULT NULL COMMENT '收货人姓名',
`receiver_address` varchar(255) DEFAULT NULL COMMENT '收货人地址',
`receiver_country_id` int(11) DEFAULT NULL COMMENT '一级城市ID(国家)',
`receiver_province_id` int(11) DEFAULT NULL COMMENT '二级城市ID(省)',
`receiver_city_id` int(11) DEFAULT NULL COMMENT '三级城市ID(市)',
`receiver_town_id` int(11) DEFAULT NULL COMMENT '四级城市ID(区/县)',
`receiver_zip` varchar(255) DEFAULT NULL COMMENT '邮编',
`receiver_tel` varchar(255) DEFAULT NULL COMMENT '收货人电话',
`receiver_mobile_tel` varchar(255) DEFAULT NULL COMMENT '收货人手机',
`cust_message` varchar(500) DEFAULT NULL,
`shipping_fee` decimal(10,2) DEFAULT NULL COMMENT '运费',
`total_original_price` decimal(10,2) DEFAULT NULL COMMENT '原价',
`total_bargin_price` decimal(10,2) DEFAULT NULL COMMENT '成交价',
`total` decimal(10,2) DEFAULT NULL COMMENT '订单总金额(包括运费)',
`is_invoice_need` int(11) DEFAULT NULL COMMENT '是否要发票',
`invoice_category` int(4) DEFAULT NULL COMMENT '1:普通纸质发票;2:专用增值发票;3:普通电子增值发票',
`invoice_tel` varchar(20) DEFAULT NULL COMMENT '开票人手机号',
`invoice_title` varchar(255) DEFAULT NULL COMMENT '发票抬头',
`invoice_content` varchar(255) DEFAULT NULL COMMENT '发票内容',
`taxpayer_id` varchar(25) DEFAULT NULL COMMENT '纳税人识别号',
`warehouse_id` int(11) DEFAULT NULL COMMENT '仓库编号',
`is_presale` int(11) DEFAULT NULL COMMENT '是否预售',
`order_creation_date` datetime DEFAULT NULL COMMENT '订单创建时间',
`paid_amount` decimal(10,2) DEFAULT NULL COMMENT '实际支付',
`collection_reduce_total` decimal(10,2) DEFAULT NULL COMMENT '订单级促销优惠金额',
`coupon_amount` decimal(10,2) DEFAULT NULL COMMENT '礼券金额(旧:店铺+平台求和;新:店铺)',
`outer_coupon_amount` decimal(10,2) DEFAULT NULL COMMENT '外部礼券金额',
`status` int(11) NOT NULL DEFAULT '0' COMMENT '订单处理状态(0:未处理;1:已处理)',
`creation_date` datetime DEFAULT NULL COMMENT '创建时间',
`last_modified_date` datetime DEFAULT NULL COMMENT '最后修改时间',
`pcc_af` decimal(10,2) DEFAULT NULL COMMENT '点券卡实付款金额,单位元,小数点后保留两位有效数字',
`alipay_point` decimal(10,2) DEFAULT NULL COMMENT '付款时使用的支付宝积分的额度, 单位元,小数点后保留两位有效数字',
`point_fee` decimal(10,2) DEFAULT NULL COMMENT '买家使用积分,下单时生成,且一直不变,单位元,小数点后保留两位有效数字',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_uniq_1` (`outer_code`) USING BTREE,
KEY `idx_date_1` (`creation_date`),
KEY `idx_date_2` (`last_modified_date`),
KEY `idx_comb` (`partner_id`,`outer_code`,`order_id`)
)
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
PARTITION BY HASH(order_id) PARTITIONS 4;
B、RANGE分区(范围)
根据分区表键值的范围把数据行存储到表的不同分区中,默认情况下使用`VALUES LESS THAN`属性,也即[0,100)。
适用分区键为日期或者时间类型,数据分布均衡,容易归档。
CREATE TABLE `product_core` (
`product_id` bigint(20) NOT NULL COMMENT '商品ID',
`cat_1` varchar(32) DEFAULT NULL COMMENT '一级分类路径',
`cat_2` varchar(32) DEFAULT NULL COMMENT '二级分类路径',
`cat_3` varchar(32) DEFAULT NULL COMMENT '三级分类路径',
`cat_4` varchar(32) DEFAULT NULL COMMENT '四级分类路径',
`cat_5` varchar(32) DEFAULT NULL COMMENT '五级分类路径',
`cat_6` varchar(32) DEFAULT NULL COMMENT '六级分类路径',
`shop_id` int(11) NOT NULL DEFAULT '0' COMMENT '店铺编号',
`is_presell` int(11) DEFAULT NULL COMMENT '是否预售(0:否;1:是)',
`creation_date` datetime DEFAULT NULL COMMENT '记录生成时间',
`last_modified_date` datetime DEFAULT NULL COMMENT '最后修改时间',
PRIMARY KEY (`product_id`,`shop_id`),
KEY `idx_date_1` (`creation_date`),
KEY `idx_date_2` (`last_modified_date`),
KEY `idx_cat_1` (`cat_1`,`product_id`),
KEY `idx_cat_2` (`cat_2`,`product_id`),
KEY `idx_cat_3` (`cat_3`,`product_id`),
KEY `idx_cat_4` (`cat_4`,`product_id`),
KEY `idx_cat_5` (`cat_5`,`product_id`),
KEY `idx_cat_6` (`cat_6`,`product_id`)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8
PARTITION BY RANGE(product_id) (
PARTITION p0 VALUES LESS THAN (1000),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN (3000),
PARTITION p3 VALUES LESS THAN MAXVALUE
);
C、LIST分区
按分区键取值的列表进行分区,每一行数据须找到对的分区列表,否则数据插入失败。
CREATE TABLE `partner` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`partner_id` int(11) NOT NULL COMMENT '合作方编号',
`partner_name` varchar(255) DEFAULT NULL COMMENT '合作方名称',
`outer_shop_name` varchar(255) DEFAULT NULL COMMENT '对外合作开放的店铺名称',
`attention_shop_type` int(11) DEFAULT NULL COMMENT '关注类型(0:自营;1:招商;3招商+自营)',
`is_presell` int(11) DEFAULT NULL COMMENT '是否支持预售(0:不支持;1:支持)',
`is_valid` int(11) DEFAULT NULL COMMENT '合作是否有效',
`product_add_mode` int(11) DEFAULT '0' COMMENT '(0:自动推送新品;1:手动添加新品)',
`creation_date` datetime DEFAULT NULL COMMENT '创建时间',
`last_modified_date` datetime DEFAULT NULL COMMENT '最后修改时间',
PRIMARY KEY (`id`, `partner_id`)
)
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
PARTITION BY LIST(partner_id) (
PARTITION p0 VALUES IN (1,3,5,7,9),
PARTITION p1 VALUES IN (2,4,6,8,10)
);
除此之外还有其他分区方式,但是分区表在实际生产环境很少使用,这里就不列举。
D、查看分区表基本信息
mysql> SELECT TABLE_NAME,PARTITION_NAME,PARTITION_METHOD,PARTITION_EXPRESSION,PARTITION_DESCRIPTION FROM information_schema.`PARTITIONS` WHERE table_name IN ('order', 'partner', 'product_core');
+--------------+----------------+------------------+----------------------+-----------------------+ | TABLE_NAME | PARTITION_NAME | PARTITION_METHOD | PARTITION_EXPRESSION | PARTITION_DESCRIPTION |
+--------------+----------------+------------------+----------------------+-----------------------+ | order | p0 | HASH | order_id | NULL |
| order | p1 | HASH | order_id | NULL |
| order | p2 | HASH | order_id | NULL |
| order | p3 | HASH | order_id | NULL |
| partner | p0 | LIST | partner_id | 1,3,5,7,9 |
| partner | p1 | LIST | partner_id | 2,4,6,8,10 |
| product_core | p0 | RANGE | product_id | 1000 |
| product_core | p1 | RANGE | product_id | 2000 |
| product_core | p2 | RANGE | product_id | 3000 |
| product_core | p3 | RANGE | product_id | MAXVALUE |
+--------------+----------------+------------------+----------------------+-----------------------+