一.什么是水平分库
将一张表水平切分到多个库中
1.1分片原则
1.需要分片的表是少数的
2.能不切分尽量不要切分
3.日志表可以采取归档方式
4.选择合适的切分规则和分片建,确保数据分片均匀,否则依然存在性能瓶颈
5.尽量避免跨分片join操作,保证关联操作表在同一分片
1.2分片后如何处理查询
1.根据简单分片规则,对分片键进行路由到正确的后端物理数据库
2.如果不是使用分片键的话,将会遍历后端数据库,极大消耗性能
二.水平切分步骤
2.1根据业务状态确定要进行水平切分的表
读写频繁,访问量非常大的表才需要切分,一般是订单表
如何选择分片键
1.尽可能的比较均匀分布数据到各个节点上,自增长主键并不是很好的选择,因为不会用于查询
2.业务字段是最频繁的或者最重要的查询条件
2.2分析业务模型选择分片键及分片算法
一般分片键选择的是频繁作为查询的字段,关键是能保证分片后的数据分布均匀,常用简单取模算法
对订单相关表进行水平切分
不仅仅是订单表,经常与订单表关联查询的表也需要一并分片,避免跨分片查询,大表不适合作为全局表
订单号,可以保证分片均匀,但是实际业务很少根据订单号来查询
下单人ID,业务查询更多,更适合,但是分片并不均匀,但不严重,值得考虑
采用简单取模分片算法,可以保证数据尽可能均匀
2.3适用mycat部署分片集群
1.使用schema.xml配置逻辑库及逻辑表
2.使用rule.xml配置分片表的分片规则
customer_id
mod-long
4
3.验证
# 现在逻辑库上进行查看,此时是没有数据的
# 需要提前建库建表,否则报错表不存在
app_imooc@172.16.10.142 00:26: [imooc_db]> select * from order_master;
Empty set (0.08 sec)
# 在逻辑库imooc_db上插入5条数据,正常是orderdb02 2条数据(节点索引顺序为1),其他各1条数据
insert into order_master(order_sn,customer_id,shipping_user,province,city,district,address,payment_method,order_money) values(70001,90001,'yzw1',1,1,1,'address1',1,20);
insert into order_master(order_sn,customer_id,shipping_user,province,city,district,address,payment_method,order_money) values(70002,90002,'yzw2',2,2,2,'address1',1,20);
insert into order_master(order_sn,customer_id,shipping_user,province,city,district,address,payment_method,order_money) values(70003,90003,'yzw3',3,3,3,'address1',1,20);
insert into order_master(order_sn,customer_id,shipping_user,province,city,district,address,payment_method,order_money) values(70004,90004,'yzw4',4,4,4,'address1',1,20);
insert into order_master(order_sn,customer_id,shipping_user,province,city,district,address,payment_method,order_money) values(70005,90005,'yzw5',5,5,5,'address1',1,20);
# truncate table报错
app_imooc@172.16.10.142 10:51: [imooc_db]> truncate table order_master;
ERROR 1105 (HY000): DROP command denied to user 'bm_mycat'@'172.16.10.142' for table 'order_master'
# 逻辑库查看插入结果
app_imooc@172.16.10.142 10:50: [imooc_db]> select order_id,order_sn,customer_id from order_master;
+----------+----------+-------------+
| order_id | order_sn | customer_id |
+----------+----------+-------------+
| 80005 | 70002 | 90002 |
| 80005 | 70003 | 90003 |
| 80005 | 70004 | 90004 |
| 80006 | 70001 | 90001 |
| 80007 | 70005 | 90005 |
+----------+----------+-------------+
5 rows in set (0.00 sec)
# 在物理库查看是否有这4条数据,验证成功
root@localhost 10:52: [orderdb01]> select order_id,order_sn,customer_id from order_master;
+----------+----------+-------------+
| order_id | order_sn | customer_id |
+----------+----------+-------------+
| 80005 | 70004 | 90004 |
+----------+----------+-------------+
1 row in set (0.00 sec)
root@localhost 10:52: [orderdb02]> select order_id,order_sn,customer_id from order_master;
+----------+----------+-------------+
| order_id | order_sn | customer_id |
+----------+----------+-------------+
| 80006 | 70001 | 90001 |
| 80007 | 70005 | 90005 |
+----------+----------+-------------+
2 rows in set (0.00 sec)
root@localhost 10:05: [orderdb03]> select order_id,order_sn,customer_id from order_master;
+----------+----------+-------------+
| order_id | order_sn | customer_id |
+----------+----------+-------------+
| 80005 | 70002 | 90002 |
+----------+----------+-------------+
1 row in set (0.00 sec)
root@localhost 10:52: [orderdb04]> select order_id,order_sn,customer_id from order_master;
+----------+----------+-------------+
| order_id | order_sn | customer_id |
+----------+----------+-------------+
| 80005 | 70003 | 90003 |
+----------+----------+-------------+
1 row in set (0.00 sec)
4.使用server.xml配置访问权限
#配置用户登录
2.4测试分片集群,采用应用端双写方式进行
2.5业务及数据迁移
三.全局自增ID
分片表中的自增ID在逻辑表中有重复
第三方给ID或者使用mycat自增ID
3.1全局自增ID方法
1.本地文件方式:适用服务器本地磁盘的方式
2.数据库方式:适用数据库存储的方式
3.本地时间戳方式:适用时间戳
4.分布式zookeeper生成ID
3.2本地文件全局ID
优点:本地加载,读取速度快,配置简单
缺点:集群部署无法使用,不同的mycat无法保证id唯一,使mycat变成了有状态的中间件
配置方法
1.server.xml增加属性
3.插入数据
# mycat restart
# delete from order_master;
insert into order_master(order_id,order_sn,customer_id,shipping_user,province,city,district,address,payment_method,order_money) values(next value for MYCATSEQ_GLOBAL,70001,90001,'yzw1',1,1,1,'address1',1,20);
insert into order_master(order_id,order_sn,customer_id,shipping