1、分库分表用来干啥的
2、分库分表的分类
2.1 垂直分表
就是把一个大表 中的字段分门别类的 按照使用频次的高低划分 成几个表。常用的字段放一个表,不常用的 放一个表。
好处是:减少io 的争抢 查看商品的详情和商品浏览不影响
2.2 水平分表
就是把同一个数据库中的同一个表 按照一定的规则 复制一份出来(还在同一个库中)两个表平分数据。解决了单表数据量过大的问题
2.3 垂直分库
垂直分库就是 按照业务把将表进行分类(例如 商品信息在一个库,店铺信息在一个库中),分布到不同的数据库上面,每个库放到不同的服务起上面,核心理念是专库 专用。依然解决不了单表数据量过大的问题。
2.4 水平分库
就是把同一个库中的表 按照一定的规则放到 复制一份放到另一个库中 两个库平分数据。 解决了单库数据量过大的问题 减少io 锁定 某个库出现问题部分库可用。
3、分库分表带来的问题
3.1 分布式事务的问题 数据的一致性问题 (sharding jdbc 解决不了)
3.2 连表查询的问题 不同的表再不同的库里面
3.3 分页 和 排序 问题。
3.4 主键避重的问题
3.5 公共表的使用
4、常用的配置 springboot
4.1 s0是 新配的从库 m0 是主库 只配了user_db数据库
spring.shardingsphere.datasource.names = m0,m1,m2,s0
4. 2 为s0配置数据源 端口是 3307 m1,m2,m0 也配置数据源
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/user_db?useUnicode = true
spring.shardingsphere.datasource.m0.username = root
spring.shardingsphere.datasource.m0.password = root
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/user_db?useUnicode = true
spring.shardingsphere.datasource.s0.username= root
spring.shardingsphere.datasource.s0.password= root
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_1?useUnicode = true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = root
4.3 主从数据库的配置 告诉 sharding jdbc m0 和s0 互为主从。这里ds0 随便起的名
spring.shardingsphere.sharding.master-slave-rules.ds0.masterDataSourceName=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slaveDataSourceNames=s0
4.4 从新的指定t_user表的分片情况
spring.shardingsphere.sharding.tables.t_user.actual-dataNodes = ds0.t_user
4.5 配置分库的策略 根据用户id 把数据分到不同的库中
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.shardingColumn = user_id
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline..algorithmExpression= m$->{user_id % 2 + 1 }
4.6 全局主键 订单表的主键生成策略
spring.shardingsphere.sharding.tables.t_order.keyGenerator.column=order_id
spring.shardingsphere.sharding.tables.t_order.keyGenerator.type=SNOWFLAKE
4.7 订单表在那个库上 (在m1 和m2上 并且是水平分表的 名字是 t_order_1,t_order_2)
spring.shardingsphere.sharding.tables.t_order.actual-dataNodes= m$->{1..2}.t_order_$->{1..2}
4.8 订单表的分片策略 根据什么算法 把数据落到具体的表上 (这里根据 order_id 来的 这个分片键)
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.shardingColumn=order_id
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.algorithmExpression=t_order_$->{order_id % 2 + 1 }
4.9 指定公共表
spring.shardingsphere.sharding.broadcast-tables=t_dict
4.10 特别的注意
特别的注意如果配置了读写分离 t_user 的数据节点用下面的配置 ds0 指的时 m0,s0;
5、具体的例子
@Mapper
@Component
public interface OrderDao {
@Insert(("INSERT INTO t_order(price,user_id,status)" +
" VALUES (#{price},#{userId},#{status});"))
int insertOrder(Order order);
@Select("select * from t_order where order_id=#{orderId}")
Order selectOrder(@Param("orderId")Long orderId);
@Select("select * from t_order where price > 13")
List<Order> selectAllOrder();
@Update("UPDATE t_order SET status=#{status} WHERE order_id=#{orderId}")
public int update(Order order);
@Select("select count(*) from t_order")
public int selectCount();
@Select("select count(*) as num from t_order group by user_id having num > 1 order by user_id" )
public List<Map> selectCountBygroup();
}