ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 링크드리스트 구조로 정제 규칙 순서 관리하기
    📖 개발 공부 2023. 12. 20. 00:06

     

    현재 속해있는 팀에서 장소 이름을 정제하는 태스크를 진행하고 있다.

    공공데이터로부터 장소 이름을 가져와서 우리가 만들어놓은 정제 규칙들을 통해 정제하여 데이터화하는 과정이라고 볼 수 있다.

     

    이 정제 과정이 필요한 이유는 크게 두가지가 있다.

     

    1. 깔끔하고 통일성 있는 장소이름을 유저에게 보여주기 위함.
    2. 여러 공공데이터를 통해 데이터화를 하는데, 공공데이터 간 중복 장소가 있을 수 있음.
      정제를 통해 이 중복 장소들을 하나의 장소로만 데이터화하기 위함.

    이러한 이유로 정제 고도화는 우리 팀에서 중요한 태스크이다!

     

    첫 정제 과정에서는, 이상한 패턴들을 가진 이름들을 수정하기 위한 규칙들을 코드 내에서 관리하고 있었다.

     

    하지만 정제해야 할 케이스들이 끝도 없이 나왔다.. 😱 😱 이상한 이름들을 가진 데이터를 제보받거나, 데이터를 보다가 발견하는 경우가 정말 많았다.

    ex) OO 신내점) (닫힌 괄호만 있는 경우) , OO&#38 (이상한 특수문자가 포함되어있는 경우) 등등

     

    이러한 케이스들은 단일 케이스가 아닌 여러 데이터에 걸쳐서 보이는 케이스들이었다.

    같은 특수문자 패턴이 보이기도 하고, 프랜차이즈의 동의어들이 보이기도 하고..!

     

    이런 이슈들을 발견할 때마다, 여러 이상 패턴들을 어떻게 하면 빠르게 정제하여 반영할 수 있을지 고민이 되었다 🤔

     

    그래서 코드 내에서 관리하고 있던 정제룰을 데이터화하여 테이블로 관리하기로 했다!

     

    테이블로 관리하면 다음과 같은 이점이 있다고 판단하여 진행하기로 했당.

     

    1. 규칙을 새로 추가하거나 삭제할 때, 서버 배포를 따로 하지 않아도 된다.
    2. API가 추가되면 손쉽게 규칙 생성/수정/삭제가 가능하다.
    3. 규칙이 추가될 때, 해당 규칙의 패턴(regex)에 대한 정제&수정 과정이 수월해진다.

    잘만 개발해놓는다면, 규칙들을 정말 손쉽게 추가/삭제를 할 수 있고, 콘트롤이 쉬워질 듯했다.

     


    규칙 순서 관리 고민고민

    정제룰 테이블 구조를 설계할 때, 가장 크게 고민했던 포인트는 규칙 순서 관리였다. 이름 정제할 때, 정제되는 순서가 정말 중요하다.

     

    예시를 들어보겠다. 다음 두가지 정제 규칙이 있다고 해보자

    1. “(주)”를 제거하는 규칙
    2. 괄호를 제거하는 규칙

    위 규칙들을 기반으로 (주)롯데호텔 이름을 가진 장소를 정제해보자. 

    • 1 → 2 순서로 정제했을 때 → 정제 결과: 롯데호텔
    • 2 → 1 순서로 정제했을 때 → 정제 결과: 주롯데호텔

     

    이 경우, 1번이 꼭 선행되어야한다.

     

    이렇게 꼭 선행되어야하는 규칙들이 존재하기 때문에, 순서 관리가 중요하다.

     

    그래서 next_rule_id 라는 컬럼으로 순서관리를 하도록 했다!

     

    next_rule_id 컬럼은 현재 규칙(현재 row)의 다음 순서 규칙의 ID이다. 이는 링크드리스트 구조를 표현할 수 있는 컬럼이다!

    요 방법은 순서를 변경할 때, 바로 앞에 있는 규칙에 대한 순서를 함께 수정하면 된다. 수정되어야할 타겟이 명확하니 이것이 장점이라고 생각한다.

     

    이렇게 next_rule_id로 두면, DB단에서는 순서 정렬을 할 수 없다. 하지만 정제를 할 때 모든 정제 규칙을 조회해서 적용해야하기 때문에 메모리에 올려두고 사용할 목적이고, 그렇기에 서버단에서 링크드리스트로 연결해서 정렬을 할 수 있는 구조이다!

    (그런데 규칙이 기대와 다르게 몇십만개 이상이 되어버린다 하면,, 그건 고민이네 🤔)

     

    id regex replacement next_rule_id
    1 \\(주\\)   3
    2 \\(|\\)   null
    3 \\(유\\)   5
    4 GS\\(지에스\\) GS 6
    5 지에스 GS 4
    6 GS 25 GS25 2

     

    위와 같은 데이터가 있다고 할 때, 다음과 같이 연결하여 표현할 수 있다.

     

    보이시나요?ㅜㅜ

     


     

    순서 관리할 때 다른 방법도 존재하는데, 왜 채택하지 않았는지 얘기해보려고 한다.

     

    order 컬럼을 추가하여 int로 관리하는 방법

    • order를 기준으로 정렬하면 되니, 정렬은 매우 쉬워진다.
    • 하지만, 규칙 순서가 바뀔 때 여러 row의 order 컬럼을 수정해야한다.
      • 맨 뒤 규칙이 맨 앞으로 순서를 수정한다고 했을 때, 모든 row의 값을 변경해야한다.
      • 다른 row의 값을 일괄 변경해준다는 점이, 수정할 때마다 영향 범위가 크다는 것에서 고민이 들었다.

     

    소수를 이용하여 순서를 변경하는 방법

    이 방법도 order 컬럼이 필요하다. 규칙이 추가될 때, 앞의 규칙보다 0.1 정도 높여서 저장하는 것이다.

    이 방법은 너무 편법 같다는 생각이 들어서.. 배제했다!

     


     

    요렇게 규칙 순서 관리의 중요성과 링크드리스트 구조를 테이블에 어떻게 표현하였는지를 이야기 해보았다!

    링크드리스트 자료구조를 오랜만에 접하고, 또 이론으로만 공부해왔던 구조를 머릿속으로 그려가면서 실제 코드로 녹여내려니까 너무 재미나게 개발을 했다!! last_rule이란 단어를 써야하는데 last_node라고 쓰기도 하고ㅋㅋ 

     

    아무튼 넘 의미있는 고민을 할 수 있어서 뜻깊은 시간이었당! 

     

    끝!

     

    아, 순서 관리 관련해서 떠오르는 좋은 방법이 있다면 조언해주시면 좋을 것 같슴다!

    728x90
    반응형

    댓글

Designed by Tistory.