[Project] JSON 데이터를 DB에서 사용하기

do_Rang·2025년 6월 16일

Project

목록 보기
3/7

🤔 문제

프로젝트 진행 중 참조 관계인 테이블의 데이터를 SELECT 해오려고 할 때 고민되는 문제가 생겼다.

프론트에서 조건을 받아오면 해당 조건과 일치하는 데이터를 A테이블에서 가져오고, 가져온 튜플들의 id를 가지고 A와 참조 관계에 있는 B테이블의 데이터를 또 가져와야 했다.

  1. 쿼리를 두 번 전송하게 되면 서버와의 통신이 늘어나고 DB 부하가 커진다. (=속도가 느려진다)
  2. 쿼리 결과가 2개 생기는데, 이를 프론트에 전송하기 위해 다시 예쁘게 조립해야 한다. A테이블의 결과와 그에 맞는 B테이블의 결과를 한 번에 전송해주어야 하기 때문이다.

🚀 DB에서 Object 사용하기

언제나 그렇듯이 정답은 있다!!!!
하나의 컬럼에는 원자값만이 존재할 수 있다고 공부해왔는데..
JSON 데이터를 컬럼 하나에 넣는다면 어떨까?!!!

해당 기능은 Oracle, PostgreSQL, MySQL, MariaDB 등 다양한 DBMS 최신 버전에서 지원하고 있다.

나는 MariaDB 기준으로 작성했다.

주요 JSON 함수

  • JSON_EXTRACT(jsonData, path) : 이미 만들어진 jsonData에서 내가 원하는 요소만 볼 수 있도록 한다. JSON_EXTRACT(데이터, '$.job') 으로 최상위 위치에 있는 객체에서 job이라는 컬람의 결과를 확인할 수 있다.
  • JSON_UNQUOTE(jsonData) : 받은 jsonData의 따옴표를 제거한다. 보통 EXTRACT의 결과가 문자열일 때 순수한 문자열로 변환하기 위해 사용한다.
  • JSON_ARRAYAGG(jsonData) : 받은 jsonData를 하나의 배열로 만든다. AGG는 집계함수라는 뜻
  • JSON_OBJECT(key, value...) : 내가 넘겨준 key, value 형태를 가지고 하나의 JSON 객체를 만든다.
  • JSON_ARRAY(1,2...) : 내가 넘겨준 데이터를 가지고 하나의 JSON 배열을 만든다.

실제로 사용해보기

D 테이블에 있는 내용을 JSON_OBJECT로 만들어서 하나의 배열로 만들어 detail이라는 이름으로 전달했다.

const SQL_SELECT_SCHEDULES = `
    SELECT 
        S.id AS schedulesId,
        S.day,
        S.start_time AS startTime,
        JSON_ARRAYAGG(
            JSON_OBJECT(
                'detailId', D.id,
                'placeId', D.place_id,
                'orderBy', D.order_by,
                'playTime', D.play_time,
                'moveTime', D.move_time
            )
        ) AS detail
    FROM schedules S LEFT JOIN schedule_detail D ON S.id = D.schedule_id
    WHERE S.map_id = ?
    GROUP BY S.id, S.day, S.start_time
    ORDER BY S.day
`;

쿼리 result에서 JSON 데이터 사용은 다음과 같다.
JSON_ARRAYAGG의 결과는 문자열 타입으로 반환되어 저장되기 때문에, JSON.parse로 다시 변환하는 작업이 필요했다.

const results = await scheduleService.getSchedules(mapId);

results.forEach((item) => {
  item.detail = JSON.parse(item.detail);
});

🤗 결론

  • 기존 결과보다 구조화된 데이터를 얻을 수 있어서 좋다고 느껴진다.
  • 프론트에 데이터를 넘기기 위해 새 Object를 만들지 않아도 깔끔하다는 것이 제일 좋았다. 👍
profile
공부하자

0개의 댓글