當公司業務量上去以後,單表支撐不了的時候,分庫分表就是一個繞不開的話題,小弟最近新入職一家公司,發現這邊公司在用ShardingSphere來進行分庫分表,以前沒接觸過這方面,因此就寫了個demo學習一下,下面文章就記錄一下如何用ShardingSphere來進行分庫分表!(能力有限,本章不會講原理奧,只是記錄如何分庫分表,原理方面後面我學習了再寫,如今先會用先0.0,
)java
一、官網文檔地址
這是ShardingSphere官網文檔的地址,有須要的能夠點進去看一下。mysql
二、技術及環境
數據庫 | 項目用到的技術 |
---|---|
mysql5.6 | springboot、mybatis、shardingsphere |
三、建庫建表
一、新建兩個數據庫:
一個user0,一個user1。二、在user0數據庫新建兩個表:
一個us_admin0,一個us_admin1,新建語句以下:程序員
CREATE TABLE `us_admin0` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`user_id` int(11) NOT NULL COMMENT '用戶id',
`addr_id` int(11) NOT NULL COMMENT '地址id',
`user_name` varchar(64) NOT NULL COMMENT '用戶編號',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='後臺用戶表';
CREATE TABLE `us_admin1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`user_id` int(11) NOT NULL COMMENT '用戶id',
`addr_id` int(11) NOT NULL COMMENT '地址id',
`user_name` varchar(64) NOT NULL COMMENT '用戶編號',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='後臺用戶表';
三、在user1數據庫新建兩個表:
一個us_admin0,一個us_admin1,新建語句以下:web
CREATE TABLE `us_admin0` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`user_id` int(11) NOT NULL COMMENT '用戶id',
`addr_id` int(11) NOT NULL COMMENT '地址id',
`user_name` varchar(64) NOT NULL COMMENT '用戶編號',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='後臺用戶表';
CREATE TABLE `us_admin1` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主鍵ID',
`user_id` int(11) NOT NULL COMMENT '用戶id',
`addr_id` int(11) NOT NULL COMMENT '地址id',
`user_name` varchar(64) NOT NULL COMMENT '用戶編號',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='後臺用戶表';
四、搭建springboot項目
這部分就idea本身建立一下就行了,pom文件及配置文件內容以下:redis
pom文件:
spring
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.sharding</groupId>
<artifactId>sphere</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>sphere</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR3</spring-cloud.version>
<redisson.version>3.8.2</redisson.version>
<mysql-connector.version>8.0.12</mysql-connector.version>
</properties>
<dependencies>
<!-- 單元測試 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web-services</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- shardingsphere的jar包 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<!--阿里數據庫鏈接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.14</version>
</dependency>
<!-- Mysql驅動包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<!-- <scope>runtime</scope>-->
</dependency>
<!-- 健康檢查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.yml配置:
sql
# 服務端口
server:
port: 8888
# 服務名
spring:
application:
name: test-user
# 配置sharding jdbc分片規則
shardingsphere:
datasource:
# 鏈接名稱(下面要用這個名稱來區分庫)
names: ds0,ds1
ds0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.1.19:3306/user0?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123
initialSize: 5 #初始化大小
maxActive: 200 #最大值
maxWait: 2000 #最大等待時間,配置獲取鏈接等待超時,時間單位都是毫秒ms
timeBetweenEvictionRunsMillis: 60000 #配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接
ds1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://192.168.1.19:3306/user1?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123
initialSize: 5 #初始化大小
maxActive: 200 #最大值
maxWait: 2000 #最大等待時間,配置獲取鏈接等待超時,時間單位都是毫秒ms
timeBetweenEvictionRunsMillis: 60000 #配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接
# 配置分片規則
sharding:
# 按表來區分
tables:
us_admin:
# 配置數據節點
actualDataNodes: ds${0..1}.us_admin${0..1}
# 分庫策略
databaseStrategy:
inline:
# 分庫的規則 用user_id這個字段來分庫 總共有兩個庫 及ds0(user0)與ds1(user1)
shardingColumn: user_id
algorithmExpression: ds${user_id % 2}
# 分表策略
tableStrategy:
inline:
shardingColumn: addr_id
algorithmExpression: us_admin${addr_id % 2}
keyGenerator:
column: id
type: SNOWFLAKE
bindingTables:
us_admin
broadcastTables:
t_config
defaultDataSourceName: ds0
props:
sql.show: true
# 配置xml 的掃描路徑
mybatis:
mapper-locations: classpath:mapper/*.xml
check-config-location: true
type-aliases-package: com.sharding.sphere.model
configuration:
cacheEnabled: true
mapUnderscoreToCamelCase: true
五、接口測試
編寫增刪改接口進行測試,分庫根據user_id來切片,分表根據addr_id來切片,分別插入一些數據,結果以下:數據庫
@RestController
public class UserController {
@Resource
UserService userService;
@RequestMapping("add")
public Integer add(@RequestBody UsAdmin usAdmin){
Integer add = userService.add(usAdmin);
return add;
}
@RequestMapping("select")
public List<UsAdmin> select(){
List<UsAdmin> select = userService.select();
return select;
}
@RequestMapping("delect")
public Integer delect(Long id){
Integer delect = userService.delect(id);
return delect;
}
}
查詢sql語句:apache
<select id="selectAll" resultMap="BaseResultMap">
select
id, addr_id, user_id, user_name
from us_admin
</select>
新增sql語句:springboot
<insert id="insertSelective" parameterType="com.sharding.sphere.model.UsAdmin">
insert into us_admin
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
id,
</if>
<if test="userId != null">
user_id,
</if>
<if test="addrId != null">
addr_id,
</if>
<if test="userName != null">
user_name,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">
#{id,jdbcType=BIGINT},
</if>
<if test="userId != null">
#{userId,jdbcType=INTEGER},
</if>
<if test="addrId != null">
#{addrId,jdbcType=INTEGER},
</if>
<if test="userName != null">
#{userName,jdbcType=VARCHAR},
</if>
</trim>
</insert>
刪除sql語句:
delete from us_admin
where id = #{id,jdbcType=BIGINT}
數據新增分表分庫結果:
查詢結果:
能夠看到,新增數據的時候以user_id%2來計算分庫,雙數在user0庫,單數在user1庫,addr_id做爲分表id,雙數在us_admin0表,單數在us_admin1表,先肯定庫而後肯定表
,而查詢一條語句能夠查詢到全部,不過ShardingSphere好像有些sql語句是不支持的,好比關聯本身這種操做(us_admin left join us_admin這種)
,還有一些不支持的sql,具體的能夠百度看看。
講道理來看,ShardingSphere其實對代碼的侵入量並不算多,只是有一些配置,配置好以後該寫的sql跟原來同樣的,多是尚未踩到該踩的坑吧,等週末研究一下原理以後再寫一篇文章分析分析。
六、公衆號
若是你以爲個人文章對你有幫助話,歡迎關注個人微信公衆號:"一個快樂又痛苦的程序員"(無廣告,單純分享原創文章、已pj的實用工具、各類Java學習資源,期待與你共同進步)
本文分享自微信公衆號 - 一個快樂又痛苦的程序員(AsuraTechnology)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。