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();
}