mysql新增,更新,批量插入操作

article/2025/10/25 13:06:22

mysql新增和更新操作

一、Insert的几种语法

例子:

CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(30) DEFAULT NULL,`money` double DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `username_index` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4

1.普通插入语句

INSERT INTO `users` (`id`, `username`, `money`)
VALUES(NULL, '小张', 30)

2.插入或更新

如果我们希望插入一条新记录(INSERT),但如果记录已经存在,就更新该记录,此时,可以使用"INSERT INTO … ON DUPLICATE KEY UPDATE …"语句:

情景示例:这张表存了用户历史充值金额,如果第一次充值就新增一条数据, 
如果该用户充值过就累加历史充值金额,需要保证单个用户数据不重复录入。

这时可以使用"INSERT INTO … ON DUPLICATE KEY UPDATE …"语句。
注意事项:"INSERT INTO … ON DUPLICATE KEY UPDATE …"语句是基于唯一索引或主键来判断唯一(是否存在)的。如下SQL所示,需要在username字段上建立唯一索引(Unique),id设置自增即可。

INSERT INTO `users` (`id`, `username`, `money`)
VALUES
(NULL, '小王', 30) 
ON DUPLICATE KEY UPDATE  money=money + 30;

若username='小王’的记录不存在,INSERT语句将插入新记录,否则,当前username='小王’的记录将被更新,更新的字段由UPDATE指定。
ON DUPLICATE KEY UPDATE为MySQL特有语法,比如在MySQL迁移Oracle或其他DB时,类似的语句要改为MERGE INTO语法。

3.插入或替换

如果我们想插入一条新记录(INSERT),但如果记录已经存在,就先删除原记录,再插入新记录。

情景示例:这张表存的每个客户最近一次交易订单信息, 要求保证单个用户数据 
不重复录入,且执行效率最高,与数据库交互最少,支撑数据库的高可用。

此时,可以使用"REPLACE INTO"语句,这样就不必先查询,再决定是否先删除再插入。
"REPLACE INTO"语句是基于唯一索引或主键来判断唯一(是否存在)的。

注意事项:
如下SQL所示,需要在username字段上建立唯一索引(Unique),id设置自增即可。

REPLACE INTO `users` (`id`, `username`, `money`)
VALUES (NULL, '小张', 30) ;

若username='小张’的记录不存在,REPLACE语句将插入新记录(首次充值),否则,当前username='小张’的记录将被删除,然后再插入新记录。

id不要给具体值,不然会影响SQL执行,业务有特殊需求除外。

小tips:
ON DUPLICATE KEY UPDATE: 
如果插入行出现唯一索引或者主键重复时,则执行旧的update;如果不会导致 
唯一索引或者主键重复时,就直接添加新行。
REPLACE INTO:如果插入行出现唯一索引或者主键重复时,则delete老记录, 
而录入新的记录;如果不会导致唯一索引或者主键重复时,就直接添加新行。

replace into 与 insert on deplicate udpate 比较:

1、在没有主键或者唯一索引重复时,replace into 与 insert on deplicate udpate 相同。
2、在主键或者唯一索引重复时,replace是delete老记录,而录入新的记录,所以原有的所有记录会被清除,这个时候,如果replace语句的字段不全的话,有些原有的比如c字段的值会被自动填充为默认值(如Null)。
3、insert on deplicate udpate只是影响一行,而REPLACE INTO可能影响多行。

4.插入或忽略

如果我们希望插入一条新记录(INSERT),但如果记录已经存在,就啥事也不干直接忽略,此时,可以使用INSERT IGNORE INTO …语句。

注意事项
同上,"INSERT IGNORE INTO …"语句是基于唯一索引或主键来判断唯一(是否存在)的,需要在username字段上建立唯一索引(Unique),id设置自增即可。

-- 用户首次添加
INSERT IGNORE INTO `users` (`id`, `username`, `money`)
VALUES (NULL, '小刘', 30) ;
-- 二次添加,直接忽略
INSERT IGNORE INTO `users` (`id`, `username`, `money`)
VALUES (NULL, '小刘', 30) ;

二、大量数据插入(三种处理方式)

1、单条循环插入

我们取10w条数据进行了一些测试,如果插入方式为程序遍历循环逐条插入。在mysql上检测插入一条的速度在0.01s到0.03s之间。

逐条插入的平均速度是0.02*100000,也就是33分钟左右。

    @Testpublic void insertUsers1() {User user = new User();user.setUserName("提莫队长");user.setPassword("正在送命");user.setPrice(3150);user.setHobby("种蘑菇");for (int i = 0; i < 100000; i++) {user.setUserName("提莫队长" + i);// 调用插入方法userMapper.insertUser(user);}}

2、修改SQL语句批量插入

insert into user_info (user_id,username,password,price,hobby)values (null,'提莫队长1','123456',3150,'种蘑菇', (null,'盖伦','123456',450,'踩蘑菇');

用批量插入插入100000条数据,测试代码如下:

    @Testpublic void insertUsers2() {List<User> list= new ArrayList<User>();User user = new User();user.setPassword("正在送命");user.setPrice(3150);user.setHobby("种蘑菇");for (int i = 0; i < 100000; i++) {user.setUserName("提莫队长" + i);// 将单个对象放入参数list中list.add(user);}userMapper.insertListUser(list);}

批量插入使用了0.046s 这相当于插入一两条数据的速度,所以用批量插入会大大提升数据插入速度,当有较大数据插入操作是用批量插入优化

批量插入的写法:

dao定义层方法:

Integer insertListUser(List<User> user);

mybatis Mapper中的sql写法:

<insert id="insertListUser" parameterType="java.util.List">INSERT INTO `db`.`user_info`( `id`,`username`,`password`,`price`,`hobby`) values<foreach collection="list" item="item"  separator="," index="index">(null,#{item.userName},#{item.password},#{item.price},#{item.hobby})</foreach></insert>

这样就能进行批量插入操作:

注:但是当批量操作数据量很大的时候。例如我插入10w条数据的SQL语句要操作的数据包超过了1M,MySQL会报如下错:

报错信息:
Mysql You can change this value on the server by setting the max_allowed_packet’ variable. Packet for query is too large (6832997 > 1048576). You can change this value on the server by setting the max_allowed_packet’ variable.
解释:
由于查询的数据包太大(6832997> 1048576)。 您可以通过设置max_allowed_packet的变量来更改服务器上的这个值。
通过解释可以看到用于操作的包太大。这里要插入的SQL内容数据大小为6M 所以报错。
解决方法:
数据库是MySQL57,是MySQL的一个系统参数问题:
max_allowed_packet,其默认值为1048576(1M),
查询:

show VARIABLES like '%max_allowed_packet%';

修改此变量的值:MySQL安装目录下的my.ini(windows)或/etc/mysql.cnf(linux) 文件中的[mysqld]段中的
max_allowed_packet = 1M,如更改为20M(或更大,如果没有这行内容,增加这一行),如下图
在这里插入图片描述
保存,重启MySQL服务。现在可以执行size大于1M小于20M的SQL语句了。
但是如果20M也不够呢?

3、分批量多次循环插入

如果不方便修改数据库配置或需要插入的内容太多时,也可以通过后端代码控制,比如插入10w条数据,分100批次每次插入1000条即可,也就是几秒钟而已;当然,如果每条的内容很多的话,另说。

4、插入速度慢的其他几种优化途径

A、通过show processlist;命令,查询是否有其他长进程或大量短进程抢占线程池资源 ?看能否通过把部分进程分配到备库从而减轻主库压力;或者,先把没用的进程kill掉一些。
B、大批量导数据,也可以先关闭索引,数据导入完后再打开索引

关闭:ALTER TABLE user_info DISABLE KEYS;
开启:ALTER TABLE user_info ENABLE KEYS;

三、REPLACE INTO语法的“坑”

上面曾提到REPLACE可能影响3条以上的记录,这是因为在表中有超过一个的唯一索引。在这种情况下,REPLACE将考虑每一个唯一索引,并对每一个索引对应的重复记录都删除,然后插入这条新记录。假设有一个table1表,有3个字段a, b, c。它们都有一个唯一索引,会怎么样呢?我们早一些数据测试一下。

-- 测试表创建,a,b,c三个字段均有唯一索引
CREATE TABLE table1(a INT NOT NULL UNIQUE,b INT NOT NULL UNIQUE, 
c INT NOT NULL UNIQUE);
-- 插入三条测试数据
INSERT into table1 VALUES(1,1,1);
INSERT into table1 VALUES(2,2,2);
INSERT into table1 VALUES(3,3,3);

此时table1中已经有了3条记录,a,b,c三个字段都是唯一(UNIQUE)索引

mysql> select * from table1;
+---+---+---+
| a | b | c |
+---+---+---+
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
+---+---+---+
3 rows in set (0.00 sec)

下面我们使用REPLACE语句向table1中插入一条记录。
REPLACE INTO table1(a, b, c) VALUES(1,2,3);

mysql> REPLACE INTO table1(a, b, c) VALUES(1,2,3);
Query OK, 4 rows affected (0.04 sec)

此时查询table1中的记录如下,只剩一条数据了~

mysql> select * from table1;
+---+---+---+
| a | b | c |
+---+---+---+
| 1 | 2 | 3 |
+---+---+---+
1 row in set (0.00 sec)

REPLACE INTO语法回顾:
如果插入行出现唯一索引或者主键重复时,则delete老记录,而录入新的记录;如果不会导致唯一索引或者主键重复时,就直接添加新行。
我们可以看到,在用REPLACE INTO时每个唯一索引都会有影响的,可能会造成误删数据的情况,因此建议不要在多唯一索引的表中使用REPLACE INTO;


http://chatgpt.dhexx.cn/article/YlSWss3D.shtml

相关文章

MySQL优化:批量插入大数据4种实用、讲究方案的测试

简明&#xff1a;本文记录个人使用MySQL插入大数据总结较实用的方案&#xff0c;通过对常用插入大数据的4种方式进行测试&#xff0c;即for循环单条、拼接SQL、批量插入saveBatch()、循环 开启批处理模式&#xff0c;得出比较实用的方案心得。 &#xff08;个人记录学习笔记内…

Hi3559A Hi3519A Hi3556A算力对比

Hi3559A Hi3519A Hi3556A算力对比 Hi3559A 即Hi3559ARFCV100 4T算力 封装 FC-BGA 常备 Hi3519A Hi3519ARFVV100 才是AI芯片 2T算力 订货 先进的智能IP摄像头Soc Hi3519V101 先进的工业IP摄像头Soc Hi3516DV300 1T算力 常备 专业4M智能IP摄像SoC Hi3516CV500 0.5T算力 常备货…

海思Hi3798MV310芯片处理器参数介绍

Hi3798MV310是用于IPTV/OTT机顶盒市场的支持4KP60 解码的超高清高性能SOC芯片。集成4核64位高性能Cortex A53处理器和多核高性能 2D/3D加速引擎&#xff1b;支持H.265/AVS2 4Kx2KP60 10bit 超高清视频解码&#xff0c;高性能的 H.265 高清视频编码&#xff0c;HDR视频解码及显示…

湖北电信黑盒创维E900V21E-HI3798MV310-MT7661RSN-当贝桌面-免拆卡刷固件包

湖北电信黑盒创维E900V21E-HI3798MV310-MT7661RSN-当贝桌面-免拆卡刷固件包-内有主板图及教程 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量…

移动机顶盒migu-jt-u1 unt400c刷机 hi3798 root

准备好u盘&#xff0c;把固件放进去&#xff0c;插到机顶盒上 1&#xff0c;打开机顶盒天灵盖。短接这两个敏感点&#xff0c;开机&#xff0c;不松手&#xff0c;等出现刷机界面。 视频 链接&#xff1a; caiyun.139.com/m/i?105Cq73pcbcbW 提取码&#xff1a;Bgq3 复制内容…

海思AI芯片(Hi3519A/3559A)方案学习(三)Ubuntu18.0.4上编译Hi3519AV100 uboot和kernel

先重申下我的平台为ubuntu18.0.4&#xff0c;SDK的目标平台为Hi3519AV100系列 准备工作 安装himix200交叉编译器 tar –xzf arm-himix200-linux.tgzsudo ./arm-himix200-linux.installsource /etc/profile 安装SDK包 tar -zxf Hi3519AV100_SDK_V2.0.1.0.tgzsudo ./sdk.unp…

Hi3798M V200 SDK文档介绍

目录 下载SDK并解压解压后主要的文件夹 下载SDK并解压 步骤1&#xff1a;下载Hi3798M V200 SDK。 大家如果有下载路径可以直接下载&#xff0c;如果没有的话可以使用我这个路径。 链接&#xff1a;https://pan.baidu.com/s/1buqwwZ7yBPNmi6JA2KG1eQ 提取码&#xff1a;dv6f ps…

FPGA+海思Hi3559

海思3559av100接收FPGA通过LVDS发送的模拟数据&#xff0c;&#xff0c;模拟数据为彩带。 FPGA可以模拟彩带或者黑白灰图像的模拟数据&#xff0c;通过LVDS协议&#xff08;LVDS为低电压差分信号&#xff0c;核心是采用极低的电压摆幅高速差动传输数据&#xff0c;可以实现点对…

海思Hi3798MV310机顶盒芯片Datasheet-基本信息

Hi3798M V310 是用于 IPTV/OTT 机顶盒市场的支持 4KP60 解码的超高清高性能 SOC芯片。集成 4 核 64 位高性能 Cortex A53 处理器和多核高性能 2D/3D 加速引擎&#xff1b;支持H.265/AVS2 4Kx2KP60 10bit 超高清视频解码&#xff0c;高性能的 H.265 高清视频编码&#xff0c;HDR…

海思Hi3798MV200机顶盒芯片规格书-基本信息

Hi3798MV200 是用于 IPTV/OTT 机顶盒市场的支持 4KP60 解码的全 4K 高性能 SOC芯片。集成 4 核 64 位高性能 Cortex A53 处理器和多核高性能 2D/3D 加速引擎;支持H.265 4Kx2K@P60 10bit 超高清视频解码,高性能的 H.265 高清视频编码,HDR 视频解码及显示,HDR 转 SDR,BT.202…

hi3798mv300是什么手机_海思Hi3798MV300/Hi3798MV310/Hi3798MV300H共升级包使用指南芯片手册...

本文针对现网各种场景&#xff0c;对hi3798MV300、Hi3798MV310、Hi3798MV300H共升级包方案的升级包的编译、制作方法和原理进行了详细介绍。 适用场景 场景1&#xff1a; 现网同时有Hi3798MV300和Hi3798MV300H&#xff0c;而且版本基线相同&#xff0c;现需要升级到最新版本 场…

Hi3519AV100 适配IMX347

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.SDK Hi3519AV100_SDK_V2.0.1.0 3.单板 Hi3519AV100开发板 IMX347 2688x1520(4M)30fps master mode i2c id 0x34 一、Sensor i2c寄存器读写 海思默认文件系统是有i2c读写工具的&#xff0c;可以使用这个工具…

海思Hi3798硬件设计,Hi3798 datasheet(2)参考资料

本文主要介绍 Hi3798C V200 芯片的硬件封装、管脚描述、管脚复用寄存器的配置方法、电气特性参数、原理图设计建议、PCB 设计建议、热设计建议等内容。本文主要为硬件工程师提供硬件设计的参考。 2.1 封装 Hi3798C V200 芯片 TFBGA&#xff08;Thin Fine BGA package&#xf…

HI3798MV200驱动移植

目录 1.UBOOT配置修改方法 2.由EMMC启动改为SPI NAND FLASH 启动 3.网络调试 4.PHY复位 5.内核起来网络不通 6.增加RTC 7.PHY 灯ACT LINK 问题 8.PHY link状态查询 9.ETH0 网络状态灯修改 1.UBOOT配置修改方法 需要对应版本的HITOOL&#xff0c;个人也是废了很大劲&a…

M301H-BYT代工-支持Hi3798 MV300H/MV300/MV310芯片-当贝纯净桌面-强刷卡刷固件包

M301H-BYT代工-支持Hi3798 MV300H&#xff0f;MV300&#xff0f;MV310芯片-当贝纯净桌面-强刷卡刷固件包 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff…

Hi3798 openSSH的移植

前言 在编译海思SDK时&#xff0c;会自动编译openssl&#xff0c;zlib&#xff0c;故无需重复编译这两者。 编译 编译openssh 本文下载openssh-7.3p1版本&#xff0c;将其下载至虚拟机 tar -xvf openssh-7.3p1.tar.gz ./configure --hostarm-linux --prefix/usr/local/ope…

海思HI3798M GPIO和PWM操作

一、GPIO拉高拉低操作 以GPIO2_7为例 地址&#xff08;0xF8B2_2400&#xff09; 基地址&#xff08;0xF8B2_2000&#xff09; 偏移地址&#xff08;0x00000400&#xff09; ①把GPIO2_7管脚复用设置为IO模式 himm 0xF8B2205C 0x00&#xff08;0xF8B2205C 基地址0xF8B2_2000 …

海思Hi3798MV100机顶盒芯片介绍

Hi3798M V100是海思推出的专门针对OTT机顶盒市场的高性价比芯片方案。在码流兼容性、在线视频播放的流畅性、图像质量以及整机性能方面保持业界最好的用户体验。集成四核高性能处理器、内置NEON&#xff0c;其处理性能可以满足各种差异化的业务需求&#xff0c;支持Dolby和DTS音…

海思Hi3798MV300_Hi3798MV300H_Datasheet-系统

Hi3798MV300/Hi3798MV300H处理器子系统 Hi3798MV300/Hi3798MV300H采用 ARMCortex-A53MPCore 四核处理器&#xff0c;Cortex-A53 MPCore 具有以下特点&#xff1a;  处理器集成了 256KB L2 cache。  支持 ARMv8-A 架构。  支持 DVFS 自动调频调压和 AVS 自适应调压。 …

海思Hi3798处理器参数,Hi3798芯片详细信息介绍

Hi3798C V200集成4核64位高性能Cortex A53 处理器、内置NEON 加速引擎&#xff0c;强大的CPU 处理能力可以满足各种差异化的业务需求。在码流兼容性、在线视频播放的流畅性、图像质量以及整机性能方面保持业界最好的用户体验。支持4K 2KP6010bit 超高清视频解码和显示&#xff…