假设有文章post和评论comment两个表,文章表记录有评论的数量,但是这个值我们要一次更新。

如下,现在post表的comment_count都是0,我们的目标是:执行一个SQL语句,让其把统计comment表的数据数量。

post表数据如下:

+---------+-------------------+---------------+
| post_id | title | comment_count |
+---------+-------------------+---------------+
| 1 | How to lean MySQL | 0 |
| 2 | How to lean PHP | 0 |
| 3 | How to lean Redis | 0 |
+---------+-------------------+---------------+

comment表数据如下:

+------------+---------+---------+
| comment_id | post_id | content |
+------------+---------+---------+
| 1 | 1 | Good! |
| 2 | 1 | Nice! |
| 3 | 1 | Yeap! |
+------------+---------+---------+

因为这里只有post_id=1的文章有评论,所以最终的comment_count值分别为:3 0 0

1 使用SQL语句

在数据量为100W以下的时候,可以用一条命令解决:

UPDATE post AS a SET comment_count = (select count(*) FROM comment WHERE post_id=a.post_id);

2 使用存储过程(数据量巨大时用)

当数据量很大的时候,比如1亿条记录,如果再用上面这条命令,就会导致所有行被锁定(InnoDB存储引擎)。

UPDATE语句首先会查找需要更新的行,如果符合要求,先锁定,然后再更新,

上面这条语句会锁定所有行,等效于锁定全表。

解决这个问题的办法就是,按post表的post_id范围批量更新,具体代码如下:

DROP PROCEDURE IF EXISTS UpdateCount;

DELIMITER //
CREATE PROCEDURE UpdateCount()
BEGIN
DECLARE lower INT; # ID下限
DECLARE upper INT; # ID上限
DECLARE step INT; # 次增加步数
DECLARE max_id INT; # 最大ID SET lower = 1;
SET upper = 0;
SET step = 10000; # 每次更新1万条数据
SET max_id = 0; # 从库中读取最大ID
SELECT max(post_id) INTO max_id FROM post; WHILE lower <= max_id DO
# 上限等于下限加上步宽
SET upper = lower + step; # 还是和上面的方法一样,只是多了post_id的限定范围
UPDATE post AS a
SET comment_count = (SELECT count(*) FROM comment WHERE post_id=a.post_id)
WHERE post_id >= lower and post_id < upper; # 更新下限
SET lower = upper;
END WHILE;
END;
//
DELIMITER ;

最后,调用一遍这个存储过程

call UpdateCount();

每次会更新1万条数据,也就是更新时暂时锁住这1万条,

一般来说,更新1万条数据执行也是很快的,

所以这样就避免了整表所有记录被锁的问题。

MySQL更新字段来自另一个表的count()值的更多相关文章

  1. mysql更新字段值提示You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode

    1 引言 当更新字段缺少where语句时,mysql会提示一下错误代码: Error Code: 1175. You are using safe update mode and you tried ...

  2. Mysql JSON字段提取某一个属性值的函数

    mysql从5.7开始才支持JSON_EXTRACT等 JSON相关的函数, 项目里用到的mysql是5.6的,需要提取JSON字段里某一个属性值进行统计, 自己写了一个笨的提取方法: CREATE ...

  3. MySQL 更新走全表和索引的评估记录数

    #!/usr/bin/perl use DBI; $db_name='scan'; $ip='127.0.0.1'; $user="root"; $passwd="123 ...

  4. mysql查询字段所在表

    use information_schema;select * from columns where column_name='字段名' ;

  5. mysql 查询字段为空显示默认值

    IFNULL() 函数用于判断第一个表达式是否为 NULL,如果为 NULL 则返回第二个参数的值,如果不为 NULL 则返回第一个参数的值. IFNULL() 函数语法格式为: IFNULL(exp ...

  6. mysql更新字段内容

    update article set a_content = REPLACE(`a_content`,'www.abc.com','www.bcd.com')

  7. mysql更新某个字符串字段的部分内容

    如果现在需要Mysql更新字段重部分数据,而不是全部数据,应该采用何种方法呢?下面介绍了两种情况下Mysql更新字段中部分数据的方法,供您参考. Mysql更新字段中部分数据第一种情况: update ...

  8. MySQL数据库 字段操作 多表关系(更新中...)

    外键 (foreign key) ## 外键 ```mysql # 作者(author):id,name,sex,age,mobile, detail_id # 作者详情(author_detail) ...

  9. 如何使用MySQL一个表中的字段更新另一个表中字段

    [本文出自:https://www.jb51.net/article/150323.htm] 这篇文章主要介绍了如何使用MySQL一个表中的字段更新另一个表中字段,需要的朋友可以参考下 1,修改1列 ...

随机推荐

  1. Spring MVC模式下,获取WebApplicationContext的工具类 方法

    在已有的注解类型下,获取WebApplicationContext的工具类 通过  WebApplicationContextUtils.getRequiredWebApplicationContex ...

  2. SecureCRT配置华为S5700交换机

    我准备从交换机中监控某台设备的流量,所以要配置交换机的某个口作为镜像口,用来下载另外一个指定端口的流量. 第一步:华为5700交换机 简而言之网口部分除了最后四个都是用来连接下级网络设备的,最后四个端 ...

  3. MybatisPlus使用代码篇

    package spring.server.consumer; import com.baomidou.mybatisplus.annotation.DbType; import com.baomid ...

  4. Nginx入门到实战

    location 语法 location 有”定位”的意思, 根据Uri来进行不同的定位. 在虚拟主机的配置中,是必不可少的,location可以把网站的不同部分,定位到不同的处理方式上. 比如, 碰 ...

  5. flask 框架快速入门

    flask 框架快速入门 搭建一个简易flask项目 首先使用 Pycharm创建flask项目 运行flask项目 1.使用Pycharm搭建flask项目 (如果Pycharm新建项目中未出现该图 ...

  6. Spring Cloud Bus 自动更新配置

    ---恢复内容开始--- Spring Cloud Config 结合 Spring Cloud bus 实现 git 仓库提交配置文件 触发消息队列 应用自动更新配置 1. config 服务端 添 ...

  7. Linux目录权限管理

    Linux目录权限管理   实验目标: 通过本实验掌握centos7/rhel7目录权限的管理.包括配置目录的所属组.SGID.读/写/执行权限等. 实验步骤: 1.创建目录/home/instruc ...

  8. AI测试——旅程的终点

    在2019年6月,我产生了一个想法,即人工智能探索测试AIET(Artificial intelligence exploration test),大概用了一周时间来思考怎么把人工智能应用到测试领域, ...

  9. Shell初学(五)bash shell的基本功能

    记住,所谓的bash shell 并不单纯指的是shell脚本,其实是Linux系统的所有指令集. shell脚本 只是汇总了指令集到文件,然后按流程和顺序执行. [1]如何查看我们的预设shell ...

  10. Java 的不可变类 (IMMUTABLE CLASS) 和 可变类 (MUTABLE CLASS)

    一.简单定义不可变对象(Immutable Objects)即对象一旦被创建,它的状态(对象的数据,也即对象属性值)就不能改变,反之即为可变对象(Mutable Objects).当满足以下条件时,对 ...