目前市面上很多互联网公司还是用的mysql数据库,然而mysql对于高并发(QPS),高访问量的请求还是比较乏力,就有了各种sql优化
以及缓存的应用,提高sql性能和减轻并发量,但是这些还是满足不了海量用户请求以及数据sql数据处理。应用而出的ElasticSearch等
搜索引擎技术,进行数据处理和挖掘,但是这种第三方框架,对数据库本身的性能还是没有提升,于是便有了数据库的分库,读写分离
分表,拆分表或者拆分表结构。
1.分库-读写分离:将增删改,和查拆分到不同mysql服务器上,这样可极大的提高吞吐量,两个数据库必须做数据同步,所以读写分离是
建立在数据库集群或者主从基础上的,mysql主从配置
2.分表:分表有垂直分表和水平分表,垂直分表:将字段进行分割,比如,用户可以有很作角色,那么便可以将用户和角色所需字段拆分开,
在用中间表关联,但是对于数据量大的,单表记录还是会很大。水平分表:水平分表就是将用户表的数据,分到另外一个有着相同数据结构
的表中,这样假如有一千万数据,那么两个表相互平分五百万数据,对于海量数据有着非常明显的改善与优化。
然后对这些拆分后的库和表进行增删改查操作,就需要用到sharding和myCat第三方框架集成进行管理,本次讲的就是sharding进行分库分表
操作,只需要配置即可,不影响正常业务代码。直接上干货
导入依赖:
<!--依赖sharding-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-common</artifactId>
<version>4.0.0-RC1</version>
</dependency>
yml配置:
spring:
main:
# 需要加入这个,等于true
allow-bean-definition-overriding: true
application:
name: cloud-provider-payment
shardingsphere:
# 参数配置,显示sql
props:
sql:
show: true
# 配置数据源
datasource:
# 给每个数据源取别名,下面的ds1,ds2,ds3任意取名字
names: ds1,ds2
# 给master-ds1每个数据源配置数据库连接信息
ds1:
# 配置druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.111:3306/dbc?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: Zhroot@8
maxPoolSize: 100
minPoolSize: 5
# 配置ds2-slave
ds2:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.0.110:3306/dbc?useUnicode=true&characterEncoding=utf8&tinyInt1isBit=false&useSSL=false&serverTimezone=GMT
username: root
password: Zhroot@8
maxPoolSize: 100
minPoolSize: 5
# 配置数据源的读写分离,但是数据库一定要做主从复制
masterslave:
# 配置主从名称,可以任意取名字
name: ms
# 配置主库master,负责数据的写入
master-data-source-name: ds1
# 配置从库slave节点
slave-data-source-names: ds2
# 配置默认数据源ds1
sharding:
# 默认数据源,主要用于写,注意一定要配置读写分离 ,注意:如果不配置,那么就会把三个节点都当做从slave节点,新增,修改和删除会出错。
default-data-source-name: ds1
tables:
# 我的表名称 test_table,进行分表
test_table:
# 分库节点配置
actual-data-nodes: ds$->{1..2}.test_table_$->{1..2}
# key-generator-column-name: id #主键
# key-generator:
# column: id #主键
# type: SNOWFLAKE # 指定id进行插入时候,雪花算法
table-strategy:
inline:
sharding-column: id
#分表节点配置
algorithm-expression: test_table_$->{id % 2 + 1} # 写法本来是$->{id % 2},但是这种对应于table_0 table_1 我的是1和2 所以需要+1
基础类:
@Data
@TableName("test_table")
public class TestTableEntity {
private Long id;
private String name;
private String bark;
}
dao层:
@Mapper
public interface TestTableDao{
int create(TestTableEntity entity);
TestTableEntity getTableById(@Param("id") Long id);
}
xml层:
<insert id="create" parameterType="com.pjrspringcloud.entity.TestTableEntity"
useGeneratedKeys="true" keyProperty="id">
insert into test_table(name, bark) value (#{name},#{bark})
</insert>
<select id="getTableById" parameterType="java.lang.Long" resultType="com.pjrspringcloud.entity.TestTableEntity">
select * from test_table where id = #{id}
</select>
service:
public interface TestTableService{
int create(TestTableEntity entity);
TestTableEntity getTableById( Long id);
}
实现类:
@Service
@Log4j2
public class TestTableServiceImpl implements TestTableService {
@Autowired
private TestTableDao tableDao;
@Override
public int create(TestTableEntity entity) {
return tableDao.create(entity);
}
@Override
public TestTableEntity getTableById(Long id) {
return tableDao.getTableById(id);
}
}
controller层:
@RestController
@RequestMapping("testTable")
@Log4j2
public class TestTableController {
@Autowired
private TestTableService tableService;
@PostMapping("create")
public Result create(@RequestParam("name") String name,@RequestParam("bark") String bark) {
TestTableEntity entity = new TestTableEntity();
entity.setName(name);
entity.setBark(bark);
tableService.create(entity);
log.info("插入成功=======name={},bark={}",name,bark);
return new Result().ok("插入成功");
}
@GetMapping("getById")
public Result getById(@RequestParam("id") Long id) {
TestTableEntity entity = tableService.getTableById(id);
log.info("查询成功============={}",entity);
return new Result().ok(entity);
}
}
启动后进行接口业务测试,成功!
注意:水平分表必须选择一种分表策略,也可以自定义分表策略,我这里展示的是id奇偶数分表。