数据库主键分案-编程思维

一.数据库自带的自增主键

  在传统单体数据库中,并且并发量不高的情况下,可以使用数据库自带的自增主键。但是它不能保持连续递增,只保证单调递增,也就是说自增主键值可能是:1,2,3,5 没有自增主键值4,这可能是因为事务回滚。

  优点:

    简单,代码方便,性能可以接受。数字ID天然排序,对分页或者需要排序的结果很有帮助。

  缺点:

    分布式数据库的分库分表的时候会有麻烦,假设有两台mysql节点,主键自增值节点1是:1 3 5,节点2是:  2,4,6。但确定好集群节点后,难于扩展。

    单体数据库在高并发场景下,每个事务都要去申请主键,数据库如果无法及时处理,自增主键就会成为瓶颈,此时自增主键已经不能解决问题了,往往需要在应用系统上做些优化。

 

二.Reids生成全局ID

  因为Redis是单线的,天生保证原子性,可以使用Redis的原子操作 INCR和INCRBY来实现。对于高并发获取redis的自增ID,可以使用list列表结构来实现队列存储,比如一次生成10w(1,2,3..,100000)个id值存储到list,新增每次需要自增id时,取队列一个。用完了队列中的自增ID,再一次生成100001~200000个。

  优点:

    不依赖于数据库,灵活方便,且性能优于数据库。数字ID天然排序,对分页或者需要排序的结果很有帮助。如果是订单号生成,可以采用日期+自增ID。
  缺点:

    需要编码和配置的工作量比较大,需要联网保证redis可用。

  注意:

    使用自增问题可能带来“尾部热点”,因为在分布式数据库中,都使用了分片,如果是自增,那写入的数据往往集中在一个节点的range范围内,其它节点空闲着。

    如果使用Hash分片,写入的数据会被分散到多个range中。主流产品的默认方案是保持 Range 分片,放弃自增主键,转而用随机主键来代替。

    随机主键方案如:UUID,内置Radom ID,外置雪花算法。

  如果是使用mycat的代理服务器,内置Radom ID。

  

三.UUID

  优点:

    简单,代码方便, 生成ID性能非常好,基本不会有性能问题,全球唯一,对分布式数据库或者在遇见数据迁移,系统数据合并,或者数据库变更等情况下,可以从容应对。
  缺点:

    没有排序,无法保证趋势递增,UUID使用字符串存储,查询的效率比较低,存储空间比较大,写入影响性能(因为要维护索引),如果是海量数据库,就需要考虑存储量的问题,传输数据量大。键值长度过长,达到了 128 位,因此存储和计算的代价都会增加。

    uuid做主键不具备业务意义。

     其它:

  Guid.NewGuid().ToString()=> 36个字符(带连字符的)
  输出:12345678-1234-1234-1234-123456789abc

  Guid.NewGuid().ToString("N")=> 32个字符(仅数字)
  输出:12345678123412341234123456789abc

  为了支持排序功能,表中添一个创建时间字段。

 

四、基于时间戳+随机数方式来生成唯一ID

  基于时间戳:DateTime.Now.ToString("yyyyMMddHHmmssfffffff")—这种情况很容易出现重复的编号。
  基于时间戳+随机数:DateTime.Now.ToString("yyyyMMddHHmmssfffffff")+Random随机数。
  这种方式比较适合针对单体应用并发不高的业务系统,生成方式并不是严格意义上的唯一ID。

   

五.雪花算法

  Twitter的snowflake(雪花)算法,跟UUID一样不用联网。snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:
  高位随机+毫秒数+机器码(数据中心+机器id)+10位的流水号码。

  优点:

    可以用snowflake来代替UUID,弥补 UUID 存在的不足,因为它不仅算法简单易实现,也满足 ID 所需要的全局唯一性,单调递增性,还包含一定的业务上的意义。

  缺点:

    最大的缺点就是它依赖于系统的时间戳,一旦系统时间不准,就有可能生成重复的 ID。所以如果我们发现系统时钟不准,就可以让发号器暂时拒绝发号,直到时钟准确为止。

  实现方案:

    1)嵌入到业务代码里,也就是分布在业务服务器中

      这种方案的好处是业务代码在使用的时候不需要跨网络调用,性能上会好一些。但是就需要更多的机器 ID 位数来支持更多的业务服务器。另外,由于业务服务器的数量很多,我们很难保证机器 ID 的唯一性,所以就需要引入 ZooKeeper 等分布式一致性组件来保证每次机器重启时都能获得唯一的机器 ID。

    2)作为独立的发号器服务部署

      业务在使用发号器的时候就需要多一次的网络调用,但是内网的调用对于性能的损耗有限,却可以减少机器 ID 的位数,如果发号器以主备方式部署,同时运行的只有一个发号器,那么机器 ID 可以省略,这样可以留更多的位数给最后的自增信息位。即使需要机器 ID,因为发号器部署实例数有限,那么就可以把机器 ID 写在发号器的配置文件里,这样即可以保证机器 ID 唯一性,也无需引入第三方组件了。

      微博和美图都是使用独立服务的方式来部署发号器的,性能上单实例单 CPU 可以达到两万每秒。

  Github地址: https://github.com/twitter-archive/snowflake

  snowflake生产的ID是一个18位的long型数字。转换为字符串长度为18位.

 https://github.com/RobThree/IdGen .net 使用

   

 

版权声明:本文版权归作者所有,遵循 CC 4.0 BY-SA 许可协议, 转载请注明原文链接
https://www.cnblogs.com/MrHSR/p/15248591.html

centos7源码编译安装mysql8 -编程思维

Centos7源码编译安装mysql8    前面介绍了很多关于mysql的文章,下面主要介绍一下mysql8的源码编译安装 一、基本环境 [root@CentOS-7-x86-64-Minimal-1810 ~]# cd /usr/local/src/ [root@CentOS-7-x86-64-Minimal-1

mariadb 公司正式在纽交所上市-编程思维

MariaDB 公司正式在纽交所上市 来源: OSCHINA 编辑: 局 2022-12-22 15:54:45  9 今年 2 月,开源数据库 MariaDB 公司完成了 1.04 亿美元的 D 轮融资,并表示计划在 Angel Pond 公司的帮助下成为一家上市公司。 12 月 19 日,Mari

仿文:普通人或者门外汉该怎样入门编程?-编程思维

继我关注很久一位编程的大牛发布了他的那篇文章—— <探究:普通人都是怎么入门编程> https://www.cnblogs.com/liuyangfirst/p/16991386.html 我先去再相关评论里看到了有人说这是AI写的一样,不过我对这篇文章的作者稍微有些了解,可能就是他写的,因为有时候你看不透

mysql 读写分离有哪些坑-编程思维

  在上一篇文章中,我和你介绍了一主多从的结构以及切换流程。今天我们就继续聊聊一主多从架构的应用场景:读写分离,以及怎么处理主备延迟导致的读写分离问题。我们在上一篇文章中提到的一主多从的结构,其实就是读写分离的基本结构了。这里,我再把这张图贴过来,方便你理解。 图 1 读写分离基本结构     读写分离的主

mysql 5.7 并行复制实现原理与调优【转】-编程思维

MySQL 5.7并行复制时代 众所周知,MySQL的复制延迟是一直被诟病的问题之一,然而在Inside君之前的两篇博客中(1,2)中都已经提到了MySQL 5.7版本已经支持“真正”的并行复制功能,官方称为为enhanced multi-threaded slave(简称MTS),因此复制延迟问题已经得到了极大的改进

mysql 5.7 和 8.0 几处细节上的差异【转】-编程思维

MySQL 8.0 相对于 MySQL 5.7,有很多新特性,比如:快速加列、原子 DDL、不可见索引、额外端口、角色管理等。这一节内容,就不讲这些新特性了,只来聊聊最近在工作学习过程中遇到的几处细节上的差异。 1 int 字段类型的差异 比如下面的建表语句,在 5.7 能正常执行: CREATE TABLE `t1`