数据库自增主键可能产生的问题-阿里云开发者社区

开发者社区> 邴越> 正文

数据库自增主键可能产生的问题

简介:
+关注继续查看

在MySQL中经常会配置自增长属性的字段作为主键,特别是使用InnoDB存储引擎,

因为InnoDB的聚集索引的特性,使用自增长属性的字段当主键性能更好,但是使用自增主键也可能会带来一些问题。
举个例子,使用自增主键对数据库做分库分表,可能出现一些诸如主键重复等的问题,或者在数据库导入的时候,可能会因为主键出现一些问题。

主要业务表的主键应该配置一个合理的策略,尽量避免自增AUTO_INCREMENT。

针对主键自增可能产生的问题,下面这两篇文章有相关的讨论:

INNODB自增主键的一些问题
mysql自增列导致主键重复问题分析

>>针对主键增长方式的解决方案

来自知乎问题-高并发网站如何解决数据库主键自增的时候出现重复?

(1)设置主键自增为何不可取
这样的话,数据库本身是单点,不可拆库,因为id会重复。

(2)依赖数据库自增机制达到全局ID唯一
使用如下语句:
REPLACE INTO Tickets64 (stub) VALUES ('a'); 
SELECT LAST_INSERT_ID();
这样可以保证全局ID唯一,但这个Tickets64表依旧是个单点。

(3)依赖数据库自增机制达到全局ID唯一并消除单点
在2的基础上,部署两个(多个)数据库实例,
设置自增步长为2(多个则为实例数),即auto-increment-increment = 2
设置auto-increment-offset分别为1,2.....
这样第一台数据库服务器的自增id为 1 3 5 7 9
第二台为2 4 6 8 10

(4)解决每次请求全局ID都读库写库压力过大的问题
比如第一次启动业务服务,会请求一个唯一id为3559
如果是2、3的方法,则id为3559,这样每次都请求数据库,对数据库压力比较大
可以用3559 * 65536(举个例子,并不一定是65536)+ 内存自增变量来作为id
当内存自增变量到达65535时,从数据库重新获取一个自增id
这样即使有多台业务服务器,id也不会重复:
第一台 3559 * 65536 + 1,2,3.....65535
第二台 3560 * 65536 + 1,2,3.....65535
然后第一台到65535了,换一个数据库自增id,这时候可能是3561 * 65536 + 1,2,3....

 


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
[20121020]主外键约束以及NULL问题.txt
[20121020]主外键约束以及NULL问题.txt 主外键约束可以一定程度保证数据完整性,但是如果外键输入的是NULL,情况会如何呢? SQL> select * from v$version ; BANNER -----------------------...
593 0
mysql 插入数据失败防止自增长主键增长的方法
mysql设置了自增长主键ID,插入失败的那个自增长ID也加一的,比如失败5个,下一个成功的不是在原来最后成功数据加1,而是直接变成加6了,失败次数一次就自动增长1了,能不能让失败的不增长的? 或者说mysql插入数据失败,怎么能防止主键增长? MYSQL不保证AUTO_INCREMENT依次增长(1,2,3,4,5),但是可以保证正向增长(1,3,5,9)所以,当你某次操作失败后,下次A
1729 0
.Net FrameWork 4.0中使用EF向数据库插入数据报datatime2类型错误的解决办法
最近用.Net 4.0创建EF的持久层,老是在插入新数据时,报datatime2类型错误。 找了很多资料,都没有得到解决,后来我询问了我的一个同事,Tom 给我解决了这个问题。   由于EF4默认把C#的DateTime类型转换成Sql server2008的datatime2类型,所以2005的数据库不支持,最终导致程序报错。
653 0
使用OpenApi弹性释放和设置云服务器ECS释放
云服务器ECS的一个重要特性就是按需创建资源。您可以在业务高峰期按需弹性的自定义规则进行资源创建,在完成业务计算的时候释放资源。本篇将提供几个Tips帮助您更加容易和自动化的完成云服务器的释放和弹性设置。
7716 0
excel文件内容导入数据库的问题及解决
今天需要导一些数据,从excel导入到数据库中。 没有装现成的plsqldev,只能用sql*loader来弄了。 首先我把excel文件的内容转换成csv文件,以逗号分隔,在另存外excel文件的时候有那个选项。
1093 0
+关注
邴越
关注分布式系统及高可用架构,探讨职业规划,实践持续学习,公众号「架构进化论」
251
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载