Mysql分库分表
数据库拆分主要指分库分表,其目的主要是分散数据库压力,达到横向扩展,满足均衡访问等。
文章目录
一、Mysql分表分库
1.垂直拆分
将不同业务功能相关的表放到不同的数据库中,也就是类似于微服务架构中:订单数据库/支付数据库/会员数据库
2.水平拆分
对同一张表数据实现拆分放到多个不同的表中存放。
【推荐】单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。 摘自:阿里巴巴java开发手册
二、如何分表分库
1.常用数据库中间件
Mycat:基于服务器端 分表分库中间件
优点:能够保证数据库的安全性
缺点:效率比较低
shadingjdbc:基于客户端改写sql 分表分库中间件
优点:效率比较高
缺点:不能够保证数据库的安全性、客户端容易内存溢出
2.分表分库策略
分表分库需要考虑点:扩容性、每张表数据均匀性。
1.取余/取模
优点:可以保证每张表数据均匀性
缺点:后期无法做扩容
2.按照范围分片
优点:容易扩容、每张表数据都是均匀的存放
缺点:前期可能会有数据表空闲
3.按照日期进行分片
优点:容易扩容
缺点:每张表数据不均匀
4.按照枚举值分片
优点:容易扩容
缺点:每张表数据不均匀
5.二进制取模范围分片
6.一致性hash分片
7.按照目标字段前缀指定的进行分区
8.按照前缀ASCII码和值进行取模范围分片
三.Shadingjdbc整合
1.Maven依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
2.相关配置
a.整合分表
# 数据源 testdb
sharding:
jdbc:
datasource:
names: testdb
# 第一个数据库
testdb:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
# 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
config:
sharding:
# 分库策略
# default-database-strategy:
# inline:
# sharding-column: id
# algorithm-expression: testdb
# 分表策略 其中test_user为逻辑表 分表主要取决于id字段
tables:
test_user:
### testdb test_user_0 test_user_1
actual-data-nodes: testdb.test_user_$->{0..1}
table-strategy:
inline:
sharding-column: id
# 分片算法表达式 test_user_1%2 test_user_2%2 test_user_3%2
algorithm-expression: test_user_$->{id % 2}
# 打印执行的数据库
props:
sql:
show: true
# 打印执行的sql语句
spring:
main:
allow-bean-definition-overriding: true
b.整合分表
# 数据源 testdb
sharding:
jdbc:
datasource:
names: testdb
# 第一个数据库
testdb:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3306/testdb?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password: root
# 水平拆分的数据库(表) 配置分库 + 分表策略 行表达式分片策略
config:
sharding:
tables:
test_user:
actual-data-nodes: testdb.test_user_$->{0..1}
table-strategy:
standard:
precise-algorithm-class-name: com.test.config.TestRangeShardingAlgorithm
sharding-column: id
# 打印执行的数据库
props:
sql:
show: true
# 打印执行的sql语句
spring:
main:
allow-bean-definition-overriding: true
@Slf4j
public class TestRangeShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
private Long TABLE_SIZE = 5l;
private String TABLE_NAME = "meite_user";
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
Double temp = Double.valueOf(preciseShardingValue.getValue()) / TABLE_SIZE;
String tableName = TABLE_NAME + (int) Math.ceil(temp);
log.info("<tableName{}>", tableName);
return tableName;
}
}
四、分表分库语句查询原理
分表分库之后如何查询的呢?
查询语句没有带上分片字段–查询所有
询语句带上分片字段–根据该分片字段 计算具体表查询
1.查询语句条件后面带上分片字段
截取该查询sql语句中 where 条件后面的分片字段,如果带上了分片字段 ,则根据该分片字段计算出具体存放在哪张表。
只会发送一条sql语句。
2.查询语句条件后面没有带上分片字段
判断该 查询语句没有分片字段,直接查询所有。
将每张表都会查询一遍。
Shadingjdbc建议查询的过程中带上分片的字段
3.分页查询,查询条件且没有带上分片字段
Shadingjdbc 将每张表数据做一个查询,在交给Shadingjdbc 分页 返回给 客户端。
4.排序查询,查询条件且没有带上分片字段
Shadingjdbc 将每张表数据做一个查询,在交给Shadingjdbc 排序 返回给 客户端。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131298.html