• 分表,分库算法


    经典案例:

    1:在memcache中分key存储。主机分布式选择主机的算法

    一:利用crc32散列

        <?php
        //范围:00-63
        function crc_hash(&$keyword,$n=64)
        {
        $hash = crc32($keyword) >> 16 & 0xffff;
        return sprintf("%02s",$hash % $n);
        }
        ?>
    

     二:当用户数量太多(如达到千万级别),数量量太大时,我们会根据用户名username使用hash算法得出0-N的一个数值,将用户信息分散存储到N个表中,如增加用户信息示例代码如下:

        <?php
    
        function getHash(&$keyword,$n)
        {
        $hash = crc32($keyword) >> 16 & 0xffff;
        return sprintf("%02s",$hash % $n);
        }
    
        $table = 'userinfo_'.getHash($username,100);
    
        $sql = "insert into {$table} values(....)";
    
        $db = new models($table);//封装的数据库操作类
        $db->MyInsert($sql);
    
        ?>
    

     三:

    hash算法一般是利用数组实现的,步骤如下:
    存元素时:
    1.把要存储的元素(value)计算一个hashcode(称为散列),这个就是key。
    2.把元素存储到以hashcode为下标的数组中。
    3.若此数组下标已经有元素,则使用链表的方式把元素连接起来。

    获得元素时:
    1.元素(value)计算hashcode。
    2.hash表中按hashcode(key)取得元素。
    3.若一个key中对应多个元素,则还需匹配是哪个元素。

    就这么简单,hash算法由于直接映射数组下标,所以查找算法的时间复杂度来说是O(1)的。不过若计算hashcode的算法不是很好的话,可能 造成一个桶(数组中的一个位置)内有多个元素,而有些桶内一个元素都没有。这样在存、取元素时都需要在桶内进行查找操作,而且造成空间的浪费。所以一个好的hashcode的算法使得任意给定的元素能够均匀地存储在hash表中的每个桶内,显得尤为重要。以下给出一个非常经典的通用散列算法,经过研究人员统计分析过散列程度的。

        unsigned long hashcode(const unsigned char *name)
        {
        unsigned long h=0,g;
        while(*name)
        {
        h=(h<<4) + *name++;
        if(g=h & 0xF0000000)
        h^=g>>24;
        h &=~g;
        }
        return h;
        }
    

    除非你对这个通用散列算法有特殊需求,导致无法满足需要,否则应该使用这个函数。

    hash算法确实应用得非常广泛,因为其查找的速度是O(1)的。比如:如今数据的海量存取和高并发访问的需求,造成关系数据库逐渐退出舞台。DB中使用B+树索引提供范围查询,hash(key-value)索引实现点查询。

    例子:

    在开发中,整型的数值可以通过取模(mod)来进行分表,但是,对于帐号这种字符串类型,却不能实现。怎么办呢,我们可以通过CRC32这个函数来分表,函数如下:

    function account_hash($account,$tail=4,$mod=1)
    {
    $crc32=sprintf("%u",crc32($account));//使用%u解决32位下出现负数的问题
    return fmod(substr(strval($crc32),-$tail,$tail),$mod); //取模计算数值
    }



    使用这个函数,可以灵活定义分表的离散程度和分表数量

    参考:http://www.dewen.io/q/405/%E6%B1%82mysql+%E5%88%86%E8%A1%A8%E7%9A%84%E6%84%8F%E4%B9%89

    1. <?php
    2. //范围:00-63
    3. function crc_hash(&$keyword,$n=64)
    4. {
    5. $hash = crc32($keyword)>>16&0xffff;
    6. return sprintf("%02s",$hash % $n);
    7. }
    8. ?>
  • 相关阅读:
    谁在TDD
    开源许可证简单总结
    【转】IIS HTTP500错误以及COM+应用程序8004e00f错误的解决方法
    [原]Linux平台Boost的编译方法
    [原]linux下格式化磁盘的相关问题
    [原]编译MongoDB,C++连接MongoDB测试
    [转]谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词(科普)
    [转]linux下如何查看文件编码格式及转换文件编码
    [原]linux(虚拟机)下安装MySQL
    [转]Linux下比较全面的监控工具dstat
  • 原文地址:https://www.cnblogs.com/Alight/p/4161080.html
Copyright © 2020-2023  润新知