带来的提升:
-
减少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_0
到t_order_9
,他们的逻辑表名为t_order
。 - 真实表(ActualTable):在分片的数据库中真实存在的物理表。即上个示例中的
t_order_0
到t_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);
以
- 分片键(ShardingColumn):分片字段用于将数据库(表)水平拆分的字段,支持单字段及多字段分片。例如上例中的order_id。
- 分片算法(ShardingAlgorithm):进行水平拆分时采用的算法,分片算法需要应用方开发者自行实现,可实现的灵活度非常高。目前提供4种分片算法。由于分片算法和业务实现紧密相关,因此并未提供内置分片算法,而是通过分片策略将各种场景提炼出来,提供更高层级的抽象,并提供接口让应用开发者自行实现分片算法。
#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"); } }