티스토리 뷰

카테고리 없음

주문번호 UNIQUE 제약조건을 설계할 때 거래처 코드를 포함하는 기준

생각방 2026. 11. 12. 13:44

목차


    ERP에서 거래처 주문을 수신하는 설명용 업무 장면입니다. 수신 목록에는 A사의 000417이 이미 등록돼 있고, B사 파일에도 000417이 들어 있습니다. 두 회사가 각자 번호를 발급한다면 별개의 주문일 수 있습니다. 이때 외부 주문번호 열에 단일 UNIQUE 제약조건이 걸려 있으면 B사 주문은 저장 단계에서 충돌합니다. PostgreSQL 18을 기준으로 거래처 코드를 키에 넣는 판단과 운영 전 확인 절차를 살펴봅니다.


    주문을 거래처 식별값과 주문번호 조합으로 구분

    주문번호 발급 주체와 재사용 범위

    먼저 연계 명세서와 원본 주문 샘플에서 번호를 누가 발급하는지 확인합니다. 중앙 주문 시스템이 모든 거래처에 걸쳐 번호의 유일성을 보장하면 UNIQUE (order_no)가 맞습니다. 이 경우 거래처별로 같은 번호를 허용하면 중앙 발급 규칙을 위반한 데이터도 저장될 수 있습니다. 거래처마다 독립적으로 번호를 발급하고 같은 거래처 안에서 유일성을 보장하면 UNIQUE (partner_code, order_no)가 맞습니다. PostgreSQL은 이때 두 열의 값 조합이 같은 행을 차단합니다. PostgreSQL 18 — 제약조건

    번호를 발급하는 방식유일성 제약 예시판단 근거
    중앙 시스템에서 통합 발급UNIQUE (order_no)전체 거래처에서 번호 하나가 주문 하나를 가리킵니다.
    거래처마다 독립 발급UNIQUE (partner_code, order_no)다른 거래처가 같은 번호를 발급할 수 있습니다.
    같은 거래처가 발급 연도마다 번호를 다시 사용UNIQUE (partner_code, issue_year, order_no)발급 연도 안에서 유일성이 보장된다는 전제가 필요합니다.

    연말에 번호가 초기화된다면 원본이 제공하는 발급 연도를 확인합니다. 12월 주문을 1월에 재수신했을 때 수신 연도로 키를 만들면 같은 주문이 새 조합으로 등록될 수 있습니다. 거래처 코드가 바뀌거나 재사용되는 환경이라면, 외부 코드를 내부의 고정된 거래처 ID로 매핑한 뒤 그 ID를 키에 사용하는 편이 안정적입니다.

    단독 값 비교와 다중 값 조합 비교

    기존 데이터에서 확인할 두 종류의 중복

    기존 단일 제약이 이미 적용돼 있다면 운영 주문 테이블에는 다른 거래처 사이의 정상적인 번호 중복이 남아 있지 않을 수 있습니다. 기존 제약에 걸려 저장되지 않은 주문도 확인할 수 있도록, 동일 파일의 재전송분을 구분한 원본 주문 헤더를 검증용 테이블에 모읍니다. 아래 예시는 번호가 여러 거래처에 걸쳐 쓰인 경우와 같은 거래처 안에서 조합이 반복된 경우를 따로 조회합니다. PostgreSQL 18 — SELECT의 GROUP BY와 HAVING

    SELECT order_no, COUNT(DISTINCT partner_code) AS partner_count
    FROM order_header_stage
    WHERE partner_code IS NOT NULL AND order_no IS NOT NULL
    GROUP BY order_no
    HAVING COUNT(DISTINCT partner_code) > 1;
    
    SELECT partner_code, order_no, COUNT(*) AS row_count
    FROM order_header_stage
    WHERE partner_code IS NOT NULL AND order_no IS NOT NULL
    GROUP BY partner_code, order_no
    HAVING COUNT(*) > 1;

    첫 결과는 번호가 여러 거래처에 나타난 목록입니다. 중앙 발급 방식이라면 원본 발급 내역과 대조하고, 거래처별 발급 방식이라면 서로 다른 주문으로 취급할 수 있는지 확인합니다. 두 번째 결과는 제약조건을 추가하기 전에 조사할 목록입니다. 원본 문서 ID와 수신 이력을 대조해 주문 정정본인지, 발급 범위를 더 나눠야 하는지 확인합니다. 쿼리에서 제외한 NULL 행은 별도로 집계합니다. 두 열이 필수인 설계라면 NOT NULL도 지정합니다. PostgreSQL의 기본 UNIQUE는 키 열에 NULL이 있는 행의 반복을 허용할 수 있습니다. PostgreSQL 18 — 제약조건

    검증용 주문 목록의 중복 후보를 원본 문서와 대조

    저장 키 변경이 조회와 재수신에 미치는 영향

    제약조건을 바꾸면 주문번호만으로는 주문 한 건을 특정하기 어려워집니다. 내부 상세 조회와 주문 상세 테이블은 고유한 order_id를 사용하고, 외부 주문번호를 받는 검색·취소 연계에는 거래처 식별값을 함께 전달하도록 맞춥니다. 기존 외래 키가 order_no의 단일 유일성에 의존한다면, 제약을 제거하기 전에 참조를 order_id 또는 새 복합 키로 옮길 계획을 세웁니다. PostgreSQL 18 — 제약조건

    재수신 때 ON CONFLICT (order_no)를 사용하는 저장 구문도 점검합니다. 두 열을 키로 확정했다면 ON CONFLICT (partner_code, order_no)로 충돌 대상을 맞춥니다. 번호 하나에 걸린 기존 유일 제약이 남아 있으면 다른 거래처의 동일 번호는 여전히 거절될 수 있습니다. 충돌 후 기존 행을 유지할지, 정정 데이터를 반영할지는 수신 계약에 맞춰 정합니다. PostgreSQL 18 — INSERT의 ON CONFLICT

    전환 테스트에서는 A사와 B사의 000417이 각각 등록되는지 확인합니다. 이어 A사 주문을 다시 보내 기존 A사 행에만 합의한 재수신 처리가 적용되는지 확인하고, B사 주문을 조회·취소했을 때 A사 주문 상태가 바뀌지 않는지 비교합니다.

    결론

    거래처 코드는 주문번호의 유일성이 거래처별로 보장될 때 키에 포함합니다. 번호가 연도별로 재사용된다면 발급 연도까지 확인합니다. 운영 반영 전에는 원본에서 찾아낸 중복과 누락을 분류하고, 확정한 키로 주문 등록부터 재수신과 취소까지 같은 주문을 찾는지 검증합니다.

    참고자료