版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012045045/article/details/84777266
之前做项目,因为数据量比较大,所以涉及到分库分表。分库自然不必多说,自然是读写分离。分表我们直接是做的数据的水平切割,将大量数据均匀分布到100张表中。
我们分表的依据是用户id和用户证件号码的出生日期对10取模。
首先说一下第一种方法,使用用户id对100取模获取用户渠道表的user_channel_0到user_channel_99,上代码。
抽象规范类:
package com.cmbc.smp.busi;
public abstract class PartTableManage <P,O> {
P p;
O o;
public abstract void init();
public abstract O getPartTableName(P param);
}
定义类
package com.cmbc.smp.busi;
public class UserChannelDimension {
public static final int MODEL = 100;
public static final String MAIN_TABLE = "user_channel_info";
public static final String UNDERLINE = "_";
public static final int TABLE_NUM = 100;
private int tableSeq ;
private int partFieldValue;
public UserChannelDimension(){
}
public UserChannelDimension(int tableSeq, int partFieldValue){
this.tableSeq = tableSeq;
this.partFieldValue = partFieldValue;
}
public int getTableSeq() {
return tableSeq;
}
public void setTableSeq(int tableSeq) {
this.tableSeq = tableSeq;
}
public int getPartFieldValue() {
return partFieldValue;
}
public void setPartFieldValue(int partFieldValue) {
this.partFieldValue = partFieldValue;
}
}
分表类:
package com.cmbc.smp.busi;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserChannelPartTableManage extends PartTableManage<UserChannelDimension, List<String>>{
private static final Logger logger = LoggerFactory.getLogger(UserChannelPartTableManage.class);
@Override
public void init() {
if(CollectionUtils.isEmpty(this.o)){
o = new ArrayList<String>(UserChannelDimension.TABLE_NUM);
}else{
o.clear();
}
for(int m = 0; m < UserChannelDimension.MODEL; m++ ){
this.o.add(UserChannelDimension.MAIN_TABLE + UserChannelDimension.UNDERLINE + m);
}
logger.info("user_channel_info分表加载成功!");
}
@Override
public List<String> getPartTableName(UserChannelDimension param) {
List<String> tables = null;
//包含如下情形:
//1.参数为空或者partFieldValue = -1,说明是获取全部分表名称
//2.PARAM非空,并且partFieldValue大于-1,则直接用partFieldValue对UserDimension.model取模,获得分表名
if(null == param ||param.getPartFieldValue() == -1){
return this.o;
}
if(param.getPartFieldValue() > -1){
param.setTableSeq(param.getPartFieldValue() % UserChannelDimension.MODEL);
tables = new ArrayList<String>(1);
tables.add(UserChannelDimension.MAIN_TABLE + UserChannelDimension.UNDERLINE + param.getTableSeq());
}
//其他情形暂不支持
return tables;
}
}
第二种方法:根据用户id和身份证日期的日期对10取模,获取100张表。user_0_0到user_9_9
上代码:
定义类:
package com.cmbc.smp.busi;
public class UserDimension {
public static final int TABLE_NUM = 100;
public static final int MODEL_ONE = 10;
public static final int MODEL_TWO = 10;
public static final String MAIN_TABLE = "user_info";
public static final String UNDERLINE = "_";
public UserDimension(){
this.dimensionOneTable = -1;
this.dimensionOneValue = -1;
this.dimensionTwoTable = -1;
this.dimensionTwoValue = -1;
}
public UserDimension(int dimensionOneTable,int dimensionOneValue,int dimensionTwoTable,int dimensionTwoValue){
this.dimensionOneTable = dimensionOneTable;
this.dimensionOneValue = dimensionOneValue;
this.dimensionTwoTable = dimensionTwoTable;
this.dimensionTwoValue = dimensionTwoValue;
}
private int dimensionOneTable;
private int dimensionTwoTable;
private int dimensionOneValue;
private int dimensionTwoValue;
public int getDimensionOneTable() {
return dimensionOneTable;
}
public void setDimensionOneTable(int dimensionOneTable) {
this.dimensionOneTable = dimensionOneTable;
}
public int getDimensionTwoTable() {
return dimensionTwoTable;
}
public void setDimensionTwoTable(int dimensionTwoTable) {
this.dimensionTwoTable = dimensionTwoTable;
}
public int getDimensionOneValue() {
return dimensionOneValue;
}
public void setDimensionOneValue(int dimensionOneValue) {
this.dimensionOneValue = dimensionOneValue;
}
public int getDimensionTwoValue() {
return dimensionTwoValue;
}
public void setDimensionTwoValue(int dimensionTwoValue) {
this.dimensionTwoValue = dimensionTwoValue;
}
}
分表类:
package com.cmbc.smp.busi;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserPartTableManage extends PartTableManage<UserDimension, List<String>>{
private static final Logger logger = LoggerFactory.getLogger(UserPartTableManage.class);
/**
* 初始化方法,加载所有表名成至List<String>
*/
@Override
public void init() {
//根据userID对10取模,身份证生日中的日对10取模,总共一百张分表,形如user_info_X_Y
if(CollectionUtils.isEmpty(this.o)){
o = new ArrayList<String>(UserDimension.TABLE_NUM);
}else{
o.clear();
}
for(int m = 0; m < UserDimension.MODEL_ONE; m++ ){
for(int n = 0; n< UserDimension.MODEL_TWO; n++){
this.o.add(UserDimension.MAIN_TABLE + UserDimension.UNDERLINE + m + UserDimension.UNDERLINE + n);
}
}
logger.info("user_info分表加载成功!");
}
@Override
public List<String> getPartTableName(UserDimension param) {
List<String> tables = null;
//1.四个字段都无有效值,说明是返回所有分表名的集合
//2.判断分表位置是否有值,若有值则直接替换
if(null == param){
return this.o;
}
//获取全部分表
if(param.getDimensionOneTable() <0 && param.getDimensionTwoTable() < 0
&& param.getDimensionOneValue() < 0 &¶m.getDimensionTwoValue() < 0 ){
return this.o;
}
//根据用户id获取所有此用户维度的所有10个分表
if(param.getDimensionOneValue() > -1 && param.getDimensionTwoValue() < 0){
tables = new ArrayList<String>(UserDimension.MODEL_TWO);
//用户分表号
param.setDimensionOneTable(param.getDimensionOneValue()%UserDimension.MODEL_ONE);
for(int k = 0 ; k < UserDimension.MODEL_TWO ; k ++ ){
tables.add(UserDimension.MAIN_TABLE + UserDimension.UNDERLINE + param.getDimensionOneTable() + UserDimension.UNDERLINE + k);
}
return tables;
}
//根据证件号生日的日获取此生日维度所有10个分表
if(param.getDimensionTwoValue() > -1 && param.getDimensionOneValue() < 0){
tables = new ArrayList<String>(UserDimension.MODEL_ONE);
//用户分表号
param.setDimensionTwoTable(param.getDimensionTwoValue()%UserDimension.MODEL_TWO);
for(int k = 0 ; k < UserDimension.MODEL_ONE ; k ++ ){
tables.add(UserDimension.MAIN_TABLE + UserDimension.UNDERLINE + k + UserDimension.UNDERLINE + param.getDimensionTwoTable());
}
return tables;
}
//根据用户id和生日获取精确的一张分表
if(param.getDimensionOneValue() > -1 && param.getDimensionTwoValue() > -1){
tables = new ArrayList<String>(1);
param.setDimensionOneTable(param.getDimensionOneValue() % UserDimension.MODEL_ONE);
param.setDimensionTwoTable(param.getDimensionTwoValue() % UserDimension.MODEL_TWO);
tables.add(UserDimension.MAIN_TABLE + UserDimension.UNDERLINE + param.getDimensionOneTable() + UserDimension.UNDERLINE + param.getDimensionTwoTable());
return tables;
}
//暂时不支持其他模式
return tables;
}
}