DB의 변경 데이터 실시간 모니터링 하는 웹 화면 구현

조회수 16580회

안녕하세요.

오랜만에 막힘을 해결하기 위해 해시코드를 찾아왔습니다.

항상 답변 고맙습니다.

node.js 환경에서 개발 중입니다.

mysql를 사용 중이고, 예를 들면 tb_test 테이블에서 msg, value 컬럼을 생성하였습니다.

<tb_test>
no(pk)    msg     value 

1        'test'    1 

2        'hello    32

위처럼 데이터가 삽입되어 있을 때,

pk 1의 value가 1 에서 382 로 업데이트 된다던가

pk 3의 새로운 튜플이 생성된다던가

경우를 실시간으로 감지하여 웹 사용자에게 모니터링 할 수 있도록 구현하려고 합니다.

현재 socket.io 를 사용하여,

<index.html>
var socket = io();
            $('#add_status').click(function() {
                socket.emit('status added', $('#comment').val());
            });

            socket.on('refresh feed', function(msg) {
                $('#show_comments').append(msg + '<br /><br />');
            });
<app.js>
io.on('connection', function(socket) {
  console.log('A user is connected');

  socket.on('status added', function(status) {

    add_status(status, function (res) {
      if (res) {
        io.emit('refresh feed', status);
      } else {
        io.emit('error');
      }
    });

  });

});

var add_status = function (status, callback) {
  pool.getConnection( function (err, conn) {
    if (err) {
      callback (false);
      return;
    }

    const insertQuery = ' INSERT INTO tb_test (msg, createdAt) VALUES '
                      + ' ( ' 
                      + mysql.escape(status) 
                      + ' , now() '
                      + ' ) ';

    console.log(insertQuery);

    conn.query(insertQuery, function (err, rows) {
      conn.release();

      if (!err) {
        callback (true);
      }

    });

    conn.on('error', function (err) {
      callback (false);
      return;
    });

  });
}

같은 방법으로 웹에서 메시지를 입력 후 버튼을 누르면,

입력한 메시지를 db에 저장함과 동시에 웹에서 <div id="show_comments"></div> 에 삽입하여 보여주도록 하는 것 까지는 구현할 수 있었습니다.

DB 데이터의 변경(insert, update, delete)시 그것을 감지하여 웹에 보여주려면 어떻게 해야 하는지 조언 부탁 드리겠습니다.

4 답변

  • 좋아요

    2

    싫어요
    채택 취소하기

    html5 의 웹소켓을 이용해서 접속된 클라이언트들에 데이터를 push(broadcast)할 수 있습니다.

    mysql 의 trigger를 사용해서 데이터 변경시 콜백처리를 할 수 있습니다.

    http url을 호출 가능하도록 mysql udf를 만들고 trigger에서 해당 udf를 호출하여 서버쪽에 변경된 데이터등을 전송할 수 있습니다. 서버에서는 받은 데이터를 웹소켓에 연결되어 있는 클라이언트들에게 push 할 수 있습니다.

    예전에는 실시간 웹의 구현을 comet 기술로 long polling등을 사용했으나 html5 가 표준인 지금에서는 웹소켓으로 편하게 구현할 수 있습니다.

    • 이제 봤네요 답변 감사합니다! 결국 디비쪽 트리거를 이용하는 방법 밖에 없는 것 같군요. mysql 이 될수도 있고 mssql 이 될 수도 있는 상황인데요. / 10초, 30초, 60초 등 한 번씩 갱신하여 실시간으로 보여주는 형태도 충분한 성능을 낼 수 있을 것 같은데, socket.io 와 setInterval ? 을 같이 사용하면 구현할 수 있을까요? 상남자 2017.4.15 22:45
    • 폴링을 하는 형태는 좋은 방법이 아닙니다. 변경이 없는 상황인데도 계속 부하를 줄 수밖에 없는 구조이고 다수의 클라이언트가 연결되어 있는 상황이면 더더욱 악영향이 될 수 밖에 없는 구조입니다. 웹소켓이 다루기 어려운 기술이 아니니 학습을 진행해보시면 좋을 듯 합니다. 정영훈 2017.4.17 12:15
  • 전제조건이 DB데이터의 변경이라면 이벤트가 발생되는 주체는 DB서버가 되어야 겠죠. 이런 생각을 저도 해본적이 없어서리 자료를 찾아보니 트리거가 있더군요 https://dev.mysql.com/doc/refman/5.6/en/trigger-syntax.html

    한군데 테이블에 변경이력을 모아놓고 그걸 화면에 보여주면 구현은 가능할 것으로 보입니다.

    아니면 mysql의 로그를 뒤져 실행된 SQL구문을 분석하여 데이터를 수집하는 방법도 있겠네요.

    http://kimyongjin.com/post/631

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 음 좀 복잡해지는 것 같군요. 그렇다면 간단히 구현할 경우 인터벌로 1초, 5초 등을 주어 현재 값과 데이터베이스 값을 비교하여 변경된지 확인한 후 변경 되었으면 업데이트 해주는 방법으로도 가능할지요? 상남자 2017.4.13 14:34
  • 가장 단순한 방법으로는

    데이터가 크지 않다면 Object 식으로 DataSet을 JS 로 들고 있고, 바뀐 부분만 키/데이터 받아서 업데이트...

    Last_Update 컬럼 같은걸로 sysdate()를 넣고 마지막으로 DB 쿼리한 시간 이후로 하거나, UPDATE/INSERT 시 FLAG Column을 넣는 방법도 있을 것 같네요.

    감사합니다.

    • (•́ ✖ •̀)
      알 수 없는 사용자
  • node.js의 사례는 모르지만 Ruby on Rails라면 이렇게 할 것 같아 의견드립니다.

    어차피 Insert/Update/Delete 명령을 node.js에서 날리는것 아닌가요? 그렇다면 서버에서 처리할 수도 있겠습니다. 해당 테이블의 값 변경을 담당하는 특정 클래스를 하나 만들고 거기에서 변경이 있을때 원하는 처리를 해 주는거지요.

    Ruby on Rails의 경우 모델을 통해서 DB의 테이블에 값을 쓰는데요. DB의 값이 변경될 때 마다 호출되는 메소드가 있습니다.(before_create, before_save 등) 여기서 원하는 작업을 해 주면 되서 편해요.

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)