RSS듀오랩스
데이터베이스 설계

ERP 공통 코드와 enum: 드롭다운 선택지를 어디에 둘지 정하는 기준

작성자
듀오랩스 대표·7분 읽기

생산 실적 화면에 불량 사유를 적는 칸이 있다고 해 보겠습니다. 한 달이 지나 불량 사유별로 집계를 내면 이런 줄이 나옵니다.

미성형     12건
미 성형     7건
성형불량    5건

현장 사람에게는 모두 같은 불량입니다. 집계 쿼리에게는 서로 다른 사유 세 개입니다. 이번 달 불량 1위가 무엇이냐는 질문에 표가 틀린 답을 냅니다.

선택지는 전부 enum 으로 막으면 된다는 생각

이런 표를 보면 떠오르는 해법은 하나입니다. 자유 입력을 없애고 선택지를 코드에 고정하는 것, 데이터베이스와 프로그램 언어의 enum 입니다. 오타가 들어갈 틈이 없으니 안전해 보입니다.

그 생각대로 불량 사유를 enum 으로 만들면 다른 곳에서 막힙니다. 현장에서 새 불량 유형이 생기면 개발자가 스키마를 고치고, 마이그레이션을 만들고, 배포해야 그 사유를 고를 수 있습니다. 여러 회사가 같은 제품을 쓰는 구조라면 더 곤란합니다. 사출 회사의 「미성형」이 배전반 회사의 선택지에도 나타납니다.

반대로 전부 자유 입력으로 두면 처음의 집계 문제로 돌아갑니다. 선택지 문제는 enum 과 자유 입력 둘 중 하나를 고르는 문제가 아닙니다. 그 사이에 칸이 하나 더 있습니다.

값을 두는 세 자리

업무 시스템의 입력값은 세 자리 중 하나에 둡니다.

자리 누가 바꾸나
enum (코드 상수) 개발자가 배포로 품목 종류, 창고 성격, 주문 상태, 전표 종류, 권한
공통 코드 표 관리자가 화면에서 불량 사유, 단위, 부서, 직함
자유 입력 입력하는 사람이 이름, 주소, 메모, 모델명

공통 코드 표는 데이터베이스에 두는 선택지 목록입니다. 보통 코드 그룹, 코드, 이름, 표시 순서, 사용 여부를 한 줄로 가집니다. 한국 ERP 에서 「공통코드 관리」라고 부르는 메뉴가 이 자리입니다.

가르는 기준은 프로그램의 분기

셋을 가르는 질문은 하나로 충분하다고 봅니다. 프로그램이 그 값을 보고 다르게 움직이는가.

품목 종류가 enum 인 것이 맞는 이유가 여기 있습니다. 완제품이면 제품 창고로 입고하고, 원자재와 부자재만 소요량을 계산해 발주 대상에 올립니다. 코드 곳곳이 이 값으로 갈라집니다. 그래서 값이 틀리면 프로그램이 조용히 잘못 동작합니다. 누군가 화면에서 「반제품2」를 만들 수 있다면, 그 값을 모르는 분기들은 아무 경로도 타지 않습니다.

불량 사유는 다릅니다. 「미성형이면 이렇게 처리한다」는 코드가 어디에도 없습니다. 이 값은 집계와 검색에만 쓰입니다. 프로그램은 값의 뜻을 몰라도 되고, 같은 말이 같은 모양으로 들어오기만 하면 됩니다. 공통 코드 표가 보장하는 것이 정확히 그것입니다.

부차적인 질문 둘이 같은 방향을 가리킵니다. 회사마다 목록이 같은지, 그리고 목록이 얼마나 자주 늘어나는지입니다. 완제품, 반제품, 원자재, 부자재의 구분은 어느 제조업체든 같고 거의 늘지 않습니다. 불량 사유와 단위는 회사마다 다르고 운영하면서 계속 늘어납니다.

enum 이 실제로 막아 주는 것

enum 을 쓰는 이유를 흔히 「오타 방지」로 말합니다. 오타 방지는 공통 코드 표도 합니다. enum 만 주는 것은 따로 있습니다.

하나는 데이터베이스가 목록 밖의 값을 거부한다는 점입니다. PostgreSQL 문서의 예시에서 정의에 없는 값을 넣으면 invalid input value for enum 오류가 납니다. 공통 코드 표도 외래 키로 비슷하게 막을 수 있지만, 그 목록은 관리자가 늘릴 수 있습니다.

다른 하나는 타입 검사입니다. TypeScript 에서 enum 값으로 분기하는 switch 에 빠진 경우가 있으면 컴파일 때 잡도록 짤 수 있습니다. 새 품목 종류를 추가하면 처리하지 않은 분기가 빌드 오류로 드러납니다. 이 장점은 값으로 분기하는 코드가 있을 때만 의미가 있습니다. 불량 사유처럼 분기가 없는 값을 enum 으로 만들면, 비용은 치르고 장점은 쓸 곳이 없습니다.

enum 을 고르면 되돌리기 어려운 부분

PostgreSQL 문서는 enum 에 대해 이렇게 적습니다.

Although enum types are primarily intended for static sets of values, there is support for adding new values to an existing enum type, and for renaming values (see ALTER TYPE). Existing values cannot be removed from an enum type, nor can the sort ordering of such values be changed, short of dropping and re-creating the enum type.

값을 더하고 이름을 바꾸는 것은 되지만, 지우거나 순서를 바꾸려면 타입을 지우고 다시 만들어야 합니다. 「정적인 값의 집합」을 위한 도구라는 문장이 이 글의 기준과 같은 말을 합니다. 자주 늘고 가끔 정리해야 하는 목록을 여기 두면, 정리할 때마다 스키마 작업이 됩니다.

공통 코드 표를 둘 때 지킬 것

공통 코드 표로 정했다면 저라면 세 가지를 처음부터 지키겠습니다.

저장은 이름이 아니라 코드로 합니다. 「미성형」이라는 글자를 저장하면, 나중에 이름을 「성형 미달」로 바꿨을 때 지난 기록과 새 기록이 다시 갈라집니다. 코드를 저장하고 이름은 보일 때 붙이면 이름을 바꿔도 지난 기록이 따라옵니다.

지우지 않고 사용 중지만 합니다. 지난 실적이 그 코드를 가리키고 있습니다. 지우면 지난 기록에 코드만 덩그러니 남습니다. 사용 중지된 코드는 새 입력의 선택지에서만 빠지고, 지난 기록에서는 이름 그대로 보여야 합니다.

회사별로 목록을 가집니다. 여러 회사가 쓰는 시스템이라면 코드 표에 회사 구분이 들어가야 합니다. 초기 목록은 업종에 맞게 채워 주고, 그 뒤는 각 회사 관리자의 몫입니다.

경계가 흐린 값들

모든 값이 깔끔하게 갈리지는 않습니다.

직함이 그런 예입니다. 거래처 담당자의 직함은 회사마다 부르는 말이 다르고 집계에도 거의 쓰이지 않습니다. 코드 표로 옮기면 입력만 불편해질 수 있습니다. 저는 집계나 필터에 실제로 쓰이기 전까지는 자유 입력으로 두는 편이 낫다고 봅니다.

설비 제조사도 애매합니다. 처음에는 코드 표로 충분해 보이지만, 설비가 늘면 제조사가 곧 매입 거래처라는 사실이 드러납니다. 그때는 코드 표가 아니라 거래처와 연결하는 것이 맞습니다. 코드 표는 「이름만 있는 목록」일 때까지만 맞는 자리입니다.

반대 방향의 경계도 있습니다. 주문 상태는 회사마다 부르는 말이 조금씩 다를 수 있지만, 상태에 따라 화면과 처리가 갈리므로 enum 에 둡니다. 부르는 말의 차이는 값이 아니라 화면에 붙이는 용어에서 해결하는 것이 맞다고 봅니다. 값을 회사마다 바꾸게 하면 분기하는 코드가 그 값을 따라갈 수 없습니다.

마지막 수정:

공유하실 때는 출처(Duolabs)와 원문 주소를 표시해 주세요.