데이터 정규화 들어가기

7과11사이·2025년 5월 29일

'진짜 망했다.'
이 말만 몇 번을 되뇌었는지 모르겠다.
프로젝트를 진행하면서 대부분은 부딪히면서 배우거나, 테스트 삼아 코드를 짜보거나, 검색을 통해서 해결을 했다. 하지만 역시 그동안 작은 단위의 프로젝트만 해서 그런지 대량의 데이터를 처리할 때 어떻게 해야할지 감도 못 잡고 있는게 요 며칠간의 내 이야기다.

오늘은 그 중, 데이터를 올바르게 필터링하는 방법 중 처음 배운 데이터 정규화 관련해서 정리해본다.
(분명 짬짬이 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를 맵핑하는 방식도 있어보였다...
이건 어떤 내용인지 조금 더 알아봐야겠다!

참고 링크

0개의 댓글