文章目錄html
學習以前先了解下分庫分表概念:https://spiritmark.blog.csdn.net/article/details/109524713java
在數據庫設計時候考慮垂直分庫和垂直分表。隨着數據庫數據量增長,不要立刻考慮作水平切分,首先考慮緩存處理,讀寫分離,使 用索引等等方式,若是這些方式不能根本解決問題了,再考慮作水平分庫和水平分表。node
分庫分表致使的問題:mysql
Apache ShardingSphere
是一套開源的分佈式數據庫中間件解決方案組成的生態圈,它由 JDBC
、 Proxy
和 Sidecar
(規劃中)這 3 款相互獨立,卻又可以混合部署配合使用的產品組成。 它們均提供標準化的數據分片、分佈式事務和數據庫治理功能,可適用於如 Java
同構、異構語言、雲原生等各類多樣化的應用場景。spring
Apache ShardingSphere
定位爲關係型數據庫中間件,旨在充分合理地在分佈式的場 景下利用關係型數據庫的計算和存儲能力,而並不是實現一個全新的關係型數據庫。 它經過關注不變,進而抓住事物本質。關係型數據庫當今依然佔有巨大市場,是各個公司核心業務的基石,將來也難於撼動,咱們目前階段更加關注在原有基礎上的增量,而非顛覆。sql
Sharding-JDBC
是輕量級的 java
框架,是加強版的 JDBC
驅動,簡化對分庫分表以後數據相關操做。
新建項目並添加依賴:數據庫
<parent> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-parentartifactId> <version>2.2.1.RELEASEversion> parent> <dependencies> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starterartifactId> dependency> <dependency> <groupId>org.springframework.bootgroupId> <artifactId>spring-boot-starter-testartifactId> dependency> <dependency> <groupId>com.alibabagroupId> <artifactId>druid-spring-boot-starterartifactId> <version>1.1.20version> dependency> <dependency> <groupId>mysqlgroupId> <artifactId>mysql-connector-javaartifactId> dependency> <dependency> <groupId>org.apache.shardingspheregroupId> <artifactId>sharding-jdbc-spring-boot-starterartifactId> <version>4.0.0-RC1version> dependency> <dependency> <groupId>com.baomidougroupId> <artifactId>mybatis-plus-boot-starterartifactId> <version>3.0.5version> dependency> <dependency> <groupId>org.projectlombokgroupId> <artifactId>lombokartifactId> dependency> dependencies>
① 按照水平分表的方式,建立數據庫和數據庫表express
水平分表規則:若是添加 cid
是偶數把數據添加 course_1
,若是是奇數添加到 course_2
apache
CREATE TABLE `course_1` ( `cid` bigint(16) NOT NULL, `cname` varchar(255) , `userId` bigint(16), `cstatus` varchar(16) , PRIMARY KEY (`cid`) )
② 編寫實體和 Mapper
類緩存
@Data public class Course { private Long cid; private String cname; private Long userId; private String cstatus; }
@Repository public interface CourseMapper extends BaseMapper<Course> { }
③ 詳細配置文件
spring: main: allow-bean-definition-overriding: true shardingsphere: datasource: names: m1 m1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3306/course_db?serverTimezone=GMT%2B8 username: root password: 1234 sharding: tables: course: actual-data-nodes: m1.course_$->{1..2} key-generator: column: cid type: SNOWFLAKE table-strategy: inline: shardingcolumn: cid algorithm-expression: course_$->{cid%2+1} props: sql: show: true mybatis-plus: configuration: map-underscore-to-camel-case: false
④ 測試
@RunWith(SpringRunner.class) @SpringBootTest public class ShardingSphereTestApplication { @Autowired CourseMapper courseMapper; @Test public void addCourse() { for (int i = 1; i 10; i++) { Course course = new Course(); course.setCname("java" + i); course.setUserId(100L); course.setCstatus("Normal" + i); courseMapper.insert(course); } } @Test public void queryCourse() { QueryWrapper<Course> wrapper = new QueryWrapper<>(); wrapper.eq("cid",493001315358605313L); Course course = courseMapper.selectOne(wrapper); System.out.println(course); } }
① 需求分析
② 建立數據庫和表
③ 詳細配置文件
spring: main: allow-bean-definition-overriding: true shardingsphere: datasource: names: m1,m2 m1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3306/course_db_2?serverTimezone=GMT%2B8 username: root password: 1234 m2: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3306/course_db_3?serverTimezone=GMT%2B8 username: root password: 1234 sharding: tables: course: actual-data-nodes: m$->{1..2}.course_$->{1..2} key-generator: column: cid type: SNOWFLAKE database-strategy: inline: sharding-column: userId algorithm-expression: m$->{userId%2+1} table-strategy: inline: sharding-column: cid algorithm-expression: course_$->{cid%2+1} props: sql: show: true mybatis-plus: configuration: map-underscore-to-camel-case: false
④ 測試代碼
@RunWith(SpringRunner.class) @SpringBootTest public class ShardingSphereTestApplication { @Autowired CourseMapper courseMapper; @Test public void addCourse() { for (int i = 1; i 20; i++) { Course course = new Course(); course.setCname("java" + i); int random = (int) (Math.random() * 10); course.setUserId(100L + random); course.setCstatus("Normal" + i); courseMapper.insert(course); } } @Test public void queryCourse() { QueryWrapper<Course> wrapper = new QueryWrapper<>(); wrapper.eq("cid", 493001315358605313L); Course course = courseMapper.selectOne(wrapper); System.out.println(course); } }
查詢實際對應的 SQL
:
公共表 :
① 思路分析
② 在對應數據庫建立公共表 t_udict,并创建对应实体和
Mapper``
CREATE TABLE `t_udict` ( `dict_id` bigint(16) NOT NULL, `ustatus` varchar(16) , `uvalue` varchar(255), PRIMARY KEY (`dict_id`) )
③ 詳細配置文件
spring: main: allow-bean-definition-overriding: true shardingsphere: datasource: names: m1,m2 m1: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3306/course_db_2?serverTimezone=GMT%2B8 username: root password: 1234 m2: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3306/course_db_3?serverTimezone=GMT%2B8 username: root password: 1234 sharding: tables: course: actual-data-nodes: m$->{1..2}.course_$->{1..2} key-generator: column: cid type: SNOWFLAKE database-strategy: inline: sharding-column: userId algorithm-expression: m$->{userId%2+1} table-strategy: inline: sharding-column: cid algorithm-expression: course_$->{cid%2+1} t_udict: key-generator: column: dict_id type: SNOWFLAKE broadcast-tables: t_udict props: sql: show: true mybatis-plus: configuration: map-underscore-to-camel-case: false
④ 進行測試
經測試:數據插入時會在每一個庫的每張表中插入,刪除時也會刪除全部數據。
@RunWith(SpringRunner.class) @SpringBootTest public class ShardingSphereTestApplication { @Autowired UdictMapper udictMapper; @Test public void addUdict() { Udict udict = new Udict(); udict.setUstatus("a"); udict.setUvalue("已啓用"); udictMapper.insert(udict); } @Test public void deleteUdict() { QueryWrapper<Udict> wrapper = new QueryWrapper<>(); wrapper.eq("dict_id", 493080009351626753L); udictMapper.delete(wrapper); } }
爲了確保數據庫產品的穩定性,不少數據庫擁有雙機熱備功能。也就是,第一臺數據庫服務器是對外提供增刪改業務的生產服務器;第二臺數據庫服務器主要進行讀的操做。
Sharding-JDBC
經過 sql
語句語義分析,實現讀寫分離過程,不會作數據同步,數據同步一般數據庫集羣間會自動同步。
詳細配置文件:
spring: main: allow-bean-definition-overriding: true shardingsphere: datasource: names: m0,s0 m0: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3306/course_db?serverTimezone=GMT%2B8 username: root password: 1234 s0: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://192.168.182.200:3307/course_db?serverTimezone=GMT%2B8 username: root password: 1234 masterslave: master-data-source-name: m0 slave-data-source-names: s0 props: sql: show: true mybatis-plus: configuration: map-underscore-to-camel-case: false
通過測試:增刪改操做都是會經過 master
數據庫,同時 master
數據庫會同步數據給 slave
數據庫;查操做都是經過 slave
數據庫.
Sharding-Proxy
定位爲 透明化的數據庫代理端,提供封裝了數據庫二進制協議的服務端版本,用於完成對異構語言的支持, 目前僅 MySQL
和 PostgreSQL
版本。
Sharding-Proxy
是獨立應用,須要安裝服務,進行分庫分表或者讀寫分離配置,啓動使用。
Sharding-proxy
的使用參考:Sharding-Proxy的基本使用。
微信搜一搜 : 全棧小劉 ,獲取文章 pdf 版本