数据库水平分表算法实现介绍如下:
一:实现思想
以MurmurHash算法为基础,在MurmurHash算法进行必要改造,本次主要进行64分表,即分为64个主表,实现思想简介如下:
1、MurmurHash生成hashcode ---详细可看代码
2、hashcode取模64生成分表下表,---详细可看代码
3、分表的下表拼接 ---详细可看代码
具体细节可参考code,如下;
二:code实现
/**
* 描述:分表生成及常用方法统一提供
* @author Aaron
* @version 1.0
* @param args
*/
public class HashTableIndex
{
private static StringBuffer stringBuffer = null;
static {
if (null == stringBuffer) {
stringBuffer = new StringBuffer();
}
}
public static long hash64A(ByteBuffer buf, int seed)
{
ByteOrder byteOrder = buf.order();
buf.order(ByteOrder.LITTLE_ENDIAN);
long m = 0xc6a4a7935bd1e995L;
int r = 47;
long h = seed ^ (buf.remaining() * m);
long k;
while (buf.remaining() >= 8)
{
k = buf.getLong();
k *= m;
k ^= k >>> r;
k *= m;
h ^= k;
h *= m;
}
if (buf.remaining() > 0)
{
ByteBuffer finish = ByteBuffer.allocate(8).order(ByteOrder.LITTLE_ENDIAN);
finish.put(buf).rewind();
h ^= finish.getLong();
h *= m;
}
h ^= h >>> r;
h *= m;
h ^= h >>> r;
buf.order(byteOrder);
return h;
}
/**
* @author Aaron 描述:hash值生成
* @param key
* @return
*/
public static long hash(byte[] key)
{
return hash64A(ByteBuffer.wrap(key), 0x1234ABCD);
}
/**
* @author Aaron
* 描述:64个分表hash下表生成
*/
public static long getTableBelow(String userId)
{
return Math.abs(hash(SafeEncoder.encode(userId)) % 64);
}
/**
* 描述:根据入参tableName、tableIndex生成分表
* @author Aaron
* @version 1.0
* @param args
*/
public static String getTableName(String tableName,long tableIndex) {
//枚举匹配
for(TableName tname :TableName.values()) {
if(tname.toString().equals(tableName)) {
stringBuffer = stringBuffer.delete(0, stringBuffer.length()).append(tableName).append("_").append(tableIndex);
}
}
return stringBuffer.toString();
}
/**
* 描述:根据入参tableName、userId生成分表
* @author Aaron
* @param args
*/
public static String getTableName(String tableName,String userId) {
//枚举匹配
//stringBuffer=null;
for(TableName tname :TableName.values()) {
if(tname.toString().equals(tableName)) {
stringBuffer = stringBuffer.delete(0, stringBuffer.length()).append(tname).append("_").append(getTableBelow(userId));
}
}
return stringBuffer.toString();
}
/**
* 描述:根据入参tableName、userId查询分表
* @author Aaron
* @param args
*/
public static String selectChildTableName(String tableName,String userId) {
//枚举匹配
for(TableName tname :TableName.values()) {
if(tname.toString().equals(tableName)) {
stringBuffer = stringBuffer.delete(0, stringBuffer.length()).append(tname).append("_").append(getTableBelow(userId));
}
}
return stringBuffer.toString();
}
// 测试
public static void main(String[] args)
{
//System.out.println(getTableBelow("39666665"));
System.out.println("-----------"+getTableName("user",getTableBelow("565")));
System.out.println("-----------"+getTableName("user","565"));
}
}
有问题可评论区讨论,欢迎大家指出不足,便于共同进步!!!!
邮箱:[email protected]