大家 mysql 分表的哈希算法是怎样的?

比如把 users 用户表分为 100 个表,users_1 ~ users_100,可以根据 userid 进行哈希,这样分成 100 张表,我们的算法是:

function hashID($id, $max)
{
    $md5 = md5($id);
    $str1 = substr($md5, 0, 2);
    $str2 = substr($md5, -2, 2);
    $newStr = intval(intval($str1 . $str2, 16));
    $hashID = $newStr % $max + 1;
    return $hashID;
}

参数 $id ,就是分表的字段,如 userid,$max 是分成多少张表。

为什么不直接 userid%100+1 这样获取分表呢?分布也是比较均匀的吧,为什么要采用如上的函数,各位业务中分表的算法是怎样的?

阅读 9.1k
4 个回答

少用% 取模 扩展表的话就蛋疼了

分表hash算法有多种,我们原来分0-9,也搞过md5取最后一位0-9a-z,这个没有绝对的好坏只说,看量吧。

至于不能直接用%,需要考虑大整数溢出的问题:
2的32次方:4294967296

4294967296%100 // 结果为0
fmod(4294967296, 100) // 为96

简单的办法就是substr($str, -2);

963,1040,1008,1016,992,1010,997,1000,1025,998,971,1036,962,998,972,954,1040,931,953,1018,1054,992,934,983,1027,973,1021,1044,997,1010,1062,978,988,1028,972,986,979,922,1032,924,993,1055,1054,1031,1023,981,1027,1017,1005,1031,1004,1009,994,1004,967,1026,1016,984,1032,987,1053,964,978,983,985,992,948,1061,1068,993,933,1028,967,1010,1007,962,1018,978,1003,1036,1001,1021,1006,1006,1041,1022,971,957,956,1007,1023,952,1011,988,991,984,1020,1025,1003,1018

这个10000个数分100个表,平均每个表数的总个数,分布的很均匀了好吧。
然后用哈希速度快,也很装逼有木有^_^
图片描述

crc32 + 取模 简单

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题