import java.util.Arrays;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 同一个hash值,先分库再分表,计算落在哪号库的哪号表中。
 *
 * 试验证:当dbSize和tableSize的最大公约数大于1时,数据会不平均
 *
 * @author lei.liu
 * @since 2021-05-08 17:27
 */
public class HashDatabaseAndTableTest {
    private static int hashSeed = 131;

    public static void main(String[] args) {
        int dbSize = 6;
        int tableSize = 10;
        int[][] array = new int[dbSize][tableSize];
        print(array);
        for (int i = 0; i < 1000000; i++) {
            String uid = String.valueOf(i);
            int hash = hash(uid);
            array[hash % dbSize][hash % tableSize]++;
        }
        System.out.println("==========");
        print(array);
    }

    private static void print(int[][] array) {
        StringBuilder sb = new StringBuilder();
        sb.append(" ")
            .append(IntStream.range(0, array[0].length + 1)
                .mapToObj(e -> "table" + e)
                .collect(Collectors.joining(" "))
            )
        .append("\n");
        for (int i = 0; i < array.length; i++) {
            sb.append("db" + i + " ");
            sb.append(Arrays.toString(array[i])).append("\n");

        }
        System.out.println(sb.toString());
    }

    public static int hash(String shardStr) {
        if (StringUtils.isEmpty(shardStr)) {
            throw new RuntimeException("shardStr not empty");
        }

        int hash = 0;
        for (int i = 0; i < shardStr.length(); i++) {
            hash = (hash * hashSeed) + shardStr.charAt(i);
        }
        return (hash & 0x7FFFFFFF) ;
    }
}
作者:admin  创建时间:2023-07-12 21:45
最后编辑:admin  更新时间:2025-09-19 10:08