java-数据库分表:根据UUID(字符串)取模定位分表

一、导读

对于数据库来说,数据量的增多简单的处理方式就是分库分表以及读写分离的模式,今天的文章只对分表做下描述,采用取模的方式定位分表下标,大家对取模都熟悉吧,例如5%3=2,取模就是取得是余数2,被除数3代表你要分几张表,取模一个很关键的因素就是除数与被除数必须是数字格式,针对数据库自增长的id是没有问题的,但是针对UUID(字符串)生成的id是无法直接取模的,接下来我会用代码给大家讲解下针对UUID(字符串)的取模。

二、解决方案及代码

UUID的组成方式是由数字0-9和小写的a-z根据一定的规则随机获取32位字符组成,我们的处理方式就是获取uuid的首字母来取模,首字母既有数字也有字符的格式,那它们对应的ASC码值或hashCode()值都是数字格式,这样看来问题就简单了,还是看以下实际代码吧,希望都帮助到大家

package com.hanshimeng;

import java.util.Map.Entry;
import java.util.TreeMap;

public class TabSuffix {

	/**
	 * 根据UUID首字母的ASC码获取表.
	 * UUID首字母包含[0123456789abcdefghijklmnopqrstuvwxyz]
	 * 分表个数必须被36整除或整除36(1 2 3 4 9 12 18 36)
	 * @param 分表数目
	 * @return 结果如"1"
	 */
	public static int getTabSuffixCurrent(int splitdemision, String uuidStr){
		// 无法被36整除,异常返回-1
		if(36 % splitdemision != 0){
			return -1;
		}
		
		// 获取首字母asc值(第一种)
		int asc = getAsc(uuidStr.substring(0,1));
		// 获取字母的hashCode(第二种)
		// int asc = uuidStr.substring(0,1).hashCode();
		if(splitdemision == 1 || splitdemision == 2 || splitdemision == 3 
				|| splitdemision == 4 || splitdemision == 12){
			if(asc == 121 || asc == 122){
				asc += 9;
			}
		}else if(splitdemision == 9){
			if(asc == 120){
				asc += 3;
			}
		}else if(splitdemision == 18){
			if(asc == 120 || asc == 121 || asc == 122){
				asc -= 8;
			}
		}else if(splitdemision == 36){
			if(asc == 120 || asc == 121 || asc == 122){
				asc += 10;
			}
		}
		int tableIdx = asc % splitdemision + 1;
		return tableIdx;
	}
	
	/**
     * 字符转ASC
     * 
     * @param st
     * @return
     */
    public static int getAsc(String st) {
        byte[] gc = st.getBytes();
        return (int) gc[0];
    }
	
	
	public static void main(String[] args) {
		// 初始UUID首字母
		String str ="0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
		String[] strGro = str.split(",");
		// 表下标:1 2 3 4 9 12 18 36
		int splitdemision = 3;
		TreeMap<Integer, Integer> map = new TreeMap<>();
		for (String item : strGro) {
			item += "uuid";
			int value = getTabSuffixCurrent(splitdemision, item);
			if(map.containsKey(value)){
				map.put(value, map.get(value)+1);
			}else{
				map.put(value, 1);
			}
		}
		
		// 测试打印数据
		for (Entry<Integer, Integer> entry : map.entrySet()) {
			System.out.println(entry.getKey()+"--"+entry.getValue());
		}
	}
}
输出结果:
1--12
2--12
3--12

注意:数据库数据的主键(UUID)生成,建议使用java.util下的UUID工具包,因为这个工具包每次生成UUID前半段是不同的,而数据库自带的UUID方法生成后首字母以及前半段都是一样的,如果描述的不清楚就看下面的例子

数据库自带的UUID生成示例:
数据库自带的UUID生成示例
java.util包下的UUID工具包生成示例:
java.util包下的UUID工具包生成示例
以上分享纯属个人观点,欢迎大家来探讨!

如需转载,请注明作者出处
作者:hanshimeng
出处:https://blog.csdn.net/hanshimeng

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值