'진짜 망했다.'
이 말만 몇 번을 되뇌었는지 모르겠다.
프로젝트를 진행하면서 대부분은 부딪히면서 배우거나, 테스트 삼아 코드를 짜보거나, 검색을 통해서 해결을 했다. 하지만 역시 그동안 작은 단위의 프로젝트만 해서 그런지 대량의 데이터를 처리할 때 어떻게 해야할지 감도 못 잡고 있는게 요 며칠간의 내 이야기다.
오늘은 그 중, 데이터를 올바르게 필터링하는 방법 중 처음 배운 데이터 정규화 관련해서 정리해본다.
(분명 짬짬이 CS 공부할 때 찾아봤던 기억이 나지만... 실전은 백지뿐이었다...)
데이터 정규화는 간단히 말하면 flat() 같은 고차함수와 같은 흐름으로 이해된다.
중첩된 데이터 구조를 하나의 평평한 구조로 바꾸는 행위를 뜻하는데, 데이터 구조를 단순하게 만드는 표현을 '정규화'라고 부르고 있었다.
그렇다면 왜 이 의미를 'Nomalization'으로 정리를 했을까..?
정규화는 데이터를 특정 범위로 변환해서 범위를 일치시키는 작업이라고 하는데, 중첩 형태가 아닌 바로 접근 가능한 구조로 만듦으로써 속도면이나 편리성에 우위가 있다고 이해할 수 있다. 따라서 겹겹이 쌓인 데이터는 '복잡'하기에 '정상'이라는 표현을 쓰는게 아닐까 싶다.
데이터가 그렇게 복잡한게 아니지 않았을까..?
사실 그동안 Swift에 참여한 프로젝트는 데이터 양이 많지 않았다.
(적어도 많이 받지 않으려고 가공을 많이 했던 기억이 난다)
'필요한 데이터만 가져와야지, 불필요한 데이터까지 한번에 왜 들고와야 할까?'라는 생각이 지배적이었다.
하지만 지금 프로젝트에서 느끼는 점은 모든 데이터 하나 하나 소중하다.
하지만 하나하나 쌓다보니 한 아이템 항목에 80가지가 넘는 가짓 수, 그것도 중첩으로 들어간 형식을 보면서 이런 상황에서 데이터 필터링은 어떻게 해야 될지 고민이 참 많이 들었다. (사실 감도 잘 안왔다 - 아직도...)
중첩 데이터 정규화
그래도 하나의 블로그를 읽으면서 복잡하게 생각하면 안되겠다는 판단을 내렸다.
나름 비슷하게 더미 형식으로 데이터를 정규화해보았다. (마지막엔 gpt의 의견도 받긴했다만...)
지금 내 상황과 완전히 떨어지는 데이터 구조는 아니었지만, 아주 조금은 어떻게 해야될지 살짝 옅본 느낌이다.🔨 변형 테스트 전 구조
{ "company": [ { "id": 1, "name": "나이O", "posts": [ { "id": 101, "title": "마이클 조던의 신화" }, { "id": 102, "title": "와플 밑창" } ] }, { "id": 2, "name": "아디O스", "posts": [ { "id": 103, "title": "축구화 원조" } ] } ] }🫠 변형 테스트 후 구조
{ company: { 1: { id: 1, name: "나이O", postIds: [101, 102] }, 2: { id: 2, name: "아디O스", postIds: [103] } }, posts: { 101: { id: 101, title: "마이클 조던의 신화" }, 102: { id: 102, title: "와플 밑창" }, 103: { id: 103, title: "축구화 원조" } } }변형 테스트 코드
const flatData = (data) => { const data = { company: {}, posts: {} } data.company.forEach(comp => { const { id, name, posts } = company; posts.forEach(post => { data.posts[post.id] = post; }) data.company[id] = { id, name, postId: posts.map(post => post.id) }; }); return data; }
담아놓고자 하는 데이터 형식을 하나의 객체로 생성한 이후,
각 데이터 항목별로 돌면서 data에 생성한 2개의 객체 속에 알맞게 배치하는 형태로 구성됐다.
찾은 예시 중, Object로 생성해서 value 혹은 key를 맵핑하는 방식도 있어보였다...
이건 어떤 내용인지 조금 더 알아봐야겠다!