分库分表之-sharding-jdbc 中间件使用

一、分库分表的方式

1、垂直分表:

将一个表拆分为多个表,按照字段使用频率,热度进行拆分,拆分后的表仍然在同一个库中

带来的提升:

  • 减少IO争抢导致锁表的几率,查询看商品详情与商品信息浏览互不影响。

  • 提供热门数据操作效率

拆分原则:

  • 把访问频率比较低字段单独放一张表中

  • 把txt,blob等大字段拆分出来放到附表中;

  • 把组合查询的列都放到一张表中;

垂直分库

把同一个库中的表拆分放到不同的数据库【不同服务器上面的数据库】

带来提升:

  • 业务层面降低了耦合

  • 不同业务数据可以很方便的进行分类管理,维护,扩展。

  • 高并发场景下,一定程度的提升了IO,降低了单机资源瓶颈,并且减少了数据库连接数

拆分原则

  • 根据业务层面对表进行分类

  • 数据是允许部署在不同的服务器上。

 

水平分库

水平分库,把同一个表的数据按照一定路由规则拆分到不同数据库库中,每一个库都可以放在不同服务器上。

提升性能:

  • 解决了单库数量量大,高并发性能瓶颈

  • 提高了系统稳定性,可用性

拆分原则:

  • 切分后数据行数巨大,存在单库读写,存储性能瓶颈

 

水平分表

将一个表通过一定的路由规则拆分到相同表结构的不同表中存储,水平分表是在同一个库中拆分

性能提升:

  • 提高数据库查询性能

  • 减少IO和锁表几率

拆分原则

  • 单表数据量过大

二、ShardingSphere简介

定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

  • 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
  • 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
  • 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。

2、sharding-jdbc核心概念

  • 逻辑表(LogicTable):进行水平拆分的时候同一类型(逻辑、数据结构相同)的表的总称。例:订单数据根据主键尾数拆分为10张表,分别是t_order_0t_order_9,他们的逻辑表名为t_order
  • 真实表(ActualTable):在分片的数据库中真实存在的物理表。即上个示例中的t_order_0t_order_9
  • 数据节点(DataNode):数据分片的最小单元。由数据源名称和数据表组成,例:ds_0.t_order_0
  • 动态表(DynamicTable):逻辑表和物理表不一定需要在配置规则中静态配置。如,按照日期分片的场景,物理表的名称随着时间的推移会产生变化。
  • 绑定表(BindingTable):指分片规则一致的主表和子表。例如:t_order表和t_order_item表,均按照order_id分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升
SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

水平分表为例:

注:下面用到的sharding-jdbc名词解释

  • 分片键(ShardingColumn):分片字段用于将数据库(表)水平拆分的字段,支持单字段及多字段分片。例如上例中的order_id。
  • 分片算法(ShardingAlgorithm):进行水平拆分时采用的算法,分片算法需要应用方开发者自行实现,可实现的灵活度非常高。目前提供4种分片算法。由于分片算法和业务实现紧密相关,因此并未提供内置分片算法,而是通过分片策略将各种场景提炼出来,提供更高层级的抽象,并提供接口让应用开发者自行实现分片算法。

项目为springboot 。

application.properties

#server.port=43210
#spring.application.name = sharding-jdbc-quickstart-demo
#server.servlet.context-path = /sharding-jdbc-quickstart-demo
spring.http.encoding.enabled = true
spring.http.encoding.charset = UTF-8
spring.http.encoding.force = true
mybatis.configuration.map-underscore-to-camel-case = true
#spring.profiles.active=masterslave

# 自定义数据源
spring.shardingsphere.datasource.names = m1
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/order_db?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 123456

# 以下是分片规则配置
# 指定t_order表的数据分布情况,配置数据节点
# t_order 逻辑表名
# insert into t_order () values ()
# $->{1..2} => 1, 2 => t_order_1,t_order_2
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes = m1.t_order_$->{1..2}

# 指定t_order表的主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE

# 指定t_order表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column = order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$->{order_id % 2 + 1}

# 打开sql输出日志
spring.shardingsphere.props.sql.show = true
logging.level.root = info
logging.level.org.springframework.web=info
logging.level.druid.sql=debug
logging.level.com.itheima.dbsharding=debug
OrderMapper
@Component
@Mapper
public interface OrderMapper {
    /**
     * 新增订单
     * @param price
     * @param userId
     * @param status
     * @return
     */
    @Insert("insert into t_order(price,user_id,status)values(#{price},#{userId},#{status})")
    int insertOrderInfo(@Param("price") BigDecimal price, @Param("userId")Long userId, @Param("status")String status);
}

 

ShardingJdbcTests 测试方法
   @Autowired
    public OrderMapper orderMapper;

    @Test
    public void testInsertOrder(){
        for (int i = 0 ; i<10; i++){
            orderMapper.insertOrderInfo(new BigDecimal((i+1)*4),1L,"Success");
        }
    }

 

 

 

posted @ 2020-07-28 17:35  AlexZS  Views(344)  Comments(0Edit  收藏  举报