Dayner에서 구매 이력을 관리하는 방법 (feat: 개인정보보호법, 원장 데이터)
개요#
Dayner에서 기프트카드와 쿠폰을 붙이기 시작하니, 결제 데이터를 어떻게 남길지가 생각보다 빨리 중요한 문제가 됐습니다. 당장 조회만 되면 끝나는 문제가 아니라, 법적으로 보관해야 하는 데이터와 운영 편의를 위해 따로 다뤄야 하는 데이터가 같이 엮여 있었기 때문입니다.
기능적으로는 사용자의 데이터 보호와 전자상거래 등에서의 소비자보호에 관한 법률 시행령(약칭: 전자상거래법 시행령)에 맞아야 했고, 비기능적으로는 결제 내역을 오래 보관하면서도 운영 테이블이 너무 무거워지지 않게 해야 했습니다.
그래서 원장 데이터와 거래 데이터를 분리해서 관리하는 쪽으로 갔고, 이 글은 왜 그런 구조를 택했는지 정리한 기록입니다.
개인정보처리방침 관점의 기능적 설계 분석#
클라이언트(Dayner 사업주)의 법률대리인으로부터 요청받은 기능에 따르면 개인정보보호법 제 6조에 의거해 모든 회원이 웹사이트의 서비스를 통해 거래한 유/무형의 대금 결제 내역을 빠짐없이 기록해야 합니다.
추가로, 대부분의 웹서비스에서는 원장 데이터를 별도로 두어 관리하고 있으니 가능하면 그렇게 구현하는 것이 좋겠다는 권고도 함께 받았습니다.
열람-보존 방법을 확인해보면
따라서
- 결제 내역을 거래발생일과 함께 데이터베이스에 저장/보존 해야합니다.
그리고 당사자(소비자)가 요청하면 데이터를 제공할 수 있어야 하고, 별도 저작물이 없는 경우에는 문서화도 가능한 형태로 관리해야 합니다.
- 결제 내역을 회원 별로 조회 할수도 있어야합니다.
개인정보 이용동의 철회 시에는 별도 보존을 해줘야합니다.
- 회원의 회원 가입 여부(개인정보 동의 기준)에 따라서 데이터를 분리하여 관리하여야 합니다.
포장주문의 경우에는 상관없지만, 기프트카드와 쿠폰은 선물을 통해 비회원도 사용할 수 있어서 타입을 분리해 관리해야 합니다.
Dayner의 데이터 관리 전략: 원장 테이블 개념의 적용#
발생하는 데이터를 관리/저장하는 전략으로 전통적인 금융 원장 테이블의 개념을 차용했습니다. 자문에 따르면 원장 테이블은 중요한 정보를 신뢰성 있게 보관하고, 필요할 때 언제든 참고할 수 있는 기준 테이블을 의미합니다.
- 효율성: PaymentArchive로 데이터를 이동함으로써 결제 내역 테이블의 크기를 관리하고 성능을 최적화할 수 있습니다. 특히 결제수단-결제 내역 형태의 테이블은 join이 발생해 조회 성능 이슈가 생기는데, 비정규화로 인해 join 연산이 어느 정도 해소되어 효율적입니다.
- 안정성: 어느 정도의 중복을 허용하는 만큼 저장 비용이 조금 늘지만, 데이터 보관은 그만큼 안정적으로 수행할 수 있습니다.
- 법적 요구사항 준수: 개인정보보호법과 금융상거래법에 따라 필요한 기간 동안 데이터를 보관하며, 데이터의 무결성을 유지하도록 설계되었습니다. 결제 관련 데이터는 최소 5년간 저장되게 하였습니다.
Dayner의 데이터 관리 방식: 원장 데이터인 PaymentArchive와 결제 내역 테이블#
위의 기능적 요청과 비기능적 특성을 고려해 결제 이력을 두 개의 테이블로 나누어 관리합니다.
- 결제 내역 테이블 (Transaction Table): 이 테이블은 실시간으로 사용자가 결제 내역을 확인할 수 있도록 최신 데이터를 유지합니다. 사용자가 결제를 진행하면, 해당 데이터는 이 테이블에 기록되고, 사용자는 언제든지 자신의 결제 내역을 조회할 수 있습니다.
- 결제 데이터 보관 테이블 (PaymentArchive): 일정 기간이 지나거나 발생된 데이터는 결제 내역 테이블에서 PaymentArchive로 이동하여 장기 보관됩니다. 과거 결제 내역을 안전하게 보관하며, 분쟁 발생 시 증거로 사용할 수 있습니다.
인프라: 보안적 측면#
- 암호화: 결제 관련 데이터는 접근이 제한된 상황에서만 사용되며, 데이터베이스 서버는 Spring 애플리케이션이 실행되는 서버와 독립적으로 구성되어 있어 직접 조회가 불가능합니다.
- 접근 통제: PaymentArchive 테이블은 AWS IAM 최상위 권한을 가진 계정만이 접근할 수 있으며, 일반 개발자나 애플리케이션 어드민 계정도 접근이 불가능하도록 설정되어 있습니다.
- 데이터 파기: 보관 기간이 지난 결제 데이터는 매월 진행되는 정산 과정에서 삭제하거나 비식별화 처리하여, 개인정보보호법의 요구사항을 충족시키고 있습니다.
결국 여기서 중요했던 건 결제 데이터를 "잘 저장한다"보다 "어떤 성격의 데이터를 어디에 남길지"를 먼저 나누는 일이었습니다. 법적으로 오래 보관해야 하는 데이터와, 사용자가 빠르게 조회해야 하는 데이터를 같은 기준으로 관리하면 둘 다 어중간해지기 쉽기 때문입니다.
이 구조로 가고 나니 사용자는 결제 내역을 빠르게 확인할 수 있고, 관리자는 보관용 데이터를 비교적 안정적으로 다룰 수 있게 됐습니다. 지금은 결제 데이터가 약 5,000건에서 10,000건 수준이지만, 이후 데이터가 더 늘어나면 인덱싱이나 아카이빙 주기를 손보는 식으로 추가 최적화도 가능할 겁니다.
다음 글에서는 여러 결제 관련 엔티티에서 하나의 원장 데이터(PaymentArchive)로 어떻게 변환해서 저장했는지 코드 쪽으로 넘어가보려고 합니다.