다섯번째 기업과제는 임상정보를 수집하는 batch와
수집한 데이터를 이용해 사용자에게 검색 기능을 제공하는 API를 구현하는 것이었다.
처음 DB 설계 회의에서 우리는 임상정보를 저장하는 방식을
재복님의 의견으로 조금 다르게 저장해보기로 하였다.
하나의 레코드에 하나의 임상정보를 저장하는 것이 아니라
여러개의 임상정보를 하나의 레코드에 저장하는 것이었다.
sqlite를 사용해야하는 조건이었는데, RDB인 것을 고려했을때
이 방식이 정말 효율적인가에 대한 고민은 마지막에 해보기로 하자.
이번 과제는 요구사항이 그렇게 많지 않았다.
우리는 batch, pagination 두 팀으로 나누어 진행하였고
나는 batch에 배치되었다. 🤣
처음엔 금방 끝날 것이라 생각했는데 언제나 그렇듯 그렇지 않았다는 것은 안비밀
어쨋든 나는 바다님이랑 같이 작업을 진행했다.
우리는 임상정보를 제공해주는 API를 통해
데이터를 불러와서 우리의 DB에 저장하는 작업을 하면 됐었다.
임상 정보는 배열로 되어있었고 전 날과 비교해 수정된 임상정보를 업데이트하거나
최근 일주일간 업데이트 된 임상정보 리스트를 실시간으로 제공할 때
배열안의 각 객체를 식별하고 중복을 제거하는 과정이 필요했다.
바다님과 나는 애초에 이 정보를 저장할 때 객체로 만들어
키값을 부여하면, 이후에 중복을 제거할 때 더 효율적일 것이라는 결론을 내렸다.
그리고 바다님과 나는 또 작업을 하다가 이런 고민을 하게 되었는데
사용자에게 최근 일주일간 업데이트 된 임상정보 리스트를 실시간으로 제공할 때 중복을 제거 하는 과정이
batch에서 이루어져야 하는 과정이라는 생각이었다.
우리는 처음에 업데이트 된 임상정보 리스트를 이런식으로 설계했다.
1일: A, B
1일자 업데이트: A, B
2일: A, B, C
2일자 업데이트: C
3일 A`, B, C
3일자 업데이트: A`
업데이트 테이블
1일: A, B
2일: C
3일: A`
그리고 사용자에게 최근 3일간의 업데이트 리스트를 제공 할 때
업데이트 테이블에서, 당일을 기준으로 3일 전까지의 데이터를 가져와서
[ A, B, C, A` ]
A가 중복되므로, 가장 최신의 A`만 남기는 작업을 해야했다.
이 작업을 매번 사용자에게 제공될 API에서 하지 않고
당일 사용자에게 보여줄 업데이트 리스트 테이블을 하나 더 추가하고
batch task를 수행할 때 미리 당일의 업데이트 리스트를 만들어 제공하기로 했다.
업데이트 리스트를 따로 관리하는 이유는
현재 요구하는 업데이트 리스트는 7일전까지 이지만
도중에 3일, 혹은 10일로 변경될 수도 있기에 확장성을 고려하였기 때문이다.
우리는 배치 중간에 서버가 다운되면
처음부터 다시 작업을 시작하는 것이 아닌
마지막 수행되었던 부분부터 다시 시작되도록
구현할 수 있을까 고민하였다.
우리는 한번의 호출로 50개의 임상정보를 가져올 수 있었고
모든 데이터를 다 불러온 후 하나의 객체로 합쳐 DB에 저장하는 방식으로 구현이 되었는데
중간 과정을 기억하기 위해서는
50개의 임상정보를 호출할 때 마다 어딘가에 임시로 정보를 저장해야했다.
결론은 중간에 정지된 서버의
임시 저장된 데이터가 유효성을 보장하지 못하므로
현재 구조에서는 구현이 힘들거라는 재복님의 의견에
리팩토링과 테스트코드 작업이 한창 남은 상황이어서
이 고민은 숙제 서랍안에 넣어놓았다.
이번 과제에서 좋았던 점은
새로운 것을 많이 접하고, 생각해볼 수 있었다는 것과 ( batch, lodash, for대신 reduce, promiseAll, 등.. )
좀더 데이터베이스를 효율적으로 다루는 방법에 대해 고민하면서 데이터베이스와 친해지는 시간을 가졌던 것이다.
후자가 내게는 제일 의미있었던 부분인데,
백엔드 개발자로서 데이터베이스에 대한 이해는 필수라는 것을 체감했기 때문이다.
혼자서 프로젝트를 진행할 때는 아직 데이터베이스 설계를 고민하는 단계까지는 가지 못했었다. 🤭
이번 프로젝트를 마친 후 내게 남은 숙제는
현재 사용중인 데이터베이스가 관계형이라는 것을 고려할때
정말 하나의 row에 수많은 데이터를 저장하는 것이 여러개의 row로 관리하는 것보다 효율적인가?
(DB에 요청을 한번만 보낸다, index 용량을 절약한다.)
조회시 성능은?
이런 작업에는 RDB보다 Nosql이 적합한가?
등등.. 여러 궁금증이 남아있지만
바로 다음 과제가 있기에 지금 이 글에 다 정리할 정도로 공부할 시간은 없다. 😇
혹시나 해서 열심히 찾아보았지만 이런 경우에 대해서 찾기 어려웠다.
직접 공부하며 스스로 파악하는게 나을 것 같다. 튜닝같은 것을 공부하면 자연스레 알게 될 것 같다.
배치 중간에 서버가 다운시
마지막 수행되었던 부분부터 다시 시작되도록
이 부분도 시도해보지 못한 것이 아쉬웠는데 지금 떠오르는 생각은
텍스트 형식으로, 혹은 인메모리 DB를 하나 더 추가하여
새로 불러온 임상정보들과, 저장에 성공한 페이지 번호를 저장해놓는 것이다.
물론 배치가 성공적으로 완료되면 임시저장된 데이터는 삭제한다.
혹시나 다음에 기회가 된다면 한번 도전해 보아야겠다 :D
프리온보딩 코스는 짧은 시간에 많은 것을 경험하고 어떤 것을 공부해야 할지 알게 해주기에 참 의미있는 것 같다 :)
결과물
https://github.com/preOnboarding-Team13/Assignment-5-humanscape
P.S
블로그 포스팅을 하며, 작성된 코드를 조금씩 리팩토링 해보았는데
리팩토링한 코드가 잘 작동 되는지 검증하는 과정에서
유닛 테스트 코드의 효율성을 완전 체감 해버렸다.
유닛 테스트는 기능 단위의 독립적인 테스트이기에 배치를 돌리거나 할 필요가 없따.
아직 테스트코드 작성과 리팩토링에 시간이 많이 소요된다.
여러 프로젝트를 진행하며 테스트 코드 작성과 리팩토링을 할 기회가 많아져서 좋은 훈련이 되는 것 같다 :D
'개발 공부' 카테고리의 다른 글
마지막 기업과제 회고록 (0) | 2021.12.05 |
---|---|
여섯번째 기업 과제 회고록 (Deer) (0) | 2021.11.22 |
원티드x위코드 프리온보딩 네번째 기업과제 (에잇퍼센트) 회고록 (0) | 2021.11.15 |
원티드x위코드 프리온보딩 세번째 기업과제 (Red Brick) 회고록 (0) | 2021.11.11 |
원티드x위코드 프리온보딩 두번째 기업과제 (Mapia Company) 회고록 (0) | 2021.11.08 |