zoukankan      html  css  js  c++  java
  • 【MySQL】下发功能SQL

    SQL参考文章:

    https://www.jb51.net/article/15627.htm

    下发,就是从别的表中同步数据到此表中,也可能是来自不同库的表,或者不同实例的表

    下发的逻辑要求:如果没有则是做插入,存在冲突的记录,则需要覆写更新,同时下发表要做出标记,不能重复下发,下发过的记录要做标记

    案例:

    A表:

    CREATE TABLE `a` (
      `ID` int NOT NULL AUTO_INCREMENT,
      `A` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL,
      `B` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL,
      `C` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL,
      PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

    B表:

    CREATE TABLE `b` (
      `ID` int NOT NULL AUTO_INCREMENT,
      `D` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL,
      `E` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL,
      `F` varchar(36) COLLATE utf8mb4_general_ci DEFAULT NULL,
      PRIMARY KEY (`ID`)
    ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

    首先A插入数据,然后下发给B表:

    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (1, '1', '1', '1');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (2, '2', '2', '2');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (3, '3', '3', '3');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (4, '4', '4', '4');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (5, '5', '5', '5');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (6, '6', '6', '6');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (7, '7', '7', '7');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (8, '8', '8', '8');
    INSERT INTO `my-info`.`a` (`ID`, `A`, `B`, `C`) VALUES (9, '9', '9', '9');

    B表为空,则可以直接向里面插入即可:(把A的全部数据向B表写入,主键为自增,不需要加入)

    INSERT INTO `my-info`.`b` (`D`, `E`, `F`) SELECT `A`, `B`, `C` FROM `my-info`.`a`

    现在A和B表一样的数据, 更新一条A表的数据:

    UPDATE `my-info`.`a` SET `A` = '100', `B` = '100', `C` = '100' WHERE `ID` = 5;

    A表 5ID的记录是100

    +----+-----+-----+-----+
    | ID | A   | B   | C   |
    +----+-----+-----+-----+
    |  1 | 1   | 1   | 1   |
    |  2 | 2   | 2   | 2   |
    |  3 | 3   | 3   | 3   |
    |  4 | 4   | 4   | 4   |
    |  5 | 100 | 100 | 100 |
    |  6 | 6   | 6   | 6   |
    |  7 | 7   | 7   | 7   |
    |  8 | 8   | 8   | 8   |
    |  9 | 9   | 9   | 9   |
    +----+-----+-----+-----+
    9 rows in set (0.04 sec)

    把A的表记录下发到B表,操作:(全选A表的记录,包括主键或者约束键字段,写入到B表中,在主键发生冲突时,更新字段)

    INSERT INTO `my-info`.`b` (`ID`, `D`, `E`, `F`) 
    SELECT `ID`, `A`, `B`, `C` FROM `my-info`.`a`
    ON DUPLICATE KEY UPDATE `D` = `A`, `E` = `B`, `F` = `C`

    SQL语法是支持的

    > Affected rows: 2
    > 时间: 0.17s

    查看B表,结果是修改了五ID的记录

    mysql> SELECT * FROM `my-info`.`B`;
    +----+-----+-----+-----+
    | ID | D   | E   | F   |
    +----+-----+-----+-----+
    |  1 | 1   | 1   | 1   |
    |  2 | 2   | 2   | 2   |
    |  3 | 3   | 3   | 3   |
    |  4 | 4   | 4   | 4   |
    |  5 | 100 | 100 | 100 |
    |  6 | 6   | 6   | 6   |
    |  7 | 7   | 7   | 7   |
    |  8 | 8   | 8   | 8   |
    |  9 | 9   | 9   | 9   |
    +----+-----+-----+-----+
    9 rows in set (0.07 sec)

    -- 实现不重复下发的逻辑问题:

    A表再追加一个下发标记字段,在执行下发SQL的时候,筛选这个下发条件

    INSERT INTO `my-info`.`b` (`ID`, `D`, `E`, `F`) 
    SELECT `ID`, `A`, `B`, `C` FROM `my-info`.`a` WHERE `下发标记字段` = '未下发的状态值'
    ON DUPLICATE KEY UPDATE `D` = `A`, `E` = `B`, `F` = `C`

    执行下发之后,要更新A表的下发状态:

    把标记为未下发的记录,更新为已下发

    UPDATE `my-info`.`a` SET `下发标记字段` = '已下发的状态值' WHERE `下发标记字段` = '未下发的状态值';

    以避免重复进行下发,或者是业务逻辑指定的区分方式来实现

    另一种情况:

    ON DUPLICATE KEY UPDATE

    更新操作是依据这个SQL组合实现,即重复的Key

    Key可以是主键,或者是索引。

    主表的单列主键不需要下发到下发表,但是需要其他其他关键字段触发DUPLICATE KEY 

    可以对字段添加唯一索引实现(唯一索引允许字段NULL值,需要字段设置NOT NULL限制)

    ALTER TABLE `table_name` ADD UNIQUE unq_col1_col2 (`column1`, `column1`);

    通过UNIQUE索引触发 DUPLICATE实现更新操作

    删除索引:

    drop index index_name on table_name ;
    
    alter table table_name drop index index_name ;
  • 相关阅读:
    Problem 1014 xxx游戏 暴力+拓扑排序
    Codeforces Beta Round #10 D. LCIS
    HDU 1423 Greatest Common Increasing Subsequence LCIS
    Codeforces Round #349 (Div. 1) A. Reberland Linguistics dp
    BZOJ 3875: [Ahoi2014]骑士游戏 dp+spfa
    Codeforces Round #360 (Div. 2) E. The Values You Can Make 01背包
    Codeforces Round #360 (Div. 2) D. Remainders Game 中国剩余定理
    UVALive 4872 Underground Cables 最小生成树
    POJ 1182 食物链 并查集
    山东省第六届ACM省赛
  • 原文地址:https://www.cnblogs.com/mindzone/p/15588417.html
Copyright © 2011-2022 走看看