数据切分,简单的说,就是通过某种条件,将我们之前存储在一台数据库上的数据,分散到多台数据库中,从而达到降低单台数据库负载的效果。数据切分,根据其切分的规则,大致分为两种类型:
垂直切分就是按照不同的表或者Schema切分到不同的数据库中,比如:在我们的课程中,订单表(order)和商品表(product)在同一个数据库中,而我们现在要对其切分,使得订单表(order)和商品表(product)分别落到不同的物理机中的不同的数据库中,使其完全隔离,从而达到降低数据库负载的效果。
一句话概括:将不同的业务数据放到不同的库中
垂直切分的特点就是规则简单,易于实施,可以根据业务模块进行划分,各个业务之间耦合性低,相互影响也较小。
一个架构设计较好的应用系统,其总体功能肯定是有多个不同的功能模块组成的。每一个功能模块对应着数据库里的一系列表。
意味着垂直拆分往往伴随着,系统程序分布式化、微服务化,当然单机的项目一般情况下也是用不到分库分表的。
在架构设计中,各个功能模块之间的交互越统一、越少越好。这样,系统模块之间的耦合度会很低,各个系统模块的可扩展性、可维护性也会大大提高。这样的系统,实现数据的垂直切分就会很容易。
但是,在实际的系统架构设计中,有一些表很难做到完全的独立,往往存在跨库join的现象。比如我们接到了一个需求,要求查询某一个类目产生了多少订单,如果在单体数据库中,我们直接连表查询就可以了。但是现在垂直切分成了两个数据库,跨库连表查询是十分影响性能的,也不推荐这样用,只能通过接口去调取服务,这样系统的复杂度又升高了。
优点:
缺点:
水平切分相比垂直切分,更为复杂。它需要将一个表中的数据,根据某种规则拆分到不同的数据库中,例如:订单尾号为奇数的订单放在了订单数据库1中,而订单尾号为偶数的订单放在了订单数据库2中。这样,原本存在一个数据库中的订单数据,被水平的切分成了两个数据库。在查询订单数据时,我们还要根据订单的尾号,判断这个订单在数据库1中,还是在数据库2中,然后将这条SQL语句发送到正确的数据库中,查出订单。
优点:
缺点:
下载地址:
https://dev.mysql.com/downloads/repo/yum/
注意选择对应的linux版本,这里采用linux7的,mysql 版本是8.0
yum localinstall mysql80-community-release-el7-3.noarch.rpm
yum install mysql-community-server
service mysqld start
查询结果最后一个冒号之后的就是密码
grep 'temporary password' /var/log/mysqld.log
mysql -uroot -p
然后输入密码
ALTER USER 'root'@'localhost' IDENTIFIED BY '这里想要的密码';
修改的密码需要复杂一点,一个大写字母、一个小写字母、一个数字和一个特殊字符,并且密码的总长度至少为8个字符,否则不符合密码策略无法修改成功
创建用户
由于我们使用的是mysql8,密码的默认加密方式改变Navicat无法连接,需要指定为老的加密方式:identified with mysql_native_password
当我们指定了老的加密方式后,控制台的客户端连接时需要指定连接的加密方式:mysql -uroot -p --default-auth=mysql_native_password
create user '用户名'@'%' identified with mysql_natice_password by '密码';
授权所有权限
grant all on *.* to '用户名'@'%';
然刷新一下配置
flush privileges;
如果还是无法连接,尝试关闭linux的防火墙
dl.mycat.io/1.6.7.3
tar -zxvf Mycat-server-1.6.7.3-release-20190828135747-linux.tar.gz
进入mycat根目录下的
vim config/server.xml
将root的schemas属性改成user
123456
user
下面还有个user的配置可以直接删掉,或者把schemas属性也改成user
vim config/schema.xml
配置分键表
mybatis的xml文件里的表需要使用逻辑表名
org.apache.shardingsphere
sharding-jdbc-spring-boot-starter
4.0.0-RC2
spring.shardingsphere.datasource.names=ds0,ds1
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbcUrl=jdbc:mysql://192.168.85.200:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ds0.username=
spring.shardingsphere.datasource.ds0.password=
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbcUrl=jdbc:mysql://192.168.85.201:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ds1.username=
spring.shardingsphere.datasource.ds1.password=
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order_$->{1..2}
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds$->{user_id%2}
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id% 2+1}
mybatis.mapper-locations=/mybatis/*.xml
logging.pattern.dateformat=HH:mm:ss
所有数据库都创建一个地址表
字段 | 中文解释 |
---|---|
id | id |
name | 地区名 |
spring修改xml文件
springboot,修改application.properties配置
# 添加广播表配置
spring.shardingsphere.sharding.broadcast-tables=area
这样在插入和修改的时候,就会同时更新所有库中的这张表,也可以进行join查询了
所有数据库都创建2个t_order_item表,分别叫做t_order_item_1和t_order_item_2
字段 | 中文解释 |
---|---|
id | id |
order_id | 订单表id |
pruduct_name | 商品名 |
user_id | 用户id |
spring修改xml文件
这里可能会有个bug,会提示广播表为空,主要原因是因为在初始化帮点表的时候,会检测是否同时是广播表,但是广播表尚未初始化,就会抛出空指针
如果以后问题解决,这里我再补上
spring.shardingsphere.datasource.names=ds0,ms1,slave0
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbcUrl=jdbc:mysql://192.168.85.200:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ds0.username=
spring.shardingsphere.datasource.ds0.password=
spring.shardingsphere.datasource.slave0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.slave0.jdbcUrl=jdbc:mysql://192.168.85.203:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.slave0.username=
spring.shardingsphere.datasource.slave0.password=
spring.shardingsphere.datasource.ms1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ms1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ms1.jdbcUrl=jdbc:mysql://192.168.85.201:3306/sharding_order?serverTimezone=Asia/Shanghai&useSSL=false
spring.shardingsphere.datasource.ms1.username=
spring.shardingsphere.datasource.ms1.password=
spring.shardingsphere.sharding.master-slave-rules.ms0.master-data-source-name=ds0
spring.shardingsphere.sharding.master-slave-rules.ms0.slave-data-source-name=slave0
spring.shardingsphere.sharding.master-slave-rules.ms0.load-balance.algorithm-type=RANDOM
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ms$->{0..1}.t_order_$->{1..2}
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ms$->{user_id%2}
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{order_id% 2+1}
mybatis.mapper-locations=/mybatis/*.xml
logging.pattern.dateformat=HH:mm:ss