前言

领导:既然自增数字主键会导致主备同步时主键冲突,自增主键能不能砍掉?

答:自增主键主要是技术上提升效率,键冲突可以考虑备库插入时不指定主键值,或者binlog改成row模式,而且,

公司规范:如果表记录超过1万行,建议用自增数字当主键,类型用BIGINT UNSIGNED。

InnoDB结构B+树

要了解InnoDB必须先了解B+树

主键B+树

B+树特点

  • 有序
  • 多叉树
  • 叶子节点之间有引用,是一个链表
    • 可以有效处理范围数据,如下图查询1-7行,无需返回父节点,直接通过2-->3的引用查询即可。

定义Max. Degree = 4:节点达到4条记录就分裂,就是每个节点最多3条记录

图1

上图主键依次递增,现在在中间插入主键8

图2

页分裂:插入节点8,原节点超过3条记录,触发页分裂,同时父节点插入新增节点起始元素。当父节点超过3个元素,同样会触发分裂。

页合并:页分裂的逆过程,删除元素时可能触发。

为什么自增数字

为什么自增

  • 减少页分裂

    • 如果不是自增主键

      • 性能开销:为了维护索引的有序性,需要先查找到中间位置(如上图的主键8),分裂原来的(3,4,7)节点为(3,4)+(7,8)两个节点,需要挪动数据,然后改变节点间的引用,期间涉及到多个IO操作,高并发环境下影响性能。
      • 空间开销:又由于页分裂后每个页依然保持16KB,所以原本16KB的元素需要平分在两个页内,也就是说两个刚分裂的页会有接近50%冗余空间,如图2红框,本来3个元素的节点分裂成只有2个元素,而数据页依然是16KB,所以分裂后节点空间利用率直接减半。在数据量大且插入频繁的情况,会造成索引树存在大量碎片,占用磁盘空间。
    • 自增主键:直接在B+树最后节点添加元素/新增节点即可。

为什么数字

减少索引树节点大小

  • 因为是数字类型BIGINT UNSIGNED,占用空间相对较少,可以让每个节点尽量多放记录,减少页分裂。在同样多记录的前提下,B+树高度可以更小,每次查询都可以减少IO。
  • InnoDB页大小默认16K,每次从磁盘拿16K的数据,可以通过参数配置。
    • show variables like 'innodb_page_size'
  • 用大小(2KB VS 8B)的记录做索引,4层的B+树最多存多少条记录
    • 2KB索引:16KB的页只能放16/2=8条数据,4层树最多存放8^4=4096条数据
    • 8B BIGINT UNSIGNED索引:16KB的页可以放16000/2=2000条数据,4层树最多存放2000^4=16000000000000,相当于同样数量的记录,树高度可以更低,查询IO更少。
  • 非主键索引叶子指向主键,可以减少非主键索引树的空间占用

PS. BIGINT UNSIGNED范围:0-2^64-1。

什么时候不需用自增主键

  • 数据量小

    • 数据量很小,小到全表扫描效率比扫描索引树要高时,不适合建立索引,就更没有自增主键的必要了。
    • 数据量千级,索引树大小不大,对性能和空间影响都不会很大。
  • KV场景
    • 在全表只有一个唯一索引(Key-Value场景),且读多写少的前提下,应尽量避免查询时回表(搜索两颗索引树),这种情况可以考虑用业务字段做主键。

References

BIGINT 范围:https://dev.mysql.com/doc/refman/8.0/en/integer-types.html

自定义B+树动态图:https://www.cs.usfca.edu/~galles/visualization/BPlusTree.html

新增一个主键自增长_为什么InnoDB宜用自增主键相关推荐

  1. 新增一个主键自增长_第17期:索引设计(主键设计)

    表的主键指的针对一张表中的一列或者多列,其结果必须能标识表中每行记录的唯一性.InnoDB 表是索引组织表,主键既是数据也是索引.主键的设计原则1. 对空间占用要小上一篇我们介绍过 InnoDB 主键 ...

  2. mysql主键自增长_全面的MySQL优化面试解析

    本文概要 文章内图片有损,需要高清可以在公众号内回复"大图" 概述 为什么要优化 系统的吞吐量瓶颈往往出现在数据库的访问速度上 随着应用程序的运行,数据库的中的数据会越来越多,处理 ...

  3. mysql 主键自增_还再使用数据库自增主键吗?

    加油站: 在数字经济时代,数据的重要性堪比石油.大数据的四个特点:Volume(数据体量大).Variety(数据类型繁多).Velocity(处理速度快).Value(商业价值高),只要合理利用数据 ...

  4. mysql 主键删除数据库_【数据库】mysql如何删除主键?

    当一个表中设置了主键之后,如果想要删除主键了要怎么做?下面本篇文章就给大家介绍MySQL删除主键的方法,希望对你们有所帮助. 首先我们来看看删除主键的语法: ALTER TABLE TABLE_NAM ...

  5. 新增一个主键自增长_使用技巧之——MyBatis如何返回插入主键

    优点 mybatis是一种持久层框架,也属于ORM映射.前身是ibatis.相比于hibernatehibernate为全自动化,配置文件书写之后不需要书写sql语句,但是欠缺灵活,很多时候需要优化: ...

  6. mysql主键和聚簇索引_[MySQL] innoDB引擎的主键与聚簇索引

    mysql的innodb引擎本身存储的形式就必须是聚簇索引的形式 , 在磁盘上树状存储的 , 但是不一定是根据主键聚簇的 , 有三种情形: 1. 有主键的情况下 , 主键就是聚簇索引 2. 没有主键的 ...

  7. mysql聚簇索引 和主键的区别_[MySQL] innoDB引擎的主键与聚簇索引

    MysqL的innodb引擎本身存储的形式就必须是聚簇索引的形式,在磁盘上树状存储的,但是不一定是根据主键聚簇的,有三种情形: 1. 有主键的情况下,主键就是聚簇索引 2. 没有主键的情况下,第一个非 ...

  8. mysql即是主键又是外键怎么写_请问 sql 字段 可不可以 即是主键又是外键

    展开全部 可以,这说明这两张表的主键相关联,只是那张是主表(就是32313133353236313431303231363533e58685e5aeb931333433656133该表的主键作为从表的 ...

  9. python 定义字典键为变量_在python字典中使用变量作为键名

    我今天来是因为我有同样的问题.我必须说,我对这些答案很失望!我同意你的观点,这种冗余应该有一个惯用的解决方案.在这种情况下,JavaScript似乎比Python更明智.所以我想增加两个建议. 首先, ...

最新文章

  1. Swift 函数和类
  2. 嵌入式 linux restful,嵌入式 RESTful 框架 express.java
  3. ecshop 奇偶行显示不同的商品样式
  4. fortran和Java学_Fortran模块和全局变量
  5. 10.31NOIP模拟赛解题报告
  6. Java之Socket与HTTP区别
  7. 吴恩达作业10:用卷积神经网络识别人脸happy(基于Keras)
  8. 较真的来了!这篇【硬核论文】为何恺明新作MAE提供了一种理论解释和数学证明...
  9. Mobile game forensics
  10. python三次方函数_python函数基础------第三次作业讲解(二)
  11. Flex 学习笔记 ComboBox内容框宽度
  12. 实战Python:详解利用Python和Pygame实现飞机大战
  13. 信息安全工程师(软考资料)
  14. 手把手教你:人脸识别考勤系统
  15. 使用jquery实现图形点击文字按顺序验证码案例及代码完整版
  16. 【原理图专题】OrCAD Capture CIS中元件产生A,B属性解决办法
  17. 【3】计算机原理-显卡工作模型
  18. 一个屌丝程序猿的人生(一百一十五)
  19. 594. 最长和谐子序列
  20. python处理PDF-通过关键词定位-截取PDF中的图表

热门文章

  1. pandas使用drop_duplicates函数基于subset参数指定的数据列子集删除重复行、并设置keep参数保留重复行中的最后一个数据行
  2. R语言replace函数数值替换实战
  3. 什么是牛顿法(Newton methods)?什么是拟牛顿法(Quasi Newton methods)?牛顿法和梯度下降法的区别是什么?
  4. 机器学习数据清洗之缺失值处理、缺失的原因、缺失值删除、缺失值填充、KNN填充
  5. Keras训练神经网络进行分类并使用GridSearchCV进行参数寻优
  6. AutoML自动化机器学习技术深入
  7. 学习笔记:数据分析和处理(ML计算模型前的预处理)——持续更新
  8. 第4期 变异注解之旅
  9. igraph 算网络指标_量化投资中,计算技术指标时常见的8个坑
  10. python 导入自定义模块