首页 > 数据库 >MySQL主键的一些思考

MySQL主键的一些思考

时间:2023-03-30 22:11:42浏览次数:38  
标签:自增 数据库 ID 思考 MySQL 主键 id

MySQL创建表的时候可以不设置主键吗?
MySQL创建表的时候是可以不主动设置主键的,但是表是一定需要一个主键的,MySQL会主动将第一个不为null的唯一索引设置为主键

为什么MySQL推荐使用自增id作为主键?
MySQL官方推荐不要使用uuid或者不连续不重复的雪花作为主键,而是使用连续自增的主键id
使用自增id的内部结构
自增id的值是顺序的,所以innodb在索引B+树的叶子节点层面可以直接把每一条记录都存储在上一条记录的后面,当达到页面的最大填充因子的时候(页面容量已经满了)下一条记录就会写入新的页中,数据按照这种顺序的方式进行填充,主键页就会以近乎于顺序的记录填满,提升了页面的最大填充率,不会有页的浪费
新插入的行一定会在原有的最大数据的下一行,这样MySQL定位和寻址非常快,不会因为计算而做出额外的消耗,
并且能够减少页分裂和碎片的产生
页分裂:保证后一个数据页的所有行主键值比前一个数据页的主键值大,所以当ID不为自增的主键的时候,就会导致后一个页的所有行并不一定比前一个数据页的行的id大。这时就会触发页分裂的逻辑,对两个页之间的数据进行调整,底层就是树结构的调整,这个消耗是很大的,甚至会涉及到多个数据页,导致性能降低
使用自增id的缺点
1. 别人一旦爬取你的数据库,就可以根据数据库的自增id获取到你业务的增长信息,从而分析出经营情况
2. 对于高并发的负载,innodb在按照主键进行插入的时候会造成明显的锁争用,auto_increment锁机制会造成自增锁的争夺,有一定的性能损失
为什么分布式系统不用自增id,而是要用雪花算法生成id
分布式id创建的业务需求
1. 全局唯一
2. 趋势递增 innodb引擎的叶子结点是有序的双向链表,趋势递增可以增加性能,不会打乱树的结构
3. 信息安全
4. 最好包含时间戳
为什么自增id不适合分布式系统?
当数据庞大的时候,在数据库分库分表之后,数据库自增id不能满足唯一id来表示数据;因为每个表都按照自己的节奏自增,会造成id冲突,从而无法满足需求
使用auto_increment实现廉价的分布式唯一主键
flickr有类似的方案,构建是一个专用的数据库服务器,上面只有一个数据库,在数据库里面有用于32位id和64位id的id表,id是auto自增的,所有数据库生成id都会向这个服务器发请求,然后服务器分发id下去,也能达到一种分布式唯一主键的效果
类似于session-redis的思想,把所有的sessionid都存在redis里面,所有的服务器实例在比较cookie的时候就先去redis里面比较,这样就能避免因为负载均衡导致的cookie失效问题
当然这个廉价的做法显然是有很大问题的
1. 并发量很小,因为只有一台服务器
2. 增加开销,并且整个请求流程变慢,因为需要向服务器发请求,并且是在硬盘层面进行操作的
3. flickr服务器成了整个系统的瓶颈和隐患,如果服务器宕机整个系统直接崩掉了
雪花算法
是twitter开源的分布式id生成算法,结果是一个64位的longint类型,核心思想是用41位来作为时间戳,10位来作为机器的id,12位作为毫秒内的流水号(意味着每个节点可以在每毫秒生成4096个id),最后还有一个符号为永远为0
优点
● 完全在内存生成,高性能高可用
● 容量大,每秒可以生成几百万id
● 趋势递增,插入数据库索引树的时候,性能比较高
缺点
● 依赖系统时钟的一致性,如果某台机器的系统时钟回拨,有可能造成id冲突
● 多台机器的ID只能保证趋势增加,即每一台机器都能保证这台机器生成的ID是在增加的,但是多台机器并不一定绝对递增
● 41位时间戳只能保证69年无重复ID
● 因为是64位的ID,在传递给前端的时候需要用字符串的类型进行传递,因为js的number类型最大只支持53位
其他分布式ID方案
● UUID:JAVA自带的API,生成一个唯一性的字符串,不能保证有序递增
● UidGenerator:百度开源的分布式ID生成器,基于雪花算法
● Leaf:美团开源的分布式ID生成器,能保证全局唯一,趋势递增,但是需要依赖关系数据库、Zookeeper等中间件

标签:自增,数据库,ID,思考,MySQL,主键,id
From: https://www.cnblogs.com/bokeofcxs/p/17274527.html

相关文章

  • MySQL
    1.mysql安装连接1.1安装mysql5.71、解压2、把这个包放到自己的电脑环境目录下3、配置环境变量4、新建mysql配置文件ini[mysq1d]#目录一定要换成自己的basedir=D:\Environmentmysq1-5.7.19\datadir=D:\Environment\mysq1-5.7.19\data\port=3306skip-grant-tables5、启......
  • Mysql 事务隔离机制、锁机制、MVCC多版本并发控制隔离机制、日志机制、
    原子性(Atomicity)当前事务的操作要么同时成功,要么同时失败。原子性由undolog日志来实现。一致性(Consistency):使用事务的最终目的,由其它3个特性以及业务代码正确逻辑来实现。隔离性(lsolation):在事务并发执行时,他们内部的操作不能互相干扰,隔离性由MySQL的各种锁以及MVC......
  • 实战SQL优化(以MySQL深分页为例)
    1准备表结构CREATETABLE`student`(`id`intNOTNULLAUTO_INCREMENT,`user_no`varchar(50)CHARACTERSETutf8mb4COLLATEutf8mb4_0900_ai_ciNULLDEFAULTNULL,`user_name`varchar(50)CHARACTERSETutf8mb4COLLATEutf8mb4_0900_ai_ciNULLDEFAULTNULL......
  • MySQL常用命令
    常用命令:https://blog.csdn.net/qq_38328378/article/details/80858073最详细的:https://blog.csdn.net/qq_34115899/article/details/81190461......
  • MySQL数据库怎么创建表?MySQL数据库基础知识
    MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,目前属于Oracle旗下产品。MySQL最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(RelationalDatabaseManagementSystem,关系数据库管理系统)应用软件之一。MySQL是一种关联数据库管理系统,关联数据库......
  • 22、MySQL主从复制详解及配置
    主从复制的介绍MySQL主从复制是指将一个MySQL服务器的数据复制到其他MySQL服务器上的过程。在主从复制中,一个MySQL服务器(称为“主服务器”或“主节点”)充当源,另一个或多个MySQL服务器(称为“从服务器”或“从节点”)充当目标。主服务器将更新和更改记录到二进制日志(binaryl......
  • MySQL、Redis和Elasticsearch比较
    MySQL是一种关系型数据库管理系统,它被广泛用于存储结构化数据。拥有极高的可靠性和安全性,支持ACID事务,并具有良好的扩展性,可以适应高并发访问的场景。Redis是一种内存......
  • MySql基本的简单sql语句
    SQL语句分类必须记住删除语句DELETEFROM表名WHERE条件插入语句简单的插入语句INSERTINTO表名(字段列表)VALUES(值列表)查询出的数据插入到已存在的表中查询出的数......
  • MySQL导入数据库1118错误解决方案[ERR] 1118 - Row size too large (> 8126). Changing
    MySQL导入数据库1118错误解决方案[ERR]1118-Rowsizetoolarge(>8126).ChangingsomecolumnstoTEXTorBLOB编辑sql文件,在开头设置一下innodb_strict_mode为0SE......
  • 拒绝“爆雷”!GaussDB(for MySQL)新上线了这个功能
    摘要:智能把控大数据量查询,防患系统奔溃于未然。本文分享自华为云社区《拒绝“爆雷”!GaussDB(forMySQL)新上线了这个功能》,作者:GaussDB数据库。什么是最大读取行一直以来,大......