MySQL的id生成策略
1 自增
CREATE TABLE `test` (
`id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
---------------------------------------------------------------------------------
问题1:单点问题,如果分表分库不能保证id唯一。
解决1:部署两个(多个)数据库实例,设置自增步长为2(多个则为实例数),即auto-increment-increment = 2,设置auto-increment-offset分别为1,2.....
这样第一台数据库服务器的自增id为 1 3 5 7 9,第二台为2 4 6 8 10。
---------------------------------------------------------------------------------
问题2:自增锁(AUTO_INC锁)。mysql5.1.22之前,当表里有一个auto_increment字段的时候,innoDB会在内存里保存一个计数器用来记录auto_increment的值,当插入一个新行数据时,就会用一个表锁来锁住这个计数器,直到插入结束。如果大量的并发插入,表锁会引起SQL堵塞。
解决1:id不使用自增,可以使用uuid等其他方式生成(后文详述)。
解决2:在mysql5.1.22之后,InnoDB为了解决自增主键锁表的问题,引入了参数innodb_autoinc_lock_mode,该实现方式是通过轻量级互斥量的增长机制完成的。用来在使用auto_increment的情况下调整锁策略。该参数可以设置三个值:0、1、2
0:traditonal 通过表锁的方式进行,所有类型的insert都用AUTO-inc locking。 1:consecutive 默认值,产生一个轻量锁,对于simple insert 自增长值的产生使用互斥量对内存中的计数器进行累加操作,对于bulk insert 则还是使用表锁的方式进行。 2:interleaved 对所有的insert-like 自增长值的产生使用互斥量机制完成,并发性能最高,并发插入可能导致自增值不连续,可能会导致Statement 的 Replication 出现不一致,使用该模式,需要用 Row Replication的模式。
2 UUID
点击uuid详情。
优点:没有自增锁的问题,也没有单点问题,实现简单。
问题:由于UUID非常的长,除占用大量存储空间外,最主要的问题是在索引上,在建立索引和基于索引进行查询时都存在性能问题。
3 自己维护一个Sequence表
CREATE TABLE `SEQUENCE` (
`table_name` varchar(18) NOT NULL,
`nextid` bigint(20) NOT NULL,
PRIMARY KEY (`table_name`)
) ENGINE=InnoDB
每当需要为某个表的新纪录生成ID时就从Sequence表中取出对应表的nextid,并将nextid的值加1后更新到数据库中以备下次使用。
优点:没有自增锁问题。
问题:由于所有插入任何都需要访问该表,该表很容易成为系统性能瓶颈,同时它也存在单点问题,一旦该表数据库失效,整个应用程序将无法工作。
解决:使用Master-Slave进行主从同步,但这也只能解决单点问题,并不能解决读写比为1:1的访问压力问题。
4 twitter的snowflake算法
介绍:分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。
有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移到Cassandra,因为Cassandra没有顺序ID生成机制,所以开发了这样一套全局唯一ID生成服务。
snowflake的结构如下(每部分用-分开):
0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
第一位为未使用,接下来的41位为毫秒级时间(41位的长度可以使用69年),然后是5位datacenterId和5位workerId(10位的长度最多支持部署1024个节点) ,最后12位是毫秒内的计数(12位的计数顺序号支持每个节点每毫秒产生4096个ID序号),一共加起来刚好64位,为一个Long型。(转换成字符串后长度最多19)。
snowflake生成的ID整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由datacenter和workerId作区分),并且效率较高。经测试snowflake每秒能够产生26万个ID。
参考:https://www.cnblogs.com/jshen/p/7682502.html
https://www.cnblogs.com/relucent/p/4955340.html
MySQL的id生成策略的更多相关文章
- hibernate(四)ID生成策略
一.ID生成策略配置 1.ID生成方式在xml中配置方式: <?xml version="1.0"?> <!DOCTYPE hibernate-mapping P ...
- Hibernate系列之ID生成策略
一.概述 hibernate中使用两种方式实现主键生成策略,分别是XML生成id和注解方式(@GeneratedValue),下面逐一进行总结. 二.XML配置方法 这种方式是在XX.hbm.xml文 ...
- Rhythmk 学习 Hibernate 03 - Hibernate 之 延时加载 以及 ID 生成策略
Hibernate 加载数据 有get,跟Load 1.懒加载: 使用session.load(type,id)获取对象,并不读取数据库,只有在使用返回对象值才正真去查询数据库. @Test publ ...
- JPA ID生成策略(转---)
尊重原创:http://tendyming.iteye.com/blog/2024985 JPA ID生成策略 @Table Table用来定义entity主表的name,catalog,schema ...
- [Hibernate开发之路](4)ID生成策略
一 对象关系数据库映射之Id 被映射的类必须定义相应数据库表主键字段.大多数类有一个JavaBeans风格的属性, 为每个实例包括唯一的标识. <id> 元素定义了该属性到数据库表主键字段 ...
- hibernate ID生成策略配置
1.Student.hbm.xml配置 <hibernate-mapping package="com.wxh.hibernate.model"> <class ...
- 分布式ID生成策略 · fossi
分布式环境下如何保证ID的不重复呢?一般我们可能会想到用UUID来实现嘛.但是UUID一般可以获取当前时间的毫秒数再加点随机数,但是在高并发下仍然可能重复.最重要的是,如果我要用这种UUID来生成分表 ...
- id生成策略 id工具类
import java.util.Random; /** * 各种id生成策略 * <p>Title: IDUtils</p> * <p>Description: ...
- 高并发环境下全局id生成策略
解决方案: 基于Redis的全局id生成策略:(推荐此方法) 基于雪花算法的全局id生成: https://www.cnblogs.com/kobe-qi/p/8761690.html 基于zooke ...
随机推荐
- 性能优化-FSL(Force Synchronous Layout)强制同步布局
通过chrome的Perfermance工具记录程序性能,切换到帧模式,点开其中一帧,看详情,中间为紫色的区块代表Layout,右上角带有红色三角的为警告,是chrome告知的强制同步布局,即FSL. ...
- 如何用js让表格的行也能拖动
行拖动的实现思路非常简单,选中一行,往上拖就与上面的行交换位置,往下拖就与下面的行交换位置.问题是如何得到交换行.我见过一个非常详细的教程,它会把表格里的每一行的高度与Y坐标计算出来,换言之,都时是比 ...
- java合并两个有序数组的算法(抛砖引玉)
前几天看见一道面试题中要将两个有序数组合并成一个新的有序数组,首先使用了嵌套循环,之后想那样效率太低,又想出了以下思路,和大家分享下,如果有更好的方法,请留言指教: 思路: 1.新建一个数组大小为fi ...
- POJ1386 Play on Words
Time Limit: 1000MS Memory Limit: 10000KB 64bit IO Format: %I64d & %I64u Description Some of ...
- roadhogrc.mock.js配置
1.roadhogrc.mock.js const fs=require('fs'); const path=require('path'); const mockPath=path.join(__d ...
- FIRST SCRAPY PRJ
zpc@Lenovo-PC:/prj/pyscrapy/a$ scrapy startproject helloword New Scrapy project 'helloword' created ...
- Android BroadcastReceiver使用
1. 介绍 BroadcastReceiver用于接收广播事件(Intent), 是Android四大组件之一 2. 使用 2.1 实现广播接收类 实现一个广播收类继承BroadcastReceiv ...
- 报告撰写,linux使用gimp简单做gif动图
我想把我的系统菜单完整记录下来,方便查看,如果单纯使用文字比较单调,使用屏幕截图,需要依次打开多个图像查看也不是很方便,就想到了使用动画的形式展示.由于本人的系统一直使用Linux系统,为了一张gif ...
- 2.OpenStack-安装消息队列服务
安装消息队列服务(安装在控制器上) yum install rabbitmq-server -y systemctl start mariadb.service 配置消息队列服务 systemctl ...
- jQuery实现日期字符串格式化
1. js仿后台的字符串的StringFormat方法 function StringFormat() { if (arguments.length == 0) return null; var st ...