首页 > C, MySQL > 分库分表(sharding)后主键全局唯一性的解决方案

分库分表(sharding)后主键全局唯一性的解决方案

随着数据量的增大,在数据库的扩展上通常遇到切分时保证键值的唯一性问题,遇到这种情况,通常有如下几种相对简单的解决方案:

1  UUID 这种方案的优点是实现和管理简单,缺点是占用空间大,查询效率低下。

2  Sequence Number 优点是实现和管理简单,确定是有性能瓶颈和单点问题。

3  不同的集群采用的起始点或者增长间隔不同 这种方案实现简单,但是后期管理麻烦。

除了上述解决方案之外其实还有很多简单可行的办法,但是通用性不太好,在各种解决方案的接触上,本人总结出一个实现和性能上都很好的解决方案,那就是采用时间戳加毫秒数再加随机数来解决,存储字段采用bigint。
下面给出php代码实现:
function ivan_fetch_unique_bigint_id()
{
    $start_timestamp = 1238119411;
    $ivan_len = 3;
    $time = explode( ‘ ‘, microtime());
    $id = ($time[1]$start_timestamp) . sprintf(‘%06u’, substr($time[0], 2, 6));
    if ($ivan_len > 0) {
        $id .= substr(sprintf(‘%010u’, mt_rand()), 0, $ivan_len);
    }
    return $id;
}
取模测试均分性很好。
转载请注明出处,谢谢。
分类: C, MySQL 标签:
  1. 2009年3月27日13:35 | #1

    高并发下还靠谱不

  2. 2009年3月27日13:47 | #2

    @神仙
    直接插入,如果id重复会抛出exception(因为会模到同一库表中),然后重新生成ID,再插入。不过我想就算高并发,这种碰撞的概率接近于0

  3. 膜拜
    2009年12月7日22:31 | #3

    其中用了unix的时间戳是32位的,貌似在2037年左右就会失效?到时候,如升级64位时间戳能否保证不发生重复id呢?

  4. 2009年12月8日17:04 | #4

    @膜拜
    我想现在的发展速度,等到2038年的时候,肯定有解决方法的,不用担心。

  5. Jack Liang
    2010年4月14日15:36 | #5

    膜拜讲得不对,这个数生成是这样的
    33109660 407978 070
    9~10位秒数 6位微妙 3位随机数

    UNIX时间戳是(2^32/2)2,147,483,648 ,足够68年的秒数用
    而bigint 范围是
    -2^63 (-9,223,372,036,854,775,808) 到 2^63-1 (9,223,372,036,854,775,807)
    这个 9,223,372,036 足够292年用
    非常充足了

  1. 本文目前尚无任何 trackbacks 和 pingbacks.