내 세상

[MySQL] ON DUPLICATE KEY UPDATE 사용 (값이 중복되면 UPDATE, 아니면 INSERT) 본문

Technical/MySQL

[MySQL] ON DUPLICATE KEY UPDATE 사용 (값이 중복되면 UPDATE, 아니면 INSERT)

sga8 2021. 2. 8. 20:12
728x90
반응형

환경

  - Backend: NodeJS (Express)

  - Frontend: React

  - Database: MySQL

 

문제

  - Update Query를 각기 다른 여러개의 where 조건으로 매우 많이 진행해야하는 상황이 생김.

  - 개별로 진행할 경우, Update Timing이 다르기 때문에 실시간 정보를 가져옴에 있어 Delay가 생김.

 

해결

  - Update의 경우 여러개의 where 조건을 사용하여 일괄적으로 사용이 어렵다.

  - 이때, INSERT INTO 구문을 UPDATE 구분처럼 사용할 수 있는 방안이 있음!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  - INSERT INTO를 했을 때, 기존에 Primary key가 겹치는 데이터가 있을 때 특정 칼럼을 업데이트하는 방식임.

    만약 겹치지않을 때는, INSERT INTO를 그대로 진행한다. 그러기 위해서는 !!!!!!!!!!!!!!!!!!

    ON DUPLICATE KEY UPDATE 를 사용한다!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 아래 참고


AS-IS 

 - async.foreach를 사용하여 list를 각기 query를 날려서 진행함.

  db.getConnection(function(err, connection) {
    async.forEach(
      req.body.list,
      function(elem, callback) {
        pstmt = connection.format(
          "UPDATE table set name = ? where class = ? and division = ?",
          [req.body.name, elem[1], elem[0]]
        );
        logInfoMysql(pstmt);
        connection.query(pstmt, function(err) {
          if (err) {
            connection.release();
            callback(err);
          }
          callback();
        });
      },
      function(err) {
        connection.release();
        if (err) {
          logger.error(err.stack);
          res.send({ result: false });
        } else {
          res.send({ result: true });
        }
      }
    );
  });

TO-BE

db.getConnection(function(err, connection) {
    if (err) {
      connection.release();
      logger.error(err.stack);
    } else {
      let values = [];
      for (let i = 0; i < req.body.list.length; i++) {
        let elem = req.body.list[i];
        let temp = [elem.id, req.body.name];
        values.push(temp);
      }

      pstmt = connection.format(
        "INSERT INTO table (id, name) VALUES ? ON DUPLICATE KEY UPDATE name = values(name)",
        [values]
      );
      logInfoMysql(pstmt);
      connection.query(pstmt, err => {
        connection.release();
        if (err) {
          logger.error(err.stack);
          res.send({ result: false });
        } else {
          res.send({ result: true });
        }
      });
    }
  });

 

 

 

728x90
반응형