Mysql分库分表之后主键处理的几种方法

目录
  • 数据库自增 ID
  • 设置数据库 sequence 或者表自增字段步长
  • UUID
  • 系统当前时间戳+XXX
  • Snowflake 算法

数据库自增 ID

搞一个数据库,什么也不干,就用于生成主键。

你的系统里每次得到一个 id,都需要往那个专门生成主键的数据库中通过插入获取一个自增的ID,拿到这个 id 之后再往对应的分库分表里去写入。

优点:方便简单。

缺点单库生成自增 id,要是高并发的话,就会有瓶颈的;如果你硬是要改进一下,那么就专门开一个服务出来,这个服务每次就拿到当前 id 最大值,然后自己递增几个 id,一次性返回一批 id,然后再把当前最大 id 值修改成递增几个 id 之后的一个值;但是无论如何都是基于单个数据库。

适合的场景:系统并发不大,只是因为数据量大的原因而去做的分库分表的话,可以采用这种方式。

设置数据库 sequence 或者表自增字段步长

可以通过设置数据库 sequence 或者表的自增字段步长来进行水平伸缩。

比如说,现在有 8 个服务节点,每个服务节点使用一个 sequence 功能来产生 ID,每个 sequence 的起始 ID 不同,并且依次递增,步长都是8

适合的场景:在用户防止产生的 ID 重复时,这种方案实现起来比较简单,也能达到性能目标。但是服务节点固定,步长也固定,将来如果还要增加服务节点,就不好搞了。

UUID

优点:本地生成,不需要基于数据库;

缺点:UUID 太长了、占用空间大;作为主键性能太差:UUID 不具有有序性,会导致 B+ 树索引在写的时候有过多的随机写操作(连续的 ID 可以产生部分顺序写),还有,由于在写的时候不能产生有顺序的 append 操作,而需要进行 insert 操作,导致频繁的进行页分裂,性能下降明显。

适合的场景:如果你是要随机生成个什么文件名、编号之类的,你可以用 UUID,但是作为InnoDB表的主键是不能用 UUID 的。

UUID.randomUUID().toString().replace(“-”, “”) -> sfsdf23423rr234sfdaf

系统当前时间戳+XXX

适合的场景:一般如果用这个方案,是将当前时间戳跟很多其他的业务字段拼接起来,作为一个 id,如果业务上你觉得可以接受,那么也是可以的。你可以将别的业务字段值跟当前时间拼接起来,组成一个全局唯一的编号。

Snowflake 算法

snowflake 算法是 twitter 开源的分布式 id 生成算法,采用 Scala 语言实现,是把一个 64 位的 long 型的 id,1 个 bit 是不用的,用其中的 41 bit 作为时间戳(毫秒数),用 10 bit 作为工作机器 id,12 bit 作为序列号。

  • 1 bit:不用,为啥呢?因为二进制里第一个 bit 为如果是 1,那么都是负数,但是我们生成的 id 都是正数,所以第一个 bit 统一都是 0。
  • 41 bit:表示的是时间戳,单位是毫秒。41 bit 可以表示的数字多达 2^41 - 1,也就是可以标识 2^41 - 1 个毫秒值,换算成年就是表示69年的时间。
  • 10 bit:记录工作机器 id,代表的是这个服务最多可以部署在 2^10台机器上哪,也就是1024台机器。但是 10 bit 里 5 个 bit 代表机房 id,5 个 bit 代表机器 id。意思就是最多代表 2^5个机房(32个机房),每个机房里可以代表 2^5 个机器(32台机器)。
  • 12 bit:这个是用来记录同一个毫秒内产生的不同 id,12 bit 可以代表的最大正整数是 2^12 - 1 = 4096,也就是说可以用这个 12 bit 代表的数字来区分同一个毫秒内的 4096 个不同的 id。
0 | 0001100 10100010 10111110 10001001 01011100 00 | 10001 | 1 1001 | 0000 00000000

到此这篇关于Mysql分库分表之后主键处理的几种方法的文章就介绍到这了,更多相关Mysql分库分表主键内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Mysql数据库分库分表全面瓦解

    目录 1 为什么要分库分表 2 垂直拆分(Scale Up 纵向扩展) 2.1 垂直分库 2.2 垂直分表 3 水平拆分(Scale Out 横向扩展) 3.1 库内分表 3.2 库内分表的实现策略 3.2.1 HASH(哈希) 3.2.2 RANGE(范围) 3.2.3 LIST(预定义列表) 3.2.4 KEY(键值) 3.2.5 Composite(复合模式) 3.3 分库分表 4 分库分表存在的问题 4.1 事务问题 4.2 跨库跨表的join问题 4.3 额外的数据管理负担和数据运算压

  • 浅谈MySQL中的自增主键用完了怎么办

    在面试中,大家应该经历过如下场景 面试官:"用过mysql吧,你们是用自增主键还是UUID?" 你:"用的是自增主键" 面试官:"为什么是自增主键?" 你:"因为采用自增主键,数据在物理结构上是顺序存储,性能最好,blabla-" 面试官:"那自增主键达到最大值了,用完了怎么办?" 你:"what,没复习啊!!"    (然后,你就可以回去等通知了!) 这个问题是一个粉丝给我提的,我觉得

  • MySQL中的主键以及设置其自增的用法教程

    1.声明主键的方法: 您可以在创建表的时候就为表加上主键,如: CREATE TABLE tbl_name ([字段描述省略...], PRIMARY KEY(index_col_name)); 也可以更新表结构时为表加上主键,如: ALTER TABLE tbl_name ADD PRIMARY KEY (index_col_name,-); /* 创建一个qq表,将qq_id设为主键,且没有对其进行NOT NULl约束 */ create table qq( qq_id int(10), n

  • MySQL常用分库分表方案汇总

    目录 一.数据库瓶颈 二.分库分表 2.水平分表 3.垂直分库 4.垂直分表 三.分库分表工具 四.分库分表步骤 五.分库分表问题 1.非partition key的查询问题 2.非partition key跨库跨表分页查询问题 3.扩容问题 六.分库分表总结 一.数据库瓶颈 不管是IO瓶颈,还是CPU瓶颈,最终都会导致数据库的活跃连接数增加,进而逼近甚至达到数据库可承载活跃连接数的阈值.在业务Service来看就是,可用数据库连接少甚至无连接可用.接下来就可以想象了吧(并发量.吞吐量.崩溃).

  • 浅谈订单重构之 MySQL 分库分表实战篇

    目录 一.目标 二.环境准备 1.基本信息 2.数据库环境准备 3.建库 & 导入分表 三.配置&实践 1.pom文件 2.常量配置 3.yml 配置 4.分库分表策略 5.dao层编写 6.单元测试 四.总结 一.目标 本文将完成如下目标: 分表数量: 256    分库数量: 4 以用户ID(user_id) 为数据库分片Key 最后测试订单创建,更新,删除, 单订单号查询,根据user_id查询列表操作. 架构图: 表结构如下: CREATE TABLE `order_XXX` (

  • MySQL中主键与rowid的使用陷阱总结

    前言 大家在MySQL中我们可能听到过rowid的概念,但是却很难去测试实践,不可避免会有一些疑惑,比如: 如何感受到rowid的存在: rowid和主键有什么关联关系: 在主键的使用中存在哪些隐患: 如何来理解rowid的潜在瓶颈并调试验证. 本文要和大家一起讨论这几个问题,测试的环境基于MySQL 5.7.19版本. 问题1.如何感受到rowid的存在 我们不妨通过一个案例来进行说明. 记得有一天统计备份数据的时候,写了一条SQL,当看到执行结果时才发现SQL语句没有写完整,在完成统计工作之

  • 快速理解MySQL中主键与外键的实例教程

    主键与外键的关系,通俗点儿讲,我现在有一个论坛,有两张表,一张是主贴 thread,一张是回帖 reply 先说说主键,主键是表里面唯一识别记录的字段,一般是帖子id,体现在访问的时候,例如是 thread.php?id=1   表示我要访问的是帖子id是1 的帖子- 再来说说外键,当我们删除某个帖子的时候,需要执行另一个操作,就是删除所有回帖,如果正常情况下,我们需要执行两次delete操作(thread和 reply),这时候如果存在外键,例如,在reply 表里面建立一个指向thread表

  • Mysql主键和唯一键的区别点总结

    什么是主键? 主键是表中唯一标识该表中每个元组(行)的列.主键对表实施完整性约束.表中只允许使用一个主键.主键不接受任何重复值和空值.表中的主键值很少更改,因此在选择主键是需要小心,要选择很少发生更改的地方.一个表的主键可以被另一个表的外键引用. 为了更好地理解主键,我们创建一个名为Student的表,它具有roll_number.name.batch.phone_number.citizen_id等属性. 在上面的示例中,roll_number属性永远不能具有相同的NULL值,因为在每个大学中

  • MySQL 创建主键,外键和复合主键的语句

    1.创建主键语法 ALTER TABLE table_name ADD CONSTRAINT pk_name PRIMARY KEY(列名); 2.创建外键语法 ALTER TABLE news_info[子表名] ADD CONSTRAINT FK_news_info_news_type[约束名] FOREIGN KEY (info_id)[子表列] REFERENCES news_type[主表名] (id)[主表列] ; 3.使用组合主键 如果一列不能唯一区分一个表里的记录时,可以考虑多个

  • MySQL分库分表详情

    一.业务场景介绍 假设目前有一个电商系统使用的是MySQL,要设计大数据量存储.高并发.高性能可扩展的方案,数据库中有用户表.用户会非常多,并且要实现高扩展性,你会怎么去设计? OK咱们先看传统的分库分表方式 当然还有些小伙伴知道按照省份/地区或一定的业务关系进行数据库拆分 OK,问题来了,如何保证合理的让数据存储在不同的库不同的表里呢?让库减少并发压力?应该怎么去制定分库分表的规则?不用急,这不就来了 二.水平分库分表方法 1.RANGE 第一种方法们可以指定一个数据范围来进行分表,例如从1~

  • mysql死锁和分库分表问题详解

    记录生产mysql的问题点. 业务场景与问题描述 请求一个外部接口时,每天的请求量在900万左右. 分为请求项目和回执这两个项目.请求是用来调用外部接口,回执是接收发送的接口. 在发送请求前会先插入数据库. 在请求后,如果接口返回调用失败,会更新数据库状态为失败. 如果发送成功,则会等待上游给出回执消息后,然后更新数据库状态. 而在生产运行过程中,半年出现过两次mysql导致的mq消费者堆积的问题. 问题分析 记录两次不同的原因导致的生产问题及原因分析. mysql死锁问题 查看mq聚合平台TP

随机推荐