項目初期沒有強大的 DBA, 隨着用戶增長, 訂單表愈來愈大, MySQL 的主機負載一直下不來, 致使吞吐下降html
表結構:java
CREATE TABLE `order_0` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `order_id` bigint(20) unsigned NOT NULL, `uid` bigint(20) unsigned NOT NULL, `money` int(11) NOT NULL, `status` tinyint(3) unsigned NOT NULL DEFAULT '0', `create_time` datetime NOT NULL, `modified_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_id` (`order_id`), KEY `idx_uid` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4
因爲是單key
業務, 只須要經過uid
來查詢, 則按照uid
來作分表因子
通過一些權衡, 仍是準備使用 shardingsphere ,社區活躍度也比較不錯
jdk 8 , shardingsphere 版本 4.0.0-RC2node
uid | uid % 2 (庫) | uid / 2 % 4 (表) |
---|---|---|
1 | 1 | 0 |
2 | 0 | 1 |
3 | 1 | 1 |
4 | 0 | 2 |
5 | 1 | 2 |
6 | 0 | 3 |
7 | 1 | 3 |
8 | 0 | 0 |
CREATE TABLE `order_0` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `order_id` bigint(20) unsigned NOT NULL, `uid` bigint(20) unsigned NOT NULL, `money` int(11) NOT NULL, `status` tinyint(3) unsigned NOT NULL DEFAULT '0', `create_time` datetime NOT NULL, `modified_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_id` (`order_id`), KEY `idx_uid` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 CREATE TABLE `order_1` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `order_id` bigint(20) unsigned NOT NULL, `uid` bigint(20) unsigned NOT NULL, `money` int(11) NOT NULL, `status` tinyint(3) unsigned NOT NULL DEFAULT '0', `create_time` datetime NOT NULL, `modified_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_id` (`order_id`), KEY `idx_uid` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 CREATE TABLE `order_2` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `order_id` bigint(20) unsigned NOT NULL, `uid` bigint(20) unsigned NOT NULL, `money` int(11) NOT NULL, `status` tinyint(3) unsigned NOT NULL DEFAULT '0', `create_time` datetime NOT NULL, `modified_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_id` (`order_id`), KEY `idx_uid` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4 CREATE TABLE `order_3` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `order_id` bigint(20) unsigned NOT NULL, `uid` bigint(20) unsigned NOT NULL, `money` int(11) NOT NULL, `status` tinyint(3) unsigned NOT NULL DEFAULT '0', `create_time` datetime NOT NULL, `modified_time` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_order_id` (`order_id`), KEY `idx_uid` (`uid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb4
<!--web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--自動生成 GET SET--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--鏈接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <!--MySQL--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.0-RC2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
spring.shardingsphere.datasource.names=db0,db1 spring.shardingsphere.datasource.db0.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.db0.driver-class-name=com.mysql.cj.jdbc.Driver spring.shardingsphere.datasource.db0.url=jdbc:mysql://localhost:3306/db0?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull spring.shardingsphere.datasource.db0.username=root spring.shardingsphere.datasource.db0.password=root spring.shardingsphere.datasource.db1.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.db1.driver-class-name=com.mysql.cj.jdbc.Driver spring.shardingsphere.datasource.db1.url=jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&zeroDateTimeBehavior=convertToNull spring.shardingsphere.datasource.db1.username=root spring.shardingsphere.datasource.db1.password=root # 是否顯示SQL語句 spring.shardingsphere.props.sql.show=true # 配置數據庫和表 spring.shardingsphere.sharding.tables.order.actual-data-nodes=db$->{0..1}.order_$->{0..1} # 配置根據哪一個字段選擇數據庫 spring.shardingsphere.sharding.tables.order.database-strategy.inline.sharding-column=uid # 配置選擇哪一個數據庫的規則 spring.shardingsphere.sharding.tables.order.database-strategy.inline.algorithm-expression=db$->{uid % 2} # 配置選擇根據哪一個字段選擇表 spring.shardingsphere.sharding.tables.order.table-strategy.inline.sharding-column=uid # 配置選擇哪一個表的規則 spring.shardingsphere.sharding.tables.order.table-strategy.inline.algorithm-expression=order_$->{(Integer)(uid / 2) % 4}
須要注意, 查詢訂單詳情須要帶上用戶 uid, 用來路由到對應的庫和表
多key業務,數據庫水平切分架構一次搞定 mysql
若是不當之處, 歡迎指出, 共同成長