【面试题24】MySQL如何给一个1000万的表安全的加字段

news2024/9/21 1:20:26

文章目录

  • 一、前言
  • 二、MySQL表添加字段的方案
    • 2.1 ALTER TABLE 添加字段
    • 2.2 Online Alter Table
    • 2.3 Percona Toolkit
    • 2.4 给表新增字段
    • 2.5 使用触发器添加字段
  • 总结


一、前言

本文已收录于PHP全栈系列专栏:PHP面试专区。
计划将全覆盖PHP开发领域所有的面试题,对标资深工程师/架构师序列,欢迎大家提前关注锁定。

当一个MySQL表有大量数据的时候,需要给它添加新的字段,会带来很多问题,如数据重构、锁定表等。本文将介绍几种安全可靠的方式,让您在MySQL表中添加字段时更加愉悦。
在这里插入图片描述

二、MySQL表添加字段的方案

2.1 ALTER TABLE 添加字段

ALTER TABLE 添加字段是最常用的方法,也是最不方便、最耗费时间的方法。假设要在一个有1000万行数据的表中添加一个字段remark,则可以使用以下命令:

ALTER TABLE table_name ADD remark VARCHAR(255);

这个命令会在表中添加一个新列remark,类型为VARCHAR(255),并且默认值为NULL。然而,ALTER TABLE 添加新的字段可能会导致锁表,长时间卡住查询和更新操作,影响其他业务的正常运行。同时,如果在表中有多个索引的情况下,那么ALTER TABLE 添加新列时将会话费更长的时间。

2.2 Online Alter Table

Online Alter Table 是MySQL 5.6中新增的功能,可以在线修改MySQL表结构,包括添加、删除、修改列等。相较于ALTER TABLE 添加字段的方式,Online Alter Table 不需要锁定表,也不会对其他应用程序产生影响。

假设要在一个有1000万行数据的表中添加一个字段remark,则可以使用以下命令:

ALTER TABLE table_name ADD COLUMN remark VARCHAR(255), ALGORITHM=INPLACE, LOCK=NONE;

这个命令使用了 Online Alter Table 的方式,添加一个新列remark,类型为VARCHAR(255),并且默认值为NULL。使用INPLACE算法, 就能保证不会产生数据复制和重建索引的情况,而且在LOCK=NONE的情况下就不需要锁表,不会对其他业务产生影响。

Online Alter Table 是一种更加安全可靠的方式,但是在实际使用中还要注意以下几点:

  1. 需要使用MySQL 5.6或者更高版本。
  2. 需要把innodb_file_per_table配置为ON,否则可能会导致磁盘空间不足。
  3. 一些特殊的数据类型不能使用Online Alter Table。(比如spatial类型,full text类型,等等)

2.3 Percona Toolkit

Percona Toolkit是Percona公司推出的MySQL实用工具包,其中有一个pt-online-schema-change工具,可以在线修改MySQL表结构,包括添加、删除、修改列等。相较于前面的两种方式,Percona Toolkit 的在线操作功能更加强大,支持对多个表进行合并、分裂、检查和校验等操作。

使用Percona Toolkit的方式,可以避免ALTER TABLE 添加字段的方式导致锁表,长时间卡住查询和更新操作,影响其他业务的正常运行。同时Percona Toolkit工具包还支持在线执行DDL语句,使到表结构的更新更加方便。

在实际使用Percona Toolkit工具包时,需要注意以下几点:

  1. 需要把innodb_file_per_table配置为ON,否则可能会导致磁盘空间不足。
  2. 安装Percona Toolkit的服务器和MySQL主机之间的网络延迟可能会影响到修改操作的速度。

2.4 给表新增字段

给表新增字段是一种非在线的方式,在不停止MySQL服务的情况下,通过重命名表和建立新表的方式,慢慢地完成表结构更改。其核心思路是:

  1. 先创建一个新的表,包含了所有原有表的列,以及要新增的列;
  2. 将旧表中的数据复制到新表中;
  3. 在原有的业务中对新表进行测试,如果没有问题则可以删除旧表、重命名新表为旧表的名字;
  4. 如果出现问题,可以还原到原来的旧表。

具体操作步骤如下:

# 1. 创建一个新表
CREATE TABLE new_table LIKE old_table;
ALTER TABLE new_table ADD remark VARCHAR(255);

# 2. 把旧表中的数据复制到新表中
INSERT INTO new_table (column1,column2,...)
  SELECT column1,column2,... FROM old_table;

# 3. 测试并且删除旧表
RENAME TABLE old_table TO backup_table;
RENAME TABLE new_table TO old_table;
DROP TABLE backup_table;

这种方式可以避免出现锁表、SQL语句阻塞等问题,但是在实际操作中需要注意以下几点:

  1. 新建的表需要和旧表有相同的索引和数据约束;
  2. 如果新表中存在外键,在复制数据之前需要先关闭外键约束,待复制结束后再开启;
  3. 大数据量的表在拷贝数据时可能会导致磁盘空间不足,因此需要确保磁盘空间足够大。

2.5 使用触发器添加字段

与其他方法相比,这种方法的好处是,它可以确保数据一致性,并且可以追踪所有表更改。缺点是,它可能会影响数据库的性能,因此只适用于小型数据集。

在这种方法中,您需要创建一个触发器,以便在插入、更新或删除行时,在新的字段中添加备注。以下是一个示例触发器:

CREATE TRIGGER add_remark_trigger BEFORE INSERT ON mytable FOR EACH ROW SET NEW.remark = 'new remark';

此触发器将在插入新行时自动添加新字段。在此示例中,它会将字段设置为 “new remark”,但是您可以根据需要修改触发器以实现不同的行为。

总体来说,在不停机更新的情况下面,在数据实时变化的的数据表下面添加字段,为了维护数据一致性,用触发器是一个不错的选择。

总结

本文介绍了大表加字段的多种方式,大家如果遇到此类情况,请结合自己项目的实际情形作出选择。数据无价,请谨慎操作。

本文已收录于PHP全栈系列专栏:PHP面试专区。
计划将全覆盖PHP开发领域所有的面试题,对标资深工程师/架构师序列,欢迎大家提前关注锁定。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/693513.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【AIGC】18、MobileSAM | 首个专为移动端设计的更快的 SAM

文章目录 一、背景二、方法2.1 耦合蒸馏2.2 从半蒸馏到解耦蒸馏 三、效果 论文:FASTER SEGMENT ANYTHING: TOWARDS LIGHTWEIGHT SAM FOR MOBILE APPLICATIONS 代码:https://github.com/ChaoningZhang/MobileSAM 出处:韩国庆熙大学 时间&am…

MP4视频格式和mp4v2的移植

目录 1、视频文件 2、MP4 3、MP4学习方法 4、MP4文件格式解析 5、MP4Info工具使用 6、mp4v2移植和播放 6.1、下载mp4v2 6.2、配置并编译 6.3、部署 6.4、编译sample 6.5、准备TF卡 6.6、运行和测试 7、MP4打包源码解析 8.添加网络telnet调试 8.1、为什么添加teln…

java进程注入

本文重点java Instrumentation java Instrumentation指的是可以用独立于应用程序之外的代理(agent)程序来监测和协助运行在JVM上的应用程序。这种监测和协助包括但不限于获取JVM运行时状态,替换和修改类定义等。简单一句话概括下:…

11 通信的基本概念

目录 通信分类概览 串行通讯与并行通讯 全双工、半双工及单工通讯 同步通讯与异步通讯 通讯速率 注意 通信分类概览 串行通讯与并行通讯 串行通讯是指设备之间通过少量数据信号线(一般是 8 根以下),地线以及控制信号线,按数据位形式一位一位地传输…

Windows下创建进程的理解

创建windows进程,需要考虑两个点,即session和权限问题。了解这两点,网络上服务创建界面进程,管理员权限进程创建普通权限进程的代码则很好理解。 1、基础知识 (1) session (2) 权限 CreateProcessAsUser需要传入一个token&#x…

LeetCode 打卡day45--完全背包问题之最小填充次数

一个人的朝圣 — LeetCode打卡第45天 知识总结Leetcode 70. 爬楼梯题目说明代码说明 Leetcode 322. 零钱兑换题目说明代码说明 Leetcode 279. 完全平方数题目说明代码说明 知识总结 今天的问题都可以归结一句话, 在完全背包的问题设置下, 问将该背包填满最少需要放几件物品. L…

java基础(并发编程)-异步模式之生产者/消费者

一、定义要点 与前面的保护性暂停中的GuardedObject不同,不需要产生结果和消费结果的线程一一对应消费队列可以用来平衡生产和消费的线程资源生产者仅负责产生结果数据,不关心数据该如何处理,而消费者专心处理结果数据消息队列是有容量限制的…

代码随想录算法训练营第17期第1天 | 704. 二分查找、27. 移除元素

从头开始,重新再来,但是又不完全一样,之前是擅长的python,现在是C,能坚持下来么? 704. 二分查找 704. 二分查找https://leetcode.cn/problems/binary-search/ 上次写这道题已经是两个月之前,说…

Openresty原理概念篇(七)OpenResty 中用到的 NGINX 知识

一 OpenResty 中用到的 NGINX 知识 Luaj 是一个 Java 的 Lua 解释器,基于 Lua 5.2.x 版本 luaj ① 说明 1) 本文可有可无原因:如果你之前没有接触过nginx或者涉及一点nginx,那么建议阅读2) 由于自己已经对nginx整个脉络体系进行讲解,本文只是机械的摘录,构成…

Java使用RabbitMQ实战,Springboot使用rabbitMQ实战

文章目录 一、Java原生API1、简单实例2、延迟消息3、消费端限流4、消息属性设置5、消息可靠投递 二、Spring-API1、简单实例(1)引入rabbitMQ.xml(2)生产者(3)消费者(4)测试类 三、Sp…

使用VSCODE跑orbslam2踩的坑

我用的是ubuntu22.04,opencv是4.7,使用其他的库感觉就算版本不一样,也能跑。 一、运行build.sh能够产生可执行文件遇到的问题 1.由于opencv版本高带来的问题 这些问题怎么定位出现在哪些文件中,你通过命令行,运行下…

更灵活的CSS3新特性:帮你简化样式管理和优化网站性能

文章目录 I. 前言:介绍CSS3的进化和发展趋势CSS3的历史和版本CSS3的标准化和浏览器支持情况 II. 新的CSS选择器:扩展选择器的功能属性选择器:更多方式选择元素伪类和伪元素:更方便地定义样式 III. 改进的排版和布局:实…

在 EulerOS 系统中设置 Chrony 时间同步服务

以下是在 EulerOS 系统中设置 Chrony 时间同步服务的所有步骤。 1.查看系统版本 [rootservice11 ~]# cat /etc/redhat-release EulerOS release 2.0 (SP5)2.检查是否已安装chrony软件 [rootservice11 ~]# rpm -qa|grep chrony chrony-3.2-2.eulerosv2r7.x86_64如果没有安装…

Openlayers实战教程学习大纲及引导

本系列教程是Openlayers的实战教程,介绍Openlayes的一些基础知识,并重点讲述哪些地方是openlayers项目中常用的,给出具体示例,起到一个很好的引导学习作用。 版本说明 Openlayers的实战教程 分为**图文版** 和 **视频版**&#x…

【经验分享】全志科技官方Ubuntu16.04根文件系统镜像的替换和测试方法

本文主要基于全志A40i开发板——TLA40i-EVM,一款基于全志科技A40i处理器设计的4核ARM Cortex-A7高性能低功耗国产评估板,演示Ubuntu根文件系统镜像的替换和测试方法。 创龙科技TLA40i-EVM评估板接口资源丰富,引出双路网口、双路CAN、双路USB…

7.5_1散列查找(上)

基于一种数据结构: 散列表(Hash Table),又称作哈希表 特点:数据元素的关键字与其存储地址直接相关 其实这个散列表也是基于数组实现的 加入19对13取余 加入再次插入1的话,塞不进去 数据元素不会直接存放到…

深入浅出设计模式 - 适配器模式

博主介绍: ✌博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家✌ Java知识图谱点击链接:体系化学习Java(Java面试专题) 💕💕 感兴趣的同学可以收…

Presto(Trino)分布式(物理)执行计划的生成和调度

文章目录 1.前言2.物理执行生成(Stage)的生成2.1不同的调度分区策略2.1.1 Connector自己提供的分区策略2.1.2 Presto提供的Partition策略(SystemPartitioningHandle): 2.2 为Stage创建StageScheduler2.2.1 普通的非bucket表的TableScan StageSplit 放置策略解析 2.2…

UE5.1.1 c++从0开始(14.用C++写UMG类)

先在这里放一个链接防止第一次看的朋友们不知道我在讲什么:https://www.bilibili.com/video/BV1nU4y1X7iQ/ 这一段的教程不难,唯一新建的C类是UMG的一个类。这个类用来写绑定在ai身上的血条。 总结一下一共做了什么事情: 给ai写了一个血条…

LeetCode Java两个单链表相交的一系列问题

题目描述 单链表可能有环,也可能无环。给定两个单链表的头节点 head1和head2,这两个链表可能相交,也可能不相交。 请实现一个函数,如果两个链表相交,请返回相交的第一个节点;如果不相交,返回n…