MySQL多个表的关联字段实现同步更新的解决方案 |
1. 背景在对数据库表结构进行设计时,为了提高查询效率,会进行一些反规范化设计,如:设计一些冗余字段 。但这样可能会存在数据同步问题,当源表字段值更新时,冗余字段值也需要同步更新 。 现有产品表 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 = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; INSERT INTO `product` VALUES (1, '产品A'); INSERT INTO `product` VALUES (2, '产品B'); INSERT INTO `product` VALUES (3, '产品C'); 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_0900_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'); 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'); 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, newProductName); // 同步更新 auth_server_product 表 authServerProductRepository.updateProductName(oldProductName, newProductName); }
2.2 利用MySQL提供的触发器功能MySQL 提供了触发器功能,在随某个表进行记录的新增( 针对上述场景中的这个问题,可以在 2.2.1 具体实现
Step 1 : 创建触发器 设计 procut 表,点击触发器,定义触发器的名称,类型选择 Step 2 : SQL 定义触发器行为 编写具体的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 Step 3 : 验证
update product set productName = '产品AA' where id = '1'
2.2.2 关于触发器
以上就是MySQL多个表的关联字段实现同步更新的解决方案的详细内容,更多关于MySQL关联字段同步更新的资料请关注其它相关文章! |