垂直分表

  • 定义:将一个表的字段分散到多个表中,每个表存储其中一部分字段。
  • 垂直分表带来的提升是:
  1. 减少IO争抢,减少锁表的几率,查看商品详情的与商品概述互不影响
  2. 充分发挥高频数据的操作效率,对商品概述数据操作的高效率不会被操作商品详情数据的低效率所拖累。
  • 通常我们按以下原则进行垂直拆分:
    1.把不常用的字段单独放在一张表
    2.把text,blob等大字段拆分出来单独放在一张表
    3.经常组合查询的字段单独放在一张表中

垂直分库

  • 定义:垂直分库是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,从而达到多个服务器共同分摊压力的效果。
  • 垂直分库带来的提升是:
    1.解决业务层面的耦合,业务清晰
    2.能对不同业务的数据进行分级管理、维护、监控、扩展等
    3.高并发场景下,垂直分库在一定程度上可以提升IO、数据库连接数、单机硬件资源的性能

1.授权主从复制专用账号

#切换至主库bin目录,登录主库
mysql -h localhost -uroot -p123
#授权主从复制专用账号
GRANT REPLICATION SLAVE ON *.* TO 'db_sync'@'%' IDENTIFIED BY 'db_sync';
#刷新权限
FLUSH PRIVILEGES;
#确认位点 记录下文件名以及位点
show master status;

2.设置从库向主库同步数据、并检查链路

#切换至从库bin目录,登录从库
mysql -h localhost -P3307 -uroot -p123
#修改从库指向到主库,使用上一步记录的文件名以及位点
CHANGE MASTER TO
master_host = 'localhost',
master_user = 'db_sync',
master_password = 'db_sync',
master_log_file = 'mysql-bin.000001',
master_log_pos = 592;
#执行该命令前,一定要重启主库和从库服务
show slave status\G
#执行该命令后,确认Slave_IO_Runing以及Slave_SQL_Runing两个状态位是否为“Yes”,如果不为
Yes,请检查error_log,然后排查相关异常。
#注意:如果之前此从库已有主库指向,需要先执行以下命令清空
STOP SLAVE IO_THREAD FOR CHANNEL '';
reset slave all;

Sharding-jdbc
Sharding-JDBC是当当网研发的开源分布式数据库中间件。从 3.0 开始,Sharding-JDBC更名为Sharding-Sphere,之后该项目进入Apache孵化器,4.0之后的版本为Apache版本。
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。 它们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于Java同构、异构语言、容器、云原生等各种多样化的应用场景。
Sharding-JDBC可以进行分库分表,同时又可以解决分库分表带来的问题,它的核心功能是:数据分片
和读写分离。
1 数据分片
数据分片是Sharding-JDBC核心功能,它是指按照某个维度将存放在单一数据库中的数据分散存放至多个数据库或表中,以达到提升性能瓶颈以及可用性的效果。 数据分片的有效手段是对关系型数据库进行分库和分表。在使用Sharding-JDBC进行数据分片前,需要了解以下概念:
2.逻辑表
水平拆分的数据库(表)的相同逻辑和数据结构表的总称。例:订单数据根据主键尾数拆分为10张表,分别是 t_order_0 到 t_order_9 ,他们的逻辑表名为 t_order 。
真实表在分片的数据库中真实存在的物理表。即上个示例中的 t_order_0 到 t_order_9 。
3.数据节点
数据分片的最小单元。由数据源名称和数据表组成,例: ds_0.t_order_0 。
4.分片键
用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片。
5.自增主键生成策略
通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式全局主键无重复。
6.绑定表
指分片规则一致的主表和子表。例如: 商品信息表 表和 商品描述 表,均按照 商品id 分片,则此两张表互为绑定表关系。

3.导入依赖

<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
</dependency>

4.配置

#基本配置
server.port=56081
spring.application.name = sharding-jdbc-demo
server.servlet.context-path = /sharding-jdbc-demo
spring.http.encoding.enabled = true
spring.http.encoding.charset = UTF-8
spring.http.encoding.force = true
# 开启swagger
swagger.enable = true
# 同名bean允许覆盖
spring.main.allow-bean-definition-overriding=true
# 将带有下划线的表字段映射为驼峰格式的实体类属性
mybatis.configuration.map-underscore-to-camel-case = true

#Sharding-jdbc配置
# 真实数据源定义
spring.shardingsphere.datasource.names = m0,m1,m2,s0,s1,s2
spring.shardingsphere.datasource.m0.type =
com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m0.url = jdbc:mysql://localhost:3306/store_db?
useUnicode=true
spring.shardingsphere.datasource.m0.username = root
spring.shardingsphere.datasource.m0.password = 123
spring.shardingsphere.datasource.m1.type =
com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url =
jdbc:mysql://localhost:3306/product_db_1?useUnicode=true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 123
spring.shardingsphere.datasource.m2.type =
com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url =
jdbc:mysql://localhost:3306/product_db_2?useUnicode=true
spring.shardingsphere.datasource.m2.username = root
spring.shardingsphere.datasource.m2.password = 123
spring.shardingsphere.datasource.s0.type =
com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.url = jdbc:mysql://localhost:3307/store_db?
useUnicode=true
spring.shardingsphere.datasource.s0.username = root
spring.shardingsphere.datasource.s0.password = 123
spring.shardingsphere.datasource.s1.type =
com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s1.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s1.url =
jdbc:mysql://localhost:3307/product_db_1?useUnicode=true
spring.shardingsphere.datasource.s1.username = root
spring.shardingsphere.datasource.s1.password = 123
spring.shardingsphere.datasource.s2.type =
com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s2.driver-class-name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s2.url =
jdbc:mysql://localhost:3307/product_db_2?useUnicode=true
spring.shardingsphere.datasource.s2.username = root
spring.shardingsphere.datasource.s2.password = 123
# 主库从库逻辑数据源定义 ds0为store_db ds1为product_db_1 ds2为product_db_2
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=s0
spring.shardingsphere.sharding.master-slave-rules.ds1.master-data-source-name=m1
spring.shardingsphere.sharding.master-slave-rules.ds1.slave-data-source-names=s1
spring.shardingsphere.sharding.master-slave-rules.ds2.master-data-source-name=m2
spring.shardingsphere.sharding.master-slave-rules.ds2.slave-data-source-names=s2
# 分库策略,以store_info_id为分片键,分片策略为store_info_id % 2+1
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column
= store_info_id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithmexpression = ds$->{store_info_id % 2+1}
# store_info分表策略,固定分配至ds0的store_info真实表
spring.shardingsphere.sharding.tables.store_info.actual-data-nodes = ds$->
{0}.store_info
spring.shardingsphere.sharding.tables.store_info.table-strategy.inline.shardingcolumn = id
spring.shardingsphere.sharding.tables.store_info.tablestrategy.inline.algorithm-expression = store_info
# product_info分表策略,分布在ds1,ds2的product_info_1和product_info_2表 ,分片策略为
product_info_id % 2+1,product_info_id采用雪花算法
spring.shardingsphere.sharding.tables.product_info.actual-data-nodes = ds$->
{1..2}.product_info_$->{1..2}
spring.shardingsphere.sharding.tables.product_info.tablestrategy.inline.sharding-column = product_info_id
spring.shardingsphere.sharding.tables.product_info.tablestrategy.inline.algorithm-expression = product_info_$->{product_info_id % 2+1}
spring.shardingsphere.sharding.tables.product_info.keygenerator.column=product_info_id
spring.shardingsphere.sharding.tables.product_info.key-generator.type=SNOWFLAKE
# product_descript分表策略,分布在ds1,ds2的product_descript_1和product_descript_2表
,分片策略为product_info_id % 2+1,id采用雪花算法
spring.shardingsphere.sharding.tables.product_descript.actual-data-nodes = ds$->{1..2}.product_descript_$->{1..2}
spring.shardingsphere.sharding.tables.product_descript.tablestrategy.inline.sharding-column = product_info_id
spring.shardingsphere.sharding.tables.product_descript.tablestrategy.inline.algorithm-expression = product_descript_$->{product_info_id %2+1}
spring.shardingsphere.sharding.tables.product_descript.key-generator.column=id
spring.shardingsphere.sharding.tables.product_descript.keygenerator.type=SNOWFLAKE
# 设置product_info,product_descript为绑定表,这两张表中的分片键名字必须一致
spring.shardingsphere.sharding.binding-tables = product_info,product_descript
# 打开sql输出日志
spring.shardingsphere.props.sql.show = true

5.DAO层代码

@Mapper
@Component
public interface ProductDao {
@Insert("insert into
product_info(store_info_id,product_name,spec,region_code,price,image_url)
value(#{storeInfoId},#{productName},#{spec},#{regionCode},#{price},#
{imageUrl})")
@Options(useGeneratedKeys = true,keyProperty = "id",keyColumn =
"product_info_id")
int insertProductInfo(ProductInfo productInfo);
@Insert("insert into
product_descript(product_info_id,descript,store_info_id) value(#
{productInfoId},#{descript},#{storeInfoId})")
@Options(useGeneratedKeys = true,keyProperty = "id",keyColumn = "id")
int insertProductDescript(ProductDescript productDescript);
@Select("select i.*, d.descript from product_info i inner join
product_descript d on i.product_info_id = d.product_info_id ")
List<ProductInfo> selectProductList();
}
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐