• 分库分表之-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");
            }
        }
     
  • 相关阅读:
    (转)值得学习百度开源70+项目
    C#中$的用法
    (转载)《C#高级编程》读书笔记
    C#调用大漠插件
    Visual Studio 2017 扩展推荐
    C#操作Dataset数据集与SQLite数据库
    (转载)C#格式规范
    (转载)DataTable与List<T>相互转换
    FastReport.Net
    (转载)C #开源框架
  • 原文地址:https://www.cnblogs.com/alomsc/p/13392431.html
Copyright © 2020-2023  润新知