暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【手写数据库核心揭秘系列】第111节 UPDATE更新演示,多表联合的跨表UPDATE,多列赋值的简洁写法

开源无限 2025-07-10
41


💻 深耕数据库内核架构设计与开发十余年,曾主导多款高性能分布式数据库内核研发,攻克高并发、低延迟等核心技术难题。现倾力打造《从零手写数据库》系列教程,首次系统性公开数据库内核源码级实现细节!
🚀 从存储引擎、查询优化到分布式事务,手把手拆解核心模块;从语法解析树构建到执行计划生成,逐行代码还原设计精髓
🌟 无论你是数据库开发者、系统架构师,还是对底层技术充满好奇的极客,这里都有你想要的“硬核干货”!点击关注,与行业老兵共同探索数据库技术的星辰大海!
公众号:开源无限

一、概述 


到此UPDATE命令基本操作已经完成,一起来看下UPDATE有哪些玩法。

二、初始化数据 


为了演示方便,初化一些有实际意义的数据。创建两张数据表,一张仓库信息的数据表,另一张是库存信息的数据表。

  • 仓库信息数据表
    CREATE TABLE warehouses (  w_id integer ,    name varchar,    address text,    capacity integer,    manager varchar);


    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (1'Warehouse A''123 Main St, City A'5000'Manager 1');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (2'Warehouse B''456 Elm St, City B'7000'Manager 2');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (3'Warehouse C''789 Oak St, City C'6000'Manager 3');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (4'Warehouse D''101 Pine St, City D'8000'Manager 4');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (5'Warehouse E''202 Maple St, City E'4500'Manager 5');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (6'Warehouse F''303 Birch St, City F'5500'Manager 6');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (7'Warehouse G''404 Cedar St, City G'7500'Manager 7');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (8'Warehouse H''505 Walnut St, City H'6500'Manager 8');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (9'Warehouse I''606 Cherry St, City I'9000'Manager 9');
    INSERT INTO warehouses (w_id, name, address, capacity, manager) VALUES (10'Warehouse J''707 Beech St, City J'8500'Manager 10');
    • 查看表中的数据行。
      [senllang@hatch exam_65]$ ./sqlparser
      MiniToad Database V0.0.1
      miniToad <select * from warehouses;
      |w_id    |name            |address                   |capacity |manager        |
      |1       |Warehouse A     |123 Main St, City A       |5000     |Manager 1      |
      |2       |Warehouse B     |456 Elm St, City B        |7000     |Manager 2      |
      |3       |Warehouse C     |789 Oak St, City C        |6000     |Manager 3      |
      |4       |Warehouse D     |101 Pine St, City D       |8000     |Manager 4      |
      |5       |Warehouse E     |202 Maple St, City E      |4500     |Manager 5      |
      |6       |Warehouse F     |303 Birch St, City F      |5500     |Manager 6      |
      |7       |Warehouse G     |404 Cedar St, City G      |7500     |Manager 7      |
      |8       |Warehouse H     |505 Walnut St, City H     |6500     |Manager 8      |
      |9       |Warehouse I     |606 Cherry St, City I     |9000     |Manager 9      |
      |10      |Warehouse J     |707 Beech St, City J      |8500     |Manager 10     |
      excutor return 10 rows
      • 库存信息数据表
        CREATE TABLE inventory ( product_id varchar,    product_name varchar,     sku varchar,     category varchar,     quantity integer ,  min_stock integer ,  max_stock integer ,  w_id integer ,  location varchar, last_received varchar,  last_sold varchar,  created_at varchar,  updated_at varchar ) ;


        INSERT INTO inventory VALUES ('P001', 'Smart Watch', 'SKU001', 'Electronics', 150205001, 'A1-01', '2023-10-01', '2023-10-10', '2023-10-15 10:00:00', '2023-10-15 10:00:00');
        INSERT INTO inventory VALUES('P002', 'Bluetooth Headset', 'SKU002', 'Audio', 200306001, 'A1-02', '2023-10-02', '2023-10-11', '2023-10-15 10:05:00', '2023-10-15 10:05:00');
        INSERT INTO inventory VALUES('P003', 'Wireless Charger', 'SKU003', 'Accessories', 80103002, 'B2-03', '2023-10-03', '2023-10-12', '2023-10-15 10:10:00', '2023-10-15 10:10:00');
        INSERT INTO inventory VALUES('P004', 'Tablet', 'SKU004', 'Electronics', 120154002, 'B2-04', '2023-10-04', '2023-10-13', '2023-10-15 10:15:00', '2023-10-15 10:15:00');
        INSERT INTO inventory VALUES('P005', 'Gaming Keyboard', 'SKU005', 'Peripherals', 90253503, 'C3-05', '2023-10-05', '2023-10-14', '2023-10-15 10:20:00', '2023-10-15 10:20:00');
        INSERT INTO inventory VALUES('P006', 'Mechanical Mouse', 'SKU006', 'Peripherals', 110204503, 'C3-06', '2023-10-06', '2023-10-15', '2023-10-15 10:25:00', '2023-10-15 10:25:00');
        INSERT INTO inventory VALUES('P007', 'HD Webcam', 'SKU007', 'Imaging', 70152504, 'D4-07', '2023-10-07', '2023-10-10', '2023-10-15 10:30:00', '2023-10-15 10:30:00');
        INSERT INTO inventory VALUES('P008', 'Portable Speaker', 'SKU008', 'Audio', 180255504, 'D4-08', '2023-10-08', '2023-10-11', '2023-10-15 10:35:00', '2023-10-15 10:35:00');
        INSERT INTO inventory VALUES('P009', 'Fitness Tracker', 'SKU009', 'Health', 130304505, 'E5-09', '2023-10-09', '2023-10-12', '2023-10-15 10:40:00', '2023-10-15 10:40:00');
        INSERT INTO inventory VALUES('P010', 'Smart Glasses', 'SKU010', 'Wearables', 60102005, 'E5-10', '2023-10-10', '2023-10-13', '2023-10-15 10:45:00', '2023-10-15 10:45:00');
        • 查看数据库中的数据。
          miniToad <# select * from inventory;
          |product_id |product_name          |sku        |category        |quantity |min_stock |max_stock |w_id    |location  |last_received  |last_sold      |created_at              |updated_at              |
          |P001       |Smart Watch           |SKU001     |Electronics     |150      |20        |500       |1       |A1-01     |2023-10-01     |2023-10-10     |2023-10-15 10:00:00     |2023-10-15 10:00:00     |
          |P002       |Bluetooth Headset     |SKU002     |Audio           |200      |30        |600       |1       |A1-02     |2023-10-02     |2023-10-11     |2023-10-15 10:05:00     |2023-10-15 10:05:00     |
          |P003       |Wireless Charger      |SKU003     |Accessories     |80       |10        |300       |2       |B2-03     |2023-10-03     |2023-10-12     |2023-10-15 10:10:00     |2023-10-15 10:10:00     |
          |P004       |Tablet                |SKU004     |Electronics     |120      |15        |400       |2       |B2-04     |2023-10-04     |2023-10-13     |2023-10-15 10:15:00     |2023-10-15 10:15:00     |
          |P005       |Gaming Keyboard       |SKU005     |Peripherals     |90       |25        |350       |3       |C3-05     |2023-10-05     |2023-10-14     |2023-10-15 10:20:00     |2023-10-15 10:20:00     |
          |P006       |Mechanical Mouse      |SKU006     |Peripherals     |110      |20        |450       |3       |C3-06     |2023-10-06     |2023-10-15     |2023-10-15 10:25:00     |2023-10-15 10:25:00     |
          |P007       |HD Webcam             |SKU007     |Imaging         |70       |15        |250       |4       |D4-07     |2023-10-07     |2023-10-10     |2023-10-15 10:30:00     |2023-10-15 10:30:00     |
          |P008       |Portable Speaker      |SKU008     |Audio           |180      |25        |550       |4       |D4-08     |2023-10-08     |2023-10-11     |2023-10-15 10:35:00     |2023-10-15 10:35:00     |
          |P009       |Fitness Tracker       |SKU009     |Health          |130      |30        |450       |5       |E5-09     |2023-10-09     |2023-10-12     |2023-10-15 10:40:00     |2023-10-15 10:40:00     |
          |P010       |Smart Glasses         |SKU010     |Wearables       |60       |10        |200       |5       |E5-10     |2023-10-10     |2023-10-13     |2023-10-15 10:45:00     |2023-10-15 10:45:00     |
          excutor return 10 rows

          三、指定值更新 


          最常见得一种用法,更新特定的一行数据,将其中一列的数据更新为指定的常量数据。

            miniToad <update warehouses set name ='warehouse west' where w_id = 1;
            excutor updated 1 rows
              miniToad <select * from warehouses where w_id=1;
              |w_id    |name            |address                   |capacity |manager        |
              |1       |warehouse west  |123 Main St, City A       |5000     |Manager 1      |
              excutor return 1 rows

              四、依赖旧值更新 


              在统计数据时,常用的一种计算总和,或者将某类数据统一增加常数值。

              比如经过产品的改良,产品体积变小,这样各仓库的容量就可以增加,假如仓库号大于5的都会多存储该类产品,容量都会加300。

                ounter(lineounter(line
                miniToad <update warehouses set capacity = capacity + 300 where w_id > 5;
                excutor updated 5 rows

                查看修改结果。

                  miniToad <select w_id, capacity from warehouses;
                  |w_id    |capacity |
                  |1       |5000     |
                  |2       |7000     |
                  |3       |6000     |
                  |4       |8000     |
                  |5       |4500     |
                  |6       |5800     |
                  |7       |7800     |
                  |8       |6800     |
                  |9       |9300     |
                  |10      |8800     |
                  excutor return 10 rows

                  五、更新多列 


                  一次更新多个属性列的值,可以在SET子句中写多个属性列,当然修改的值也可以是依赖其它属性列。

                    miniToad <update warehouses set name='warehouse north',manager='lisa' where w_id=2;
                    excutor updated 1 rows
                    miniToad <select * from warehouses where w_id=2;
                    |w_id    |name            |address                   |capacity |manager        |
                    |2       |warehouse north |456 Elm St, City B        |7000     |lisa           |
                    excutor return 1 rows

                     六、 联合查询下的修改


                    为了更精确的找到要修改的数据行,查询条件更加复杂,会通过多表的联合查询来找到符合条件的数据行。

                    上一个例子只是笼统的指定仓库ID来增加容量,现在通过查询库存表,得知那些仓库存储了改良的产品,只将这些仓库的容量增加。通过仓库和库存表的联合,找到健康类产品的存储5号仓库。

                      miniToad <select w.w_id, capacity, category from warehouses w, inventory i where w.w_id=i.w_id and category = 'Health';
                      |w_id    |capacity |category        |
                      |5       |4500     |Health          |

                      在更新语句中,同样使用联合查询条件,此处仓库表,在UPDATE后面已经指定,FROM子句中就不再重复指定,都会被加到基本表。

                        miniToad <#  update warehouses w set capacity =  capacity + 300 from inventory i where w.w_id=i.w_id and category = 'Health';
                        excutor updated 1 rows

                        更新成功后,再来验证一下结果。

                          miniToad <#  select w.w_id, capacity, category from warehouses w, inventory i where w.w_id=i.w_id and category = 'Health';
                          |w_id    |capacity |category        |
                          |5       |4800     |Health          |
                          excutor return 1 rows

                          七、多属性更新为相同值 


                          在更新语法中,还有一种更新多个属性列为相同值的简写方式。

                          假如将9号仓库的名称和它的管理员名称都修改为相同值,先来查看一下旧值。

                            miniToad <select * from warehouses where w_id=9;
                            |w_id    |name            |address                   |capacity |manager        |
                            |9       |Warehouse I     |606 Cherry St, City I     |9000     |Manager 9      |
                            excutor return 1 rows

                            在更新时,就可以将属性列名称写在列表中,修改值只指定一次。

                              miniToad <update warehouses set (name, manager)='Bruce gold' where w_id=9;
                              excutor updated 1 rows

                              修改成功后,再来验证一下。

                                miniToad <select * from warehouses where w_id=9;
                                |w_id    |name            |address                   |capacity |manager        |
                                |9       |Bruce gold      |606 Cherry St, City I     |9000     |Bruce gold     |
                                excutor return 1 rows
                                🌟 点赞收藏,分享给身边的技术伙伴,关注我们,持续获取数据库内核开发的硬核干货!一起从源码级实现到分布式架构,解锁数据库技术的每一个核心细节!🚀

                                【往期精彩推荐】
                                【手写数据库核心揭秘系列】第105节 UPDATE命令中SET子句的实现细节,复用SELECT类似逻辑,你敢相信吗?

                                【手写数据库核心揭秘系列】第99节 多表联合查询演示,高复杂度查询SQL,四张数据表混合联合类型的查询

                                【手写数据库核心揭秘系列】第90讲 带表达式的select查询结果展示

                                文章转载自开源无限,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                评论