Innodb引擎的表上更换主键会发生什么

MYSQL-INNODB索引构成详解 对于MYSQL的INNODB存储引擎的索引,大家是不陌生的,都能想到是 B+树结构,可以加速SQL查询。但对于B+树索引,它到底“长”得什么样子,它具体如何由一个个字节构成的,这些的基础知识鲜有人深究。本篇文章从MYSQL行记录开始说起,层层递进,包括数据页,B+树聚簇索引,B+树二级索引,最后在文章末尾给出MYSQL索引的建议。文章涉及较多基础知识,内容较为枯燥,因此采用较多的图片补充说明,希望能对读者有帮助。 阅读详情

数据库的问题,如果不去深入思考,可能还真的只是一知半解,以前用Oracle的时候,也是经过几年不断地去探究其内部实现的原理,才真正明白了在Oracle数据库上做某个操作或者做某个配置的合理的方法。现在又到了国产数据库和开源数据库当道的时代了,我们不仅仅需要去研究一个Oracle数据库而是要去研究数个甚至数十个数据库了,这对于DBA来说是一件十分悲哀的事情。想起当年Poder说过的我这辈子只要干好Oracle数据库优化一件事就可以了,不知道这种数据库群雄并起的时代,对我们DBA来说是好事还是坏事了。

天底下的事情就怕较真,昨天一个客户咨询如果在一个MYSQL数据库上更换PRIMARY KEY,会发生什么?所有的索引都必须重建吗?这个问题似乎答案很简单,对于普通的堆表来说,主键更换不会影响其他索引,而对于Mysql innodb这样的BTREE表来说,所有的Secondary index里存储的不是数据行的物理地址,而是主键的键值,那么一旦主键更换了,那么所有的Secondary index就都必须重建了。不过这似乎太不合理了,真的会发生这样的事情吗?如果我们的表上面有好多个Secondary index,而且表的数据量很大,这样的操作似乎太消耗资源了?Innodb会不会采取更为巧妙的方法来处理这个问题呢?从一个架构师的角度,我首先就拒绝这样的设计,如果真的是这样,Innodb更换主键的成本就太高了。

innodb是采用BTREE存储结构的。因此在一张表的数据中分为两个段,一个段是主键索引段,被称为cluster primary key,一个段是数据段。

七月份的时候我发过一篇文章,讨论了BTREE结构表的一些基本结构,实际上MYSQL、达梦等数据库都使用了这种结构。采用这种存储结构的数据库有两个特点:首先,表中以主键值的顺序物理存储行。这意味着主键不仅唯一标识一行,而且还是它的一部分。或者更确切地说,物理行是表主键的一部分;其次,二级索引条目不指向实际的行位置,每个二级索引条目中存储的都是主键的值。当查询通过二级索引读取一行时,这个值被主键用于额外的隐式查找,以定位实际的行。

基于这样的底层存储结构,在设计MYSQL表的主键的时候,也有许多优化的原则,比如说,主键的键值尽可能地短,从而提高主键地效率。另外一点是选择主键的时候,尽可能选择增长趋势的字段作为主键(比如自增字段),因为innodb的行是按照主键的顺序插入的,采用自增的主键,有助于减少大量数据插入时的碎片产生,避免不必要的PAGE分裂,从而提高高并发插入的性能。当然你的数据库的负载没有那么大的时候,这些也不会成为一个主要的问题。

实际上,对于用惯了Oracle数据库的认,我们很可能在使用MySQL数据库上犯下错误。对于大量做范围扫描的应用来说,大家可能已经忘记了索引的一个重要的属性,cluster factor,一条索引的cluster factor越大,则做范围扫描的成本越高。对于Oracle这样的HEAP存储结构的数据库来说,插入数据是是有一定的随机性的,不过总体来说还是顺序添加为主。因此如果一个索引的扫描是和数据插入的性状相类似的时候,索引的cluster factor会比较小,扫描的总体成本会比较小。而对于BTREE存储结构的表,其行存储的位置和主键索引有关,因此如果MYSQL的索引也按照ORACLE那样去计算一个CLUSTER FACTOR的话,针对于范围扫描,其性能特征会和Oracle不同。当然,随着现在硬件的发展,存储性能的提升,CPU处理能力的巨大提升,这点系统开销往往可以被我们忽略,不过对于一些高并发,高负载,超大数据量的环节,MYSQL的这个特性的差异还是需要被我们重视。我们如果采用类似Oracle优化CLUSTER FACTOR的方法来优化数据存储,是不会获得和ORACLE一样的优化效果的。关于Oracle的CLUSTER FACTOR问题,我以前在《DBA的思想天空》这本书中讨论过,有兴趣的朋友可以去翻看。

前面谈了一些似乎和今天的话题不相干的问题,我们还是回到问题本身,那就是在INNODB上更换主键,会发生什么?

实际上我们潜意识里的想法就是正确的答案,刚开始我对更换主键的想法是有点想多了。实际上,当我们在MYSQL上创建一张表的时候,如果没有指定主键,则INNODB引擎会自动在表中找到非空唯一性的字段,在上面创建一个主键索引作为CLUSTER PRIMARY KEY。如果找不到,则会创建一个6字节的自增量,用这个自增量来创建CLUSTER PRIMARY KEY,这是因为INNODB的表上必须要有一个索引段。Secondary Index中的所有索引项都要指向这个索引段。有兴趣的朋友可以做个实验,创建一张无法选出主键的表的时候,我们会发现这张表上回自动产生一个GEN_CLUSTER_INDEX的UNIQUE索引,作为该表的主键。当我们在表上添加一个主键后,这个索引就会被删除,用新的主键字段创建一个新的unique索引来替代。当当我们修改INNODB表上的主键时,老的主键和UNIQUE索引会被删除,新的索引会被创建。根据INNODB的SECONDARY INDEX的设计原理,那么在主键更换的时候,二级索引是必须重建的。这也导致了在INNODB上更换主键是一个十分高开销的操作。

最后要说的一点是,如果你真的要在INNODB上更换主键,先删除老的主键,后创建新的主键是一种不可取的操作,因为删除老主键的时候,主键索引被删除,GEN_CLUSTER_INDEX会被创建,所有的二级索引会被重建。添加新主键的时候,GEN_CLUSTER_INDEX会被删除,主键索引会被创建,二级索引要再次重建。正确的做法是:ALTER TABLE DROP PRIMARY KEY ,ADD PRIMARY KEY TEST_TABLE(TEST_COL)。

明白了上面的原理,那么当我们在修改主键的时候,遇到#1878 - Temporary file write failure.这样的问题也不会一头雾水了,你知道MYSQL在干什么。

虽然讲了这么多,似乎在这方面MYSQL的设计不是很合理,是的,不合理,不过这是权衡多种因素的结果,这种不合理是为了其他方面更为合理,因为修改主键在实际已上线的生产系统中应该是个小概率事件。我们既然要用MYSQL,就应该对此早有准备,在设计数据表的时候就认真考虑好主键的问题。

【实验】Linux下完全卸载oracle单实例(亲身体验完整版) 停止oracle数据库服务 停止监听 卸载数据库实例 因为自己懒得再弄dbca图形化界面啥的,直接采用dbca静默删除数据库实例,命令如下 dbca -silent -deleteDatabase -sourcedb orclhq -sid orcl -sysDBAUserName orcl -sysDBAPassword zte [oracle@slave ~]$ dbca -silent ... 阅读详情

相关推荐

centos7下100T存储扩容(LVM)至150T

查看新增磁盘情况lsblk,fdisk -l [root@localhost ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 4.2G 0 rom vda 252:0 0 80G 0 disk ├─vda1 252:1 0 1G 0 part /boot └─vda2 252:2

tiyager的博客 1025

完整表修改主键的问题

--第一如果主键在已有列中建立  默认插入的第一个索引是0--如果主键是自增的那么默认插入的第一个索引是1--如果有索引值有0自增主键会将其置换为1--如果此时已经有1那就会报错--如果没有不合适的键那么就会总最后递增--如果有1个NULL值此时设置为主键会将NULL置换为0,实际上是nut noll 将其置换为0的--DUPLICATE entry '0' FOR KEY 'PRIMARY'  ...

不以人人的意志为转义乃天道 352

ArcGIS数据处理必备技能:从地理坐标到UTM投影的面转栅格完整流程

本文详细介绍了在ArcGIS中从地理坐标到UTM投影的面转栅格完整流程,包括坐标系转换、像元大小设置及质量控制等关键步骤。通过实战案例和Python脚本示例,帮助用户解决常见问题并优化数据处理效率,特别适合需要精确GIS数据分析的专业人士。

weixin_42628688的博客 180

【MySQL】索引

学习于极客时间 哈希索引 哈希索引做区间查询是很慢的,哈希表适用于只有等值查询的场景,比如 Memcached 及其他一些 NoSQL 引擎。 有序数组索引 有序数组在等值查询和范围查询场景中的性能就都很好。 如果仅仅看查询效率,有序数组就是最好的数据结构了。但是,在需要更新数据的时候就麻烦了,你往中间插入一个记录就必须得挪动后面所有的记录,成本太高。 有序数组索引只适用于静态存储引擎,比如你要保存的是省市这类几乎不会再修改的数据。 二叉树索引 二叉树为了维持 O(log(N)) 的查询复杂

keeper42的博客 1444

用C#语言实现记事本

本次程序设计作业为用C#语言设计一个记事本,设计的记事本应与电脑系统自带的记事本类似,最后实现的界面及功能应类似于下图。

qq_57738695的博客 2847

OpenMythos深度解析

本文深入解析了kyegomez/OpenMythos项目如何从第一性原理重建Claude Mythos的核心架构。该项目并非直接复制Claude,而是基于公开论文和实验结果推测其可能的设计理念,构建了包含多模态注意力、深度推理引擎、知识检索模块等六大核心组件的模块化架构。重点剖析了分组查询注意力(GQA)的实现细节,展示了KV头扩展等关键技术。该项目已成为大模型开源社区最受关注的研究之一,为理解Claude的架构思想提供了有价值的参考。

Crown_22的博客 518

为什么推荐InnoDB引擎使用自增主键?

原文地址:http://www.ywnds.com/?p=8735 在使用InnoDB存储引擎时,如果没有特别的需要,请永远使用一个与业务无关的自增字段作为主键,除非高并发写入操作可能需要衡量自增主键,后面会讲。 经常看到有帖子或博客讨论主键选择问题,有人建议使用业务无关的自增主键,有人觉得没有必要,完全可以使用如学号或身份证号这种唯一字段作为主键。不论支持哪种论点,大多数论据都是业务

奋斗、 9467

突破Cloudflare 5秒盾!Python爬虫+GPT分析JS混淆实战(附完整代码)

这篇文章的核心观点其实不是“怎么过CF”,而是如何把LLM嵌入逆向工程的工作流。AI不会取代逆向工程师,但它正在重新定义逆向工程师的工作方式。过去我们80%的时间花在读懂混淆代码上,现在这部分可以外包给GPT,我们把精力集中在架构判断、异常处理和系统设计这些真正需要人类直觉的地方。技术会变,CF的防护会升级,GPT的能力也会迭代。但这种“人机协作拆解复杂问题”的方法论,比任何具体的绕过技巧都更有长期价值。参考资料Cloudflare Bot Management官方文档。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 535

mysql 修改主键

ALTER TABLE `test2` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `id` ) 重设主键字段 有时数据库操作时需要将一个主键修改为联合主键或者把主键改为其他列,这时候单纯的add primary key是没有用的,必须先删除主键约束再重新添加。 MYSQL: 1、alter table TABNAME drop primary key; 2、...

影密卫 1万+

AUTOSAR进阶图解==>AUTOSAR_SWS_DefaultErrorTracer

AUTOSAR Default Error Tracer (DET)是AUTOSAR架构中的核心错误追踪模块,提供统一的错误报告机制。DET能够处理开发错误、运行时错误和瞬态故障三类问题,支持模块级和实例级的配置管理。模块架构上,DET通过Det_API接口与其他模块交互,可配置转发错误至诊断事件管理器(DEM)或调试日志追踪(DLT)。其配置结构包含全局参数和模块实例参数,允许灵活控制错误报告行为。DET在AUTOSAR 4.3.0版本中从DevelopmentErrorTracer扩展而来,增强了错误处

一名留德华的,康德的信徒的,专注于汽车电子领域的博客 909

华为OD机试双机位C卷-魔法收积木 (C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【魔法收积木】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为od - 魔法收积木。

qq_45776114的博客 1940

MYSQL:更换主键需要注意的事项

最近在使用主键时,有部分疑惑,所以特意查了一下资料,去了解这些内容。

учёба 1113

解决Jupyter Notebook中Plotly图表显示问题

摘要:在Jupyter Notebook中使用Plotly绘图时遇到图表无法显示的问题。通过分析发现Python 3.12版本与Jupyter存在兼容性问题。解决方案是将Python降级到3.11版本,重新创建虚拟环境后图表正常显示。这表明版本兼容性对数据可视化工具至关重要,环境配置检查是解决问题的关键步骤。该案例为遇到类似问题的开发者提供了参考方案。

m0_74337424的博客 124

Mysql数据库引擎MYISAM和INNODB详解

一、数据库引擎   数据库引擎是用于存储、处理和保护数据的核心服务。利用数据库引擎可控制访问权限并快速处理事务,从而满足企业内大多数需要处理大量数据的应用程序的要求。 使用数据库引擎创建用于联机事务处理或联机分析处理数据的关系数据库。这包括创建用于存储数据的表和用于查看、管理和保护数据安全的数据库对象(如索引、视图和存储过程)。 二、数据库引擎任务   在数据库引擎文档中,各主题的顺序遵循用...

m493096871的博客 1022

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【总结】InnoDB存储引擎

该文章为知识总结的文章,如果是初学者,建议先从专栏学习:数据库专栏 文章目录一、InnoDB存储引擎工作方式二、关键特性1. 插入缓存2. 两次写3. 自适应哈希索引三、redo log、binlog和undo log1. 什么是redo log?2. 什么是binlog?3. redo log和binlog区别4. 回滚日志(undo log)5. redo log和undo log的区别6. 一条更新语句执行的顺序 一、InnoDB存储引擎工作方式 将数据库文件按页(每页16k)读取到缓冲池,然后.

xzzz2020的博客 291

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

为什么 MySQL 需要“回表”?

使用MySQL的你一定听过“回表”。其对查询性能的影响成为普遍共识,但事实果真如此吗?网络上关于“回表”的分析与解决的文章非常多,绝大多数并未指明真正原因,只要使用MySQL就会有“回表”问题吗?

HAibiiin的博客 2257

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

mysql主键一定要有序吗_MySQL为什么需要主键

MySQL为什么需要主键主键表中每一行都应该有可以唯一标识自己的一列(或一组列)。一个顾客可以使用顾客编号列,而订单可以使用订单ID,雇员可以使用雇员ID或雇员社会保险号。主键一列(或一组列),其值能够唯一区分表中的每个行。唯一标识表中每行的这个列(或这组列)称为主键。没有主键,更新或删除表中特定行很困难,因为没有安全的方法保证只设计相关的行。表中的任何列都可以作为主键,只要它满足以下条件:任何两...

weixin_42571280的博客 1593

InnoDB 存储引擎

学习Mysql有一段时间了,对SQL语法、索引、查询优化做了一定的了解,但是总感觉浮于表面,所以想换一种角度去理解Mysql-它的存储实现引擎:InnoDB。InnoDB是Mysql5.5之后默认的存储引擎,本文也主要是参照Mysql5.6的官方手册。 一、存储引擎的作用是什么? 在深入讨论InnoDB前,想先讨论以下存储引擎的作用。数据库是我们用来组织和存储数据的工具,在Mysql系统的三层结构中,数据的组织和存储主要由存储引擎层实现。我们知道,Mysql的数据是存在磁盘中,数据的计算是在内存中,所以

weixin_41400063的博客 410

mysql update 事物锁表_详解mysql 锁表 for update (引擎/事务)

转自http://www.jbxue.com/db/13128.html由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表单给锁住)。例子:假设有个表单products ,里面有id跟name二个栏位,id是主键。例1: (明确指定主键,并且有此笔...

weixin_35757191的博客 561

详解mysql 锁表 for update (引擎/事务)

转自http://www.jbxue.com/db/13128.html 由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料表...

choukuad381324的博客 378

mysql 事务 myisam_Mysql事务以及InnoDB和MyISAM区别讲解

而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。MYSQL存储数据时,有不同的存储方式,这些方式都使用了不同的底层实现(如:存储机制,索引技巧,索引技巧,锁定水平),底层实现的差异带来的功能也就不同。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持以及外部键等高级数据库功能。我为什么要改默认引擎,其实原因很简单,我使用的Mysql默认引擎是MyISAM,而MyISAM并不支持事务处理,所以我需要更换它的引擎。

2401_84148518的博客 882

数据库引擎

一:数据库引擎的定义 数据库引擎简单来说就是一个"数据库发动机"。当你访问数据库时,不管是手工访问,还是程序访问,都不是直接读写数据库文件,而是 通过数据库引擎去访问数据库文件。以关系型数据库为例,你发SQL语句给数据库引擎, 数据库引擎解释SQL语句,提取出你需要的数据返回给你。因此,对访问者来说,数据库引擎就是SQL语句的解释器。   正式来说,数据库引擎是用于 存储、处理和保护...

dctCheng的博客 2760

mysql 主键id设置自增唯一 为什么还会重复出现

mysql 主键id设置自增唯一 为什么还会重复出现

happy10091812的博客 3992

mysql 锁表 for update_Mysql 锁表 for update (引擎/事务)

Mysql 锁表 for update (引擎/事务)因为之前用过oracle,知道利用select * for update 可以锁表。所以很自然就想到在mysql中能不能适应for update来锁表呢。学习参考如下由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table L...

weixin_39605004的博客 289

【Mysql】数据库引擎

引擎存储引擎数据库引擎数据库引擎的定义数据库引擎的任务mySql引擎的类别ISAM引擎MyISAM引擎Heap引擎InnoDB引擎InnoDB与MyISAM对比 存储引擎 MySQL常见的两种存储引擎:MyISAM和InnoDB 数据库引擎 数据库引擎的定义 访问数据库时,通过数据库引擎访问数据库文件。以关系数据库为例,发送SQL语句给数据库引擎,数据库引擎解释SQL语句,提取出需要的数据进行返回,数据库引擎就是SQL语句的解释器。 数据库引擎是用于存储、处理和保护数据的核心服务。利用数据库引擎可以控制访问

张茂祯的博客 270

MySQL存储引擎选型指南:InnoDB、MyISAM与Memory场景对比

数据库查询性能优化是后端工程师绕不开的命题,而存储引擎的选型往往成为影响系统吞吐的关键一环。在MySQL体系下,InnoDB通过聚簇索引与行级锁支撑高并发事务场景,MyISAM则依靠朴素的结构在只读报表中展现速度优势,Memory引擎以内存存取提供毫秒级响应却需要严格容量控制。理解不同引擎在数据组织、锁竞争与缓存机制上的底层差异,才能精准定位慢查询根因,避免因表锁等待或索引缺失导致性能雪崩。从OLTP高并发到历史归档,只有依据实际读写特征反推引擎选择,并配合规范的切换流程,才能让数据库在正确的位置发挥最大效

weixin_30522983的博客 288
上一篇: Mysql的ut_delay问题分析
下一篇: 高并发场景下优化spinlock
DBAIOps社区
博客等级 码龄3年 970粉丝 107原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值