금칙어 목록을 받았다. 2,217행이고 컬럼이 다섯이다.
Table of contents
Open Table of contents
상황 — 2,217행에 컬럼 다섯
컬럼 구성은 이렇다.
키워드 · 유형 · 설명 · 등록자 · 등록일
유형 값은 두 가지뿐이다.
문제키워드
기타
2,217개를 두 종류로만 나눈 셈이다.
값을 훑으면 실제 성격은 훨씬 여러 갈래다. 두 이름 중 하나를 고르느라 그 갈래가 목록에서 사라진 상태다.
유형 이 문제키워드 와 기타 둘뿐이라 어느 쪽에도 잘 안 맞는 것들이 기타 로 몰린 것으로 보인다. 목록을 만드는 사람이 고를 수 있는 값이 둘밖에 없으면 그 분류는 실제 성격을 따라가지 못한다.
유형은 둘뿐이었다
키워드 쪽을 보면 이런 것들이 섞여 있다.
욕설·비속어
성인 관련
경쟁 서비스 이름
자판 오타 변형
특정 브랜드 리콜 대응
알파벳 한 글자
막는 이유가 서로 다른데 유형은 둘로만 갈린다.
욕설과 리콜 대응이 같은 문제키워드 안에 들어 있으면 둘을 코드에서 가를 방법이 없다. 목록을 읽는 쪽에서는 전부 같은 무게로 다루게 된다.
경쟁 서비스 이름과 자판 오타 변형도 키워드 만 보면 어느 쪽 사정으로 들어온 것인지 읽히지 않는다. 이름만 남고 근거가 사라진 항목은 나중에 손대기가 가장 어렵다.
이유가 다르면 대응도 달라야 한다
막는 이유별로 유지 기간이 다르다.
[욕설] 영구 차단
[경쟁사명] 정책이 바뀌면 풀릴 수 있음
[리콜 대응] 상황이 끝나면 풀어야 함
한시적인 것과 영구적인 것이 한 목록에 섞여 있다.
유형이 둘뿐이면 나중에 풀 것을 골라내기 어렵다. 리콜이 끝나도 그 항목이 어느 것이었는지 목록에서 짚이지 않는다.
푸는 절차가 없으면 목록은 늘기만 한다. 2,217이라는 수 자체가 그 결과일 수 있다.
막을 이유가 생길 때마다 키워드 한 줄이 늘고 그 이유가 없어져도 줄지 않는 구조다. 지금 목록의 상당수가 이미 풀려도 되는 것일 가능성을 배제할 수 없다.
대응 — 등록일과 등록자
유형이 못 담은 것을 다른 컬럼이 조금 메운다.
언제 추가됐나
등록일 로 묶으면 특정 시기에 몰려 들어온 덩어리가 보인다. 같은 사건 대응이면 한 덩어리로 뭉쳐 있을 가능성이 크다.
등록자 는 물어볼 상대를 알려준다.
이 키워드 왜 막혔나요
↓
등록자에게 확인
설명 이 비어 있어도 사람이 남아 있으면 근거를 되찾을 수 있다.
두 컬럼 다 원래 그 용도로 만든 것은 아닐 것이다. 유형이 성격을 못 담은 탓에 부수적으로 그 역할을 하고 있다.
다만 등록일 로 묶은 덩어리가 같은 사건인지는 그 자체로는 확정되지 않는다. 그 시기에 다른 이유로 들어온 것이 섞여 있으면 묶음이 그대로 틀린 근거가 된다.
알파벳 한 글자가 있었다
목록에서 가장 눈에 띄는 것이 이것이다.
a b c d e f g ...
설명 컬럼에는 이렇게 적혀 있다.
알파벳 한글짜 단어
이 항목들이 검사 방식을 알려주는 단서다.
부분 일치로 검사하면 a 하나 때문에 거의 모든 상품명이 걸린다.
"a" 가 금칙어
↓
"apple", "banana", "Made in Japan" 전부 걸림
그러니 이 목록은 완전 일치를 전제로 만들어진 것으로 보인다.
문제는 욕설 변형처럼 부분 일치라야 뜻이 있는 항목도 같은 목록에 있다는 점이다. 앞뒤에 글자가 붙어도 막아야 하는 것들이라 완전 일치로는 안 걸린다.
[알파벳 한 글자] 완전 일치여야 함
[욕설 변형] 부분 일치여야 함
항목마다 어느 쪽인지를 담는 컬럼이 있어야 이 둘이 한 목록에 있을 수 있다.
지금 목록에는 그 컬럼이 없으니 코드가 추측하게 된다. 길이가 1이면 완전 일치로 보는 식인데 두 글자짜리에서 같은 문제가 다시 난다.
설명 컬럼이 채워진 항목은 그 글로 방식을 짐작할 여지가 있지만 비어 있는 줄이 더 많다. 추측이 틀리면 막아야 할 것이 안 막히거나 안 막아야 할 것이 막히는 쪽으로 갈린다.
제약 — 대량 등록에서의 검사 횟수
성능 쪽도 걸린다. 단순 반복이면 상품명 하나에 2,217번 문자열 검색이다.
상품 등록 1건 × 금칙어 2,217개 = 2,217번 검사
셀러가 엑셀로 수천 건을 한 번에 올리는 화면이 있다.
5,000건 × 2,217개 = 1,100만 번
이 수를 그대로 돌리기는 어려워 보인다. 줄이는 방법이 몇 가지 떠오른다.
[정규식 하나로 합침] 2,217개를 OR로 이어 한 번에
[길이로 사전 필터] 상품명보다 긴 금칙어는 건너뜀
[완전 일치는 해시] 셋으로 만들어 조회
셋째가 특히 커 보인다. 완전 일치 항목은 단어를 키로 하는 배열에 모으면 isset 한 번으로 판정된다.
[반복] 2,217번
[해시] 1번
부분 일치가 필요한 것만 남기면 반복으로 도는 개수 자체가 준다. 다만 이 분리의 전제가 항목별 검사 방식을 아는 것이라 지금 목록으로는 시작할 수 없다.
정규식으로 합치는 쪽은 2,217개를 이어 붙인 패턴이 얼마나 무거운지를 따로 재 봐야 한다. 길이로 거르는 쪽은 효과가 상품명 길이에 따라 달라져서 평균만 보고 판단하기 어렵다.
목록만 보고 답이 안 나오는 것은 만든 쪽에 확인할 질문으로 남는다.
이 목록은 완전 일치 전제인가 부분 일치 전제인가
알파벳 한 글자는 어떻게 처리하기로 한 것인가
한시적인 항목을 푸는 절차가 있나
정리
- 금칙어가 2,217개인데
유형은 둘뿐이다 - 실제 성격은 여러 갈래이고 영구와 한시적이 섞여 있다
- 유형이 둘이면 나중에 풀 것을 골라내기 어렵다
등록일과등록자가 유형이 못 담은 정보를 대신 준다- 알파벳 한 글자 항목이 있어 부분 일치로 돌리면 거의 다 막힌다
- 그래서 완전 일치 전제로 보이는데 부분 일치가 필요한 항목도 섞여 있다
- 검사 방식을 담는 컬럼이 없어 코드가 추측하게 된다
- 대량 등록에서 검사가 1,100만 번이 된다
- 완전 일치를
isset쪽으로 옮기면 반복 횟수가 크게 준다