开发者

MySQL多个表的关联字段实现同步更新的解决方案

目录
  • 1. 背景
    • 1.1 表结构定义
      • 1.1.1 product 表
      • 1.1.2 auth_server_product 表
      • 1.1.3 mobile_version 表
  • 2. 解决方案
    • 2.1 应用层代码中更新
      • 2.2 利用mysql提供的触发器功能
        • 2.2.1 具体实现
        • 2.2.2 关于触发器

    1. 背景

    在对数据库表结构进行设计时,为了提高查询效率,会进行一些反规范化设计,如:设计一些冗余字段。但这样可能会存在数据同步问题,当源表字段值更新时,冗余字段值也需要同步更新。

    现有产品表 product ,移动端版本 mobile_version ,授权绑定产品表auth_server_product 三个表,这三个表有一个共同字段 productName,期望当 pythonproduct 表中的 productName 字段的值改变时,将该字段修改后的值同步更新到 mobile_version,auth_server_product 两个表中。

    1.1 表结构定义

    1.1.1 product 表

    CREATE TABLE `product`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `productName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mbandroid4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
    
    INSERT INTO `product` VALUES (1, '产品A');
    INSERT INTO `pphproduct` VALUES (2, '产品B');
    INSERT INTO `product` VALUES (3, '产品C');
    

    MySQL多个表的关联字段实现同步更新的解决方案

    1.1.2 auth_server_product 表

    CREATE TABLE `auth_server_product`  (
      `id` int(0) NOT NULL,
      `authId` int(0) NULL DEFAULT NULL,
      `productId` int(0) NULL DEFAULT NULL,
      `productName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_09python00_ai_ci ROW_FORMAT = Dynamic;
    
    INSERT INTO `auth_server_product` VALUES (1, 1, 1, '产品A');
    INSERT INTO `auth_server_product` VALUES (2, 1, 2, '产品B');
    INSERT INTO `auth_server_product` VALUES (3, 1, 3, '产品C');
    

    MySQL多个表的关联字段实现同步更新的解决方案

    1.1.3 mobile_version 表

    CREATE TABLE `mobile_version`  (
      `id` int(0) NOT NULL,
      `mobile_version` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
      `productId` int(0) NULL DEFAULT NULL,
      `productName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
    
    
    INSERT INTO `mobile_version` VALUES (1, 'V1.0.0', 1, '产品A');
    INSERT INTO `mobile_version` VALUES (2, 'V1.0.1', 1, '产品A');
    

    MySQL多个表的关联字段实现同步更新的解决方案

    2. 解决方案

    2.1 应用层代码中更新

    代码层实现数据同步逻辑,在更新 product 表中的 productName 字段时,同步更新auth_server_product 与 mobile_version 两表中的字段值。大致逻辑如下:

    @Transactional
    public void updateProductName(String oldProductName, String newproductName) {
        // 更新 product 表中的 productName
        productRepository.updateProductName(oldProductName, newProductName);
        
        // 同步更新 mobile_version 表
        mobileVersionRepository.updateProductName(oldProductName, nwww.devze.comewProductName);
    
        // 同步更新 auth_server_product 表
        authServerProductRepository.updateProductName(oldProductName, newProductName);
    }
    

    该种方案的劣势

    • 代码复杂,耦合性强;
    • 数据不一致:如果同步逻辑没有被正确实现或处理,可能会导致数据不一致。

    2.2 利用MySQL提供的触发器功能

    MySQL 提供了触发器功能,在随某个表进行记录的新增(INSERT)、修改(UPDATE) 或是删除( DELETE) 操作时,会自动触发相应的操作。

    针对上述场景中的这个问题,可以在 product 表设置触发器,在 UPDATE 操作时,通过触发器来同步更新 mobile_versionauth_server_product 表中的 productName 字段。

    2.2.1 具体实现

    Navicat 为例进行演示

    Step 1 : 创建触发器

    设计 procut 表,点击触发器,定义触发器的名称,类型选择AFTER UPDATE,表示在product 表中的 productName 更新后 同步更新其他表。

    Step 2 : SQL 定义触发器行为

    编写具体的SQL语句定义触发器行为,在这个例子中,期望在 productName 更新时,自动更新 mobile_versionauth_server_product 表中的 productName。SQL 下:

    BEGIN
        -- 如果 productName 发生变化
        IF OLD.productName <> NEW.productName THEN
            -- 更新 mobile_version 表中的 productName
            UPDATE mobile_version
            SET productName = NEW.productName
            WHERE productName = OLD.productName;
            
            -- 更新 auth_server_product 表中的 productName
            UPDATE auth_server_product
            SET productName = NEW.productName
            WHERE productName = OLD.productName;
        END IF;
    END 
    

    MySQL多个表的关联字段实现同步更新的解决方案

    Step 3 : 验证

    • show triggers,可查看当前数据库中的触发器,验证触发器是否创建成功。

    MySQL多个表的关联字段实现同步更新的解决方案

    • 执行更新语句,验证触发器的定义能否达到期望的效果。
    update product set productName = '产品AA' where id = '1'
    

    MySQL多个表的关联字段实现同步更新的解决方案

    MySQL多个表的关联字段实现同步更新的解决方案

    MySQL多个表的关联字段实现同步更新的解决方案

    可以看到,当 product 表中的 productName 值更新后,mobile_version 与 auth_server_product 对应的 productName 值同步更新。

    2.2.2 关于触发器

    • 触发事件:触发器会在某个特定事件发生时被触发。常见的触发事件包括:

      • INSERT:在插入数据时触发。
      • UPDATE:在更新数据时触发。
      • DELETE:在删除数据时触发。
    • 触发时机:触发器可以定义在数据事件发生的 BEFORE)或 AFTER)执行。

      • BEFORE:触发器在数据变更之前执行。
      • AFTER:触发器在数据变更之后执行。
    • 触发器的作用域:触发器通常绑定到某个表上,并且只能在该表的数据操作时触发。它不能跨表执行,也不能直接返回数据。

    以上就是MySQL多个表的关联字段实现同步更新的解决方案的详细内容,更多关于MySQL关联字段同步更新的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新数据库

    数据库排行榜