最近在做一个用Java实现一个简易的搜索引擎项目时,由于数据量很大,需要分表。这里的分表指的水平分表。数据大概有几千万行了吧。

image-20220829225513347

当数据量特别大的时候,查询速度特别慢,为了加快查询速度,只能采用分表的策略。除了水平切分还有垂直切分,用的不多。

当数据库分表后,为了方便操作数据库,我们可以采用Sharding-jdbc。你可以把它理解为加强版的JDBC

当我们需要使用Shard-jdbc,首先我们需要导入pom坐标

1
2
3
4
5
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>

我这里使用的4.0版本

然后配置如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
main:
allow-bean-definition-overriding: true #允许bean覆盖
shardingsphere:
datasource:
names: master #数据源名称
master:
type: com.alibaba.druid.pool.DruidDataSource #使用druid数据源,如果不用就去掉这一行,如果用记得导入pom坐标
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.37.135:3306/my_search_engine?serverTimezone=UTC
username: root
password: root
sharding:
tables:
data_seg_relation: #需要分表的表名 也可以理解为分表后的表名前缀
#分成100个表 从data_seg_relation_0 -->data_seg_relation_99
actual-data-nodes: master.data_seg_relation_$->{0..99}
key-generator: #主键生成策略
column: id
type: SNOWFLAKE #使用雪花算法生成id
table-strategy:
inline:
algorithm-expression: data_seg_relation_$->{seg_id % 100} #如何映射到表
sharding-column: seg_id

说明一下,这是数据库里面的表。

我们可以看到 data_seg_relation被分成了100个表,从data_seg_relation_0data_seg_relation_99

image-20220829230552472

表结构

image-20220829230826244
1
2
algorithm-expression: data_seg_relation_$->{seg_id % 100} #如何映射到表
sharding-column: seg_id

这个配置的意思是,当你查询的时候,比如 select * from data_seg_relation where seg_id=1165136

Shard-jdbc会根据seg_id这个取值,seg_id % 100 = 36。然后它实际就会去查data_seg_relation_36这个表。

当你配置好之后,你就可以像没有分表那样来去操作数据库。

但需要注意的是【踩的几个坑吧】:

  • 如果你的Javajdk8以上的版本,或许你会报这样的错:

    Cause: javax.xml.bind.JAXBException: Implementation of JAXB-API has not been found on module path or classpath.

    大概率就是你jdk版本的原因,要么你回退到jdk8版本,要么你就添加如下pom坐标。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/javax.activation/activation -->
    <dependency>
    <groupId>javax.activation</groupId>
    <artifactId>activation</artifactId>
    <version>1.1</version>
    </dependency>
    <!-- https://mvnrepository.com/artifact/org.glassfish.jaxb/jaxb-runtime -->
    <dependency>
    <groupId>org.glassfish.jaxb</groupId>
    <artifactId>jaxb-runtime</artifactId>
    <version>2.3.0-b170127.1453</version>
    </dependency>
  • 当你用使用mybatis或mybatis-plus时,就不需要再配置它们的数据源了。

  • 你当你写SQL时,最好别用子查询,因为你可能会报错的,【错误信息找不到ಥ_ಥ】

    解决方法就是不用子查询,一条SQL语句拆成两条不就好了!

__END__