Offcanvas

How To / 개발자

블로그 | 개발자가 참고할 만한 ‘삭제’ 삼가는 애플리케이션 작성법

2023.01.12 Andrew C. Oliver  |  InfoWorld
유지할 만한 기록이 업데이트나 삭제 작업으로 인해 제거되곤 한다. 이러한 기록을 보존하는 데이터베이스 애플리케이션을 작성하는 방법을 살펴본다.

소프트웨어 개발은 재량의 여지가 큰 업무다. 예를 들어 계정 A와 계정 B가 있다. 하나에서 인출하고 이를 다른 하나의 내부에 삽입한다. 일부 예외적인 경우를 제외한다면 아마 이 작업은 개발자마다 다른 방식으로 수행할 가능성이 높다.

그러나 데이터베이스 애플리케이션을  작성함에 있어 업데이트 또는 삭제를 실행하지 않는 방법을 검토할 가치가 충분하다. IoT 애플리케이션 개발자들이 애용하는 접근법이다. 장치가 타임스탬프가 있는 테이블에 들어가는 시계열 데이터(일반적으로 상태 정보)를 보낸다. 오라클과 같은 기성 데이터베이스, 코크로치DB, 유가바이트, 마리아DB X팬드와 같은 최신 분산 SQL 데이터베이스, 또는 몽고DB와 같은 NoSQL 데이터베이스를 사용하는지 여부에 관계없이 방법은 기본적으로 동일하다. 다음의 테이블을 살펴본다.
 
Customer {
  id BIGINT(0) UNSIGNED AUTO_UNIQUE NOT NULL,
  name_given TINYTEXT,
  name_middle TINYTEXT,
  name_family TINYTEXT,
  email [varchar] TINYTEXT,
  dob DATETIME
}

고객이 이메일이나 성을 변경하는 경우 업데이트가 필요하다. 그러나 이는 히스토리가 사라진다는 것을 의미한다. 업데이트는 논리적으로 삭제 및 삽입 작업으로 간주될 수 있다. 다른 방법은 다음과 같다. 
 
Customer {
  entry_id BIGINT(0) UNSIGNED AUTO_UNIQUE NOT NULL,
  entry_date TIMESTAMP NOT NULL,
  id BIGINT(0) UNSIGNED NOT NULL,
  name_given TINYTEXT,
  name_middle TINYTEXT,
  name_family TINYTEXT,
  email [varchar] TINYTEXT,
  dob DATETIME
}


entry_id는 행의 고유 키가 되지만 id는 고유한 사람을 식별하는 키이다. 누군가의 현재 이름과 이메일을 찾으려면 다음과 같은 쿼리를 실행한다. 
 
select … from Customer where id=1 and entry_date = (select max(entry_date) from customer where id =1)

이 쿼리는 id가 1인 고객의 마지막 항목을 가져온다. 고객의 이메일 또는 성을 변경하려면 id가 1인 새 행과 새 행을 삽입한다. (참고 : id가 시퀀스가 아닌 auto_unique인 경우 max(entry_id)를 수행하지 않는다.)

이 접근법에는 하위 쿼리와 또 다른 조인이 필요하다는 분명한 단점이 있다. 그러나 분명한 이점이 있다. 예를 들어 일부 통신 또는 기타 데이터가 이전 가족 이름과 함께 반환되거나 회사가 이전 이메일 주소에서 이메일을 받는 경우에서 그렇다. 

또 다른 장점은 날짜 정보다. 일부 관할권에서는 요청 시 또는 수집된 날짜를 기준으로 정보를 삭제해야 한다. 이 접근법은 해당 작업을 쉽게 만든다. 

한편 고려해야 하는 몇 가지 다른 문제가 있다. 특정 품목을 배송한 고객을 찾는 문제를 생각해본다. Customer, Order, ShipmentShipped_Item 테이블이 있을 수 있다. "현재" 레코드만 원하고 모든 테이블에 버전이 지정되어 있다고 가정하면 최소한 세 개의 하위 쿼리가 생성된다. 대신 첫 번째 고객 테이블 정의와 같은 보다 전통적인 구조를 가질 수 있다. 그러나 한 아카이브 테이블을 사용하여 삭제 시 삽입을 실행할 수 있다. 
 
Customer_Archive {
  archive_id BIGINT(0) UNSIGNED AUTO_UNIQUE NOT NULL,
  customer_id BIGINT(0) UNSIGNED NOT NULL,
  entry_date TIMESTAMP NOT NULL,
  name_given TINYTEXT,
  name_middle TINYTEXT,
  name_family TINYTEXT,
  email [varchar] TINYTEXT,
  dob DATETIME
}

이러한 접근의 장점은 현재 레코드만 Customer, Order, Shipment 및 Shipped_Item 테이블에 있고 조인 수가 줄어든다는 것이다. 이에 더해 감사 로그보다 검색 관련 이점을 가진다. 현재 레코드를 히스토리와 결합하여 검색하는 쿼리에는 단점이 있다. 

어떤 운영체제에서도 히스토리가 효율성을 방해하는 상황을 원하는 이는 없다. 애플리케이션이 삭제하지 않더라도 일부 시스템 프로세스가 지정된 날짜보다 오래된 레코드를 제거하도록 요구할 수 있다. 또한 일부 유형의 데이터를 분석 데이터베이스에 제공하는 것이 합리적일 수 있다. 

업데이트와 삭제는 역사를 제거한다. 선택한 구조와 상관없이 데이터베이스 스키마를 설계할 때라면, 복식부기 회계(double entry accounting)에서 메모를 하고 현재 상태와 함께 히스토리를 보존하는 방안을 검토하는 것이 현명하다. 이 원칙이 모든 애플리케이션에 적용되어야 하는 것은 아니겠지만 적용 여지가 크다. IoT 또는 회계 애플리케이션에 국한되지 않는다. 

* Andrew C. Oliver는 오랜 오픈소스 경력을 보유한 칼럼니스트이자 소프트웨어 개발자다. ciokr@idg.co.kr
 
CIO Korea 뉴스레터 및 IT 트랜드 보고서 무료 구독하기
Sponsored
추천 테크라이브러리

회사명:한국IDG 제호: CIO Korea 주소 : 서울시 중구 세종대로 23, 4층 우)04512
등록번호 : 서울 아01641 등록발행일자 : 2011년 05월 27일

발행인 : 박형미 편집인 : 천신응 청소년보호책임자 : 한정규
사업자 등록번호 : 214-87-22467 Tel : 02-558-6950

Copyright © 2024 International Data Group. All rights reserved.