开发者社区> 问答> 正文

数据库分表后,id如何生成?

已解决

单表数据量大了之后,需要分表。但是分表之后,表带id就不能再使用自动增长了。如何生成id?

展开
收起
exinnet 2016-01-25 17:20:05 3203 0
1 条回答
写回答
取消 提交回答
  • 淘宝技术专家
    采纳回答

    有很多中方式,这里说一种cas的方式。
    其实这里并不是严格的CAS,而是使用了比较交换原子操作的思想。
    生成思路如下:
    每次生成全局id时,先从sequence表中获取当前的全局最大id。然后在获取的全局id上做加1操作。把加1后的值更新到数据库。更新时是关键。
    如加1后的值为203,表名是users,数据表结构如下:
    CREATE TABLE SEQUENCE (

    `name` varchar(30) NOT NULL COMMENT '分表的表名',
    `gid` bigint(20) NOT NULL COMMENT '最大全局id',
    PRIMARY KEY (`name`)

    ) ENGINE=InnoDB

    那么更新语句是。
    update sequence set gid = 203 where name = 'users' and gid < 203;
    sql语句的 and gid < 203 是为了保证并发环境下gid的值只增不减。
    如果update语句的影响记录条数为0说明,已经有其他进程提前生成了203这个值,并写入了数据库。需要重复以上步骤从新生成。
    代码实现如下:
    //$name 表名
    function next_id_db($name){

    //获取数据库全局sequence对象
    $seq_dao = Wk_Sequence_Dao_Sequence::getInstance();
    $threshold = 100; //最大尝试次数
    for($i = 0; $i < $threshold; $i++){
        $last_id = $seq_dao->get_seq_id($name);//从数据库获取全局id
        $id = $last_id +1;
        $ret = $seq_dao->set_seq_id($name, $id);
        if($ret){
            return $id;
            break;
        }
    }
    return false;

    }

    更多方式,可以查看 数据库分表后,并发环境下,生成全局id生成的几种方式

    2019-07-17 18:26:30
    赞同 展开评论 打赏
问答分类:
问答标签:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
DTCC 2022大会集锦《云原生一站式数据库技术与实践》 立即下载
阿里云瑶池数据库精要2022版 立即下载
2022 DTCC-阿里云一站式数据库上云最佳实践 立即下载