数据库优化
优化策略
- 表结构的优化,包括字段,类型,长度等
- 进行索引等数据库级别的优化
- 业务需求场景层面的优化调整
在以上几种手段都用了之后再进行分库分表的操作.一般不推荐上来就分库分表.除非能够预测到数据量的级别.
什么时候需要分库分库
Mysql数据库单表数据量在1千万以下时可以保证性能超过则需要更多的维护优化成本.
在数据量涨幅预期过快时,需要提前进行分库分表.
数据库分表的几种方案
mycat之类的中间件
mycat属于中间件的实现方式,应用直接连接mycat,然后由mycat去选择具体的库和表.
sharding-jdbc之类的代理层
sharding-jdbc具体使用方式
先在pom.xml
中引入依赖
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.1</version>
</dependency>
这里用的是sharding-jdbc-spring-boot-starter
需要注意的是,此时druid
不能用spring-boot-starter
版本的,需要用正常的包:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.22</version>
</dependency>
不然启动会报错找不到url
在配置文件中添加数据分片相关的配置
spring:
shardingsphere:
datasource:
names: ds0
ds0:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.01:3306/demo
username: root
password: '123456'
sharding:
tables:
userorder:
actual-data-nodes: ds0.t_order$->{0..1}
table-strategy:
inline:
sharding-column: orderid
algorithm-expression: t_order$->{orderid % 2}
defaultDataSourceName: ds0
props:
sql.show: true
这里type
填数据库连接池的类名.
具体其他配置项,参考官方文档
自定义分片策略
首先新建一个类,实现对应的分片方法:
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Range;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
public class ShardingTest implements PreciseShardingAlgorithm<String>, RangeShardingAlgorithm<String> {
/**
* in/= 判断标准
*
* @param collection
* @param preciseShardingValue
* @return
*/
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
Date time = DateUtil.parse(preciseShardingValue.getValue(), "yyyy-MM-dd HH:mm:ss");
String logicTableName = preciseShardingValue.getLogicTableName();
int year = DateUtil.year(time);
// 定义表名
String tableName = logicTableName + year;
for (String name : collection) {
if (tableName.equals(name)) {
return tableName;
}
}
throw new IllegalArgumentException();
}
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
System.out.println(rangeShardingValue.getValueRange());
Range<String> valueRange = rangeShardingValue.getValueRange();
Date right = null;
Date left = null;
// 如果有固定范围则取
if (valueRange.hasLowerBound()) {
String lowerEndpoint = valueRange.upperEndpoint();
String yearMonth = lowerEndpoint.substring(0, 7);
left = DateUtil.parse(yearMonth, "yyyy-MM");
}
if (valueRange.hasUpperBound()) {
String upperEndpoint = valueRange.upperEndpoint();
String yearMonth = upperEndpoint.substring(0, 7);
right = DateUtil.parse(yearMonth, "yyyy-MM");
}
Range<Date> range;
if (left == null && right != null) {
range = Range.upTo(right, valueRange.upperBoundType());
} else if (right == null && left != null) {
range = Range.downTo(left, valueRange.lowerBoundType());
} else {
range = Range.range(right, valueRange.lowerBoundType(), left, valueRange.upperBoundType());
}
ArrayList<String> list = new ArrayList<>();
for (String tableOriginName : collection) {
String[] userorders = tableOriginName.split("userorder");
String tableTime = userorders[1];
DateTime time = DateUtil.parse(tableTime, "yyyy");
if (range.contains(time)) {
list.add(tableOriginName);
}
}
return list;
}
}
然后在配置文件中指定类名:
spring:
shardingsphere:
datasource:
...
sharding:
tables:
userorder:
actual-data-nodes: ds0.t_order$->{2017..2020}
table-strategy:
standard:
shardingColumn: orderTime #分片列名称
preciseAlgorithmClassName: com.demo.common.ShardingTest #精确分片算法类名称,用于=和IN。。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
rangeAlgorithmClassName: com.demo.common.ShardingTest #范围分片算法类名称,用于BETWEEN,可选。。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器
...
分库分表策略
切分策略大体可以分为垂直切分和水平切分
按分库来说
垂直切分的例子:用户库,商品库,订单库…
水平分库的例子:按用户id的奇偶,按商品的类型,按订单的时间(月份)
按分表来说
用户表,垂直切分:用户基本信息,用户附加信息,用户认证信息
用户表水平切分:按用户id的奇偶,按用户地区等
转载:https://blog.csdn.net/u014705309/article/details/105733517
查看评论