MySQL几种更新操作的案例分析

目录
  • 案例分析
  • 更新账户金额
    • 直接更新
    • 乐观锁方案
    • 无锁方案
    • 排队操作
  • 常见问题
    • 如果数据中存在 update_time 字段受影响的行数是多少?
    • 如果执行 update 更新但受影响的行数为 0 会加行锁吗?
  • 参考资料

本文将通过一个 用户账户金额更新的案例 分析几种数据更新的操作的优劣。希望对大家有帮助 🐶。

数据库版本 : mysql 5.7.23

案例分析

创建数据库的DDL:

CREATE TABLE `hw_account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `balance` int(11) DEFAULT NULL,
  `status` varchar(20) DEFAULT NULL,
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

更新账户金额

直接更新

方案 1 查询后更新

# 数据查询
select * from hw_account where id = 1;

# 数据更新
update hw_account set balance = 5 where id = 1;

存在的问题,就是分两次操作,如果并发执行的时候,可能造成更新丢失的问题.

乐观锁方案

利用版本号操作,即对数据库增加乐观锁的方式进行。

# 数据查询
select * from hw_account where id = 1;

# 数据更新
update hw_account set balance = 5 , version = version + 1
  where id = 1 and version = n;

# 判断是否成功
if row < 1 {
   回滚
}

存在的问题,如果该条数据并发操作的时候,会导致其他的请求失败。如果这个请求的前置链路比较长的话, 回滚成本比较高。

无锁方案

不用查询,采用数据库的计算,也不需要版本号的操作,直接通过域值进行有效性判断。具体的 SQL 如下:

# 数据更新
update hw_account set balance = balance + @change_num , version = version + 1
  where id = 1 and version = n;

# 判断是否成功
if row < 1 {
   回滚
}   

这种方案修改比较简单, 但是依赖于数据计算,感觉不是特别友好。

排队操作

通过 redis 或者 zk 的分布式锁,进行数据请求进行排队。然后在进行数据更新。

# 伪代码

if (获取分布式锁) {
  update hw_account set balance = @balance where id = 1;
} else {
  # 进入等待,或者进行自旋获取锁
}

常见问题

如果数据中存在 update_time 字段受影响的行数是多少?

update_time 的字段定义如下,如果数据为id = 1, status = 1 如果执行更新数据的 sql 为

update hw_account set `status` = 1 where id = 1;

返回的受影响的行数为 0;

如果执行 update 更新但受影响的行数为 0 会加行锁吗?

会的, 执行更新的语句都会加行锁(前提,事务内)

参考资料

mysql.com

到此这篇关于MySQL几种更新操作的案例分析的文章就介绍到这了,更多相关MySQL 更新操作内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • MYSQL 的10大经典优化案例场景实战

    目录 一.SQL优化一般步骤 1.explain 分析SQL的执行计划 2.show profile 分析 3.trace 4.确定问题并采用相应的措施 二.场景分析(案例) 1. 最左匹配 2.隐式转换 3.大分页 4.in + order by 5.范围查询阻断,后续字段不能走索引 6.不等于.不包含不能用到索引的快速搜索 7.优化器选择不使用索引的情况 8.复杂查询 9.asc和desc混用 10.大数据 一.SQL优化一般步骤 通过慢查日志等定位那些执行效率较低的SQL语句 1.expl

  • SQL数据库十四种案例介绍

    数据表 /* Navicat SQLite Data Transfer Source Server : school Source Server Version : 30808 Source Host : :0 Target Server Type : SQLite Target Server Version : 30808 File Encoding : 65001 Date: 2021-12-23 16:06:04 */ PRAGMA foreign_keys = OFF; -- -----

  • SQL Server批量插入数据案例详解

    在SQL Server 中插入一条数据使用Insert语句,但是如果想要批量插入一堆数据的话,循环使用Insert不仅效率低,而且会导致SQL一系统性能问题.下面介绍SQL Server支持的两种批量数据插入方法:Bulk和表值参数(Table-Valued Parameters),高效插入数据. 新建数据库: --Create DataBase create database BulkTestDB; go use BulkTestDB; go --Create Table Create tab

  • MySQL几种更新操作的案例分析

    目录 案例分析 更新账户金额 直接更新 乐观锁方案 无锁方案 排队操作 常见问题 如果数据中存在 update_time 字段受影响的行数是多少? 如果执行 update 更新但受影响的行数为 0 会加行锁吗? 参考资料 本文将通过一个 用户账户金额更新的案例 分析几种数据更新的操作的优劣.希望对大家有帮助

  • MySql删除和更新操作对性能有影响吗

    删除和更新操作的开销往往比插入高,所以一个好的设计需要减少对数据库的更新和删除操作. 3.1更新操作 数据库的更新操作会带来一连串的"效应":更新操作需要记录日志(以便错误时回滚):更新可变长字段(如,varchar类型)会带来数据物理存储的变化(记录的移动):更新索引字段会导致索引重建:更新主键会导致数据重组等.这一切不但会造成更新操作本身效率低,而且由于磁片碎片的产生会造成以后查询性能的降低.为了应对这一情况,有两种策略:一.减少更新次数,把多个字段的更新写到同一个语句里:二.避免

  • PHP数组操作简单案例分析

    本文实例讲述了PHP数组操作相关技巧.分享给大家供大家参考,具体如下: 这个是一道简单的PHP数组入门题 $Str = "as5454654%^$%^$7675dhasjkdhh12u123123asdasd"; //将上面的统计上面字符串不同字符和出现的次数. 实现方式:将字符串转换成数组,在通过对数组的操作得到相应的结果. $len = strlen($str); //数组存在数组中 $array = array(); for($i=0;$i<$len;$i++) { arr

  • mysql三种批量增加的性能分析

    下面把代码写出来,希望大家批评指正. 首先domain对象.在这里使用的注解的方式,都是比较新的版本. User.java 复制代码 代码如下: package com.bao.sample.s3h4.domain; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Generatio

  • Android SQLite数据库增删改查操作的案例分析

    Person实体类 复制代码 代码如下: package com.ljq.domain; public class Person {    private Integer id;    private String name;    private String phone; public Person() {        super();    } public Person(String name, String phone) {        super();        this.n

  • thinkPHP事务操作简单案例分析

    本文实例讲述了thinkPHP事务操作.分享给大家供大家参考,具体如下: 1.说明 Db::startTrans(); try{ 操作: 对象->save(); Db::commit(); } catch (Exception $ex) { Db::rollback(); throw $ex; } 2.案例 private function createOrderByTrans($snap) { Db::startTrans(); try { $orderNo = $this->makeOrd

  • php 的多进程操作实践案例分析

    本文实例讲述了php 的多进程操作.分享给大家供大家参考,具体如下: php的多进程处理依赖于pcntl扩展,通过pcntl_fork创建子进程来进行并行处理. 例1如下: <?php $pid = pcntl_fork(); if($pid == -1) { //错误处理:创建子进程失败时返回-1. die('fork error'); } else if ($pid) { //父进程会得到子进程号,所以这里是父进程执行的逻辑 echo "parent \n"; //等待子进程

  • Spring框架设值注入操作实战案例分析

    本文实例讲述了Spring框架设值注入操作.分享给大家供大家参考,具体如下: 一 配置 <?xml version="1.0" encoding="GBK"?> <!-- Spring配置文件的根元素,使用spring-beans-4.0.xsd语义约束 --> <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http:

  • MySQL Innodb表导致死锁日志情况分析与归纳

    案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志.两个sql语句如下:(1)insert into backup_table select * from source_table(2)DELETE FROM source_table WHERE Id>5 AND titleWeight<32768 AND joinTime<'$daysago_1week'teamUser表的表结构如下:PRIMARY

  • Python的mysql数据库的更新如何实现

    Python的mysql数据库的更新           Python的mysql数据库的更新操作,在实际应用项目中会用到更新数据库,更新过程中可能会出现数据丢失或者数据错乱等系统性的问题,还希望大家正确操作, 一 代码 import pymysql # 打开数据库连接 db = pymysql.connect("localhost","root","root","db_test01" ) # 使用cursor()方法获取操作

随机推荐