mysql分库分表
一、如何进行分库分表1、概念:将原本存储在单个数据库上的数据拆分到多个数据库中(分库),把原来存储在单张表的数据拆分到多张数据表中,实现数据切分,从而提生数据库操作性能。分库分表的实现方式分为两种:垂直切分,水平切分。2、水平拆分:将数据分散到多张表,涉及到分区键。分库:每个库结构一样,数据不一样,没有交集。库多了可以缓解io和cpu压力。分表:每个表结构一样,数据不一样,没有交集。表数量减少,可
文章共2,709字 · 阅读需要大约10分钟
一键AI生成摘要,助你高效阅读
问答
·
一、如何进行分库分表
1、概念:
将原本存储在单个数据库上的数据拆分到多个数据库中(分库),把原来存储在单张表的数据拆分到多张数据表中,实现数据切分,从而提生数据库操作性能。分库分表的实现方式分为两种:垂直切分,水平切分。
2、水平拆分:
将数据分散到多张表,涉及到分区键。
- 分库:每个库结构一样,数据不一样,没有交集。库多了可以缓解io和cpu压力。
- 分表:每个表结构一样,数据不一样,没有交集。表数量减少,可以提高sql执行效率,减轻cpu压力。
优缺点:
- 优点:
- 单库(表)的数据保持在一定的量(减少),有助于性能的提高。
- 拆分结构相同,程序改造较小
- 缺点:
- 数据扩容有难度,维护量大。
- 拆分规则很难抽象出来
- 分片事务的一致性的问题,部分业务无法关联。
3、垂直拆分:
将字段拆分为多张表,需要一定的重构。
- 分库:每个库结构,数据都不一样,所有库的并集为全量数据。
- 分表:每个表结构、数据不一样,至少有一列交集,用于关联数据,所有表的并集为全量数据。
优缺点:
- 优点:
- 拆分后业务清晰(专库专用按业务拆分)
- 数据维护简单、按业务不同放到不同机器上。
- 缺点:
- 单表数据量大,写和读的压力大
- 受某种业务来决定或者被限制。也就是说一个业务往往会影响到数据库的瓶颈(性能问题)。
二、分库分表开源框架
1、jdbc直连层
shardingshpere、tddl(淘宝)
-
优点:快速性能高、支持跨数据库
-
缺点:不支持跨语言。
2、proxy代理层
mycat、mysql-proxy
-
优点:需要网络、支持跨平台、跨语言
-
缺点:性能比jdbc低、不支持跨数据库
三、分库分表存在的问题
1、分布式事务
ACID(原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性)
当我们在进行多个数据库CURD(增删改查)操作的时候,如果出现错误,那么事务在回滚时只支持一个数据库的回滚,而其他数据库则是会操作成功,那么就会出现脏数据的出现。数据一致性不会得到保证
2、分布式id
在分表中存在,自增id会存在id重复的情况。
3、分布式查询 join
join查询存在数据组合问题。
4、多数据库源管理
四、springboot整合shareingshere
1、导入依赖
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.1.1</version>
</dependency>
2、配置
spring:
shardingsphere:
datasource:
names: master,slave
commoun:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/shop?serverTimezone=UTC&characterEncoding=utf8&useUnicode=tr&ueuseSSL=false
username: root
password: root
hikari:
# 连接池最小空闲连接数
minimum-idle: 5
# 连接池允许的最大连接数
maximum-pool-size: 10
# 等待连接池分配连接的最大时长(毫秒)
connection-timeout: 30000
master:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/shop?serverTimezone=UTC&characterEncoding=utf8&useUnicode=tr&ueuseSSL=false
username: root
password: root
slave:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/shop?serverTimezone=UTC&characterEncoding=utf8&useUnicode=tr&ueuseSSL=false
username: root
password: root
props:
sql:
show: true
mybatis:
configuration:
# 数据库下划线转驼峰配置
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:/mybatis/mapper/*.xml
3、分片配置
sharding:
tables:
employee:
actualDataNodes: master.employee_$->{0..2}
tableStrategy:
inline:
shardingColumn: id
algorithmExpression: employee_$->{id % 2}
keyGenerator:
type: SNOWFLAKE
column: id
#进行分库配置 按照id进行分库
binding-tables: employee
# databaseStrategy:
# inline:
# shardingColumn: id
# algorithmExpression: employee_$->{id % 2}
4、读写分离与分片整合配置
sharding:
binding-tables: employee
tables:
employee:
actualDataNodes: ms.employee_$->{0..2}
tableStrategy:
inline:
shardingColumn: d_id
algorithmExpression: employee_$->{d_id % 2}
keyGenerator:
type: SNOWFLAKE
column: d_id
default-table-strategy:
none:
default-key-generator:
type: SNOWFLAKE
column: d_id
default-data-source-name: master
master-slave-rules:
ms:
slave-data-source-names: slave
load-balance-algorithm-type: round_robin
master-data-source-name: master
五、测试
1、测试查询
@GetMapping("select")
public List<Employee> insertDept(Employee employee) {
return employeeMapper.getEmp(employee);
}
- 数据库中进行水平分表。
- 查询所有:
<select id="getEmp" resultType="com.beans.Employee">
select *
from employee
</select>
- 查询在slave中进行查询
2、测试插入
@GetMapping("insert")
public Long insert(Employee employee) {
employee.setDId(12L);
employee.setGender(1);
employee.setDate(new Date());
employee.setEmail("123121312@12312");
employeeMapper.insertEmp(employee);
return employee.getId();
}
- 插入一条数据
<insert id="insertEmp" useGeneratedKeys="true" keyProperty="id">
INSERT INTO employee(lastName, email, gender, d_id, date)
VALUES (#{lastName}, #{email}, #{gender}, #{dId}, #{date})
</insert>
- 插入会在master进行
更多推荐
已为社区贡献1条内容
所有评论(0)