12장.유령파일

  • 하드 디스크 대량 장애로 데이터베이스를 복원했지만, 이미지는 데이터베이스 밖의 파일 시스템에 일반 파일로 저장.
  • 이미지파일 백업 미비로 전체 이미지 파일 손실.

12.1 목표: 이미지 또는 벌크 미디어 저장

  • 대부분 애플리케이션에서 이미지나 다른 미디어를 사용.
  • 미디어가 데이터베이스에 저장된 엔티티와 연된되기도 한다.
  • 데이터베이스에서 이런 엔티티를 쿼리할 때 관련된 이미지도 함께 얻을 수 있어야 한다.

12.2 안티패턴: 파일을 사용해야 한다고 가정한다.

  • 개념적으로 이미지는 테이블 속성.

1)
..
portrait_image BLOB
..
;
..
screenshot_image BLOB
..
;

2)
..
screenshot_image varchar(100),
caption  varchar(100),
..
;

  • 프로그래머들은 일반적으로 파일을 항상 데이터베이스 밖에 저장해야 한다는 생각을 한다.
  • 파일을 별도로 저장하는 방식에 몇 가지 중대한 위험이 있다.

DELETE 문제

  • 이미지가 데이터베이스 밖에 저장되어 있고 이미지 경로를 포함하고 있는 행을 삭제할 때, 해당 행이 가리키는 경로의 파일을 자동으로 삭제하는 방법이 없다.
  • 데이터베이스에서 이미지를 참조하는 행을 삭제할 때 이미지 파일도 함께 삭제하도록 에플리케이션을 설계하지 않는 한, 고아가 된 이미지 파일이 계속 쌓일 것이다.

트랜잭션 문제

  • 파일의 내용을 변경하면 트랜잭션이 아직 커밋되지 않은 상태라도 다른 클라이언트에서 파일의 변경된 내용을 즉시 본다.

ROLLBACK 문제

  • 롤백시 데이터베이스에서 삭제된 행은 살아나지만, 지워진 파일은 되살아나지 않는다.

백업문제

  • 데이터베이스 백업 도구를 사용하고, 그 다음 외부 이미지 파일을 백업하기 위해 파일 시스템 백업 도구를 사용해야 한다.
  • 파일을 복사한 것과 데이터베이스 백업이 잘 동기화 된 상태인지는 단정하기 어렵다.

SQL 접근 권한 문제

  • 외부 파일은 GRANT나 REVOKE 같은 SQL문으로 할당한 접근권한을 우회한다.

SQL 데이터 타입 문제

  • screenshot_path에 저장된 경로는 문자열일 뿐이다.
  • 데이터베이스는 문자열이 유효한 경로이름인지 검증하지 않고, 해당 경로가 실제로 존재하는지도 검증 할 수 없다.
  • 파일 이름을 변경하거나 파일 이동, 삭제해도, 데이터베이스는 컬럼에 있는 문자열을 자동으로 업데이트하지 않는다.
  • 이 문자열을 경로로 다루는 로직은 어떤 것이든 애플리케이션 코드에 의존할 수밖에 없다.

12.3 안티패턴 인식 방법

  • 프로젝트에서 아래와 같은 질문에 대해 생각해 보지 않았다면 이 안티패턴에 대해 유죄다.
    • 데이터 백업과 복원 절차는 어떻게 되는가? 백업을 어떻게 검증할 수 있는가?
      백업을 만든 서버 이외의 다른 서버에서 데이터 복원 테스트를 해 본적이 있는가?
    • 이미지는 계속 쌓이는가, 아니면 더 이상 필요하지 않으면 시스템에서 삭제 되는가?
      이미지를 삭제하는 절차는 어떻게 되는가? 자동화된 절차인가, 수작업 절차인가?
    • 어플리케이션의 어떤 사용자가 이미지를 볼 수 있는 권한이 있는가? 권한은 어떻게 확인하는가?
      권한이 없는 이미지를 요청하면 사용자가 뭘 보게 되는가?
  • *이미지에 대한 변경을 취소할 수 있는가? 그렇다면, 애플리케이션이 이전 상태의 이미지로 복원해야 하는가?

12.4 안티패턴 사용이 합당한 경우

  • 이미지가 없다면 데이터베이스가 훨씬 가벼워진다.
  • 이미지를 제외하면 데이터베이스 백업이 빨리지고 결과도 작다. 별도의 백업 단계를 통해 파일 시스템의 이미지를 복사해야 하지만,
    엄청나게 큰 데이터베이스를 백업하는 것보다는 이게 쉬울 수 있다.
  • 이미지가 데이터베이스 외부의 파일로 되어 있다면, 일반적인 이미지 미리보기나 편집이 쉽다.
  • 일부 데이터 베이스 제품은 좀더(또는 조금 덜) 투명하게 외부 파일을 참조하는 특수한 SQL 데이터 타입을 지원한다.
    이런 데이터타입은 Oracle(BFILE), SQL Server 2008(FILESTREAM)이 있다.

12.5 해법: 필요한 경우에는 BLOB 데이터 타입을 사용하라.

  • 이미지 데이터가 데이터베이스에 저장된다. 이미지를 로드하기 위한 별도 단계가 필요하지 않다. 파일 경로가 잘못될 위험도 없다.
  • 행을 삭제하면 이미지도 자동 삭제된다.
  • 커밋하기 전까지는 이미지 변경이 다른 클라이언트에 보이지 않는다.
  • 트랜잭션을 롤백하면 이미지도 이전 상태로 복원된다.
  • 행을 업데이트할 때 해당 행에 잠금이 설정되므로 다른 클라이언트는 동일한 이미지를 동시에 업데이트할 수 없다.
  • 데이터베이스 백업에 모든 이미지가 포함된다.
  • SQL 권한은 행뿐 아니라 이미지에 대한 접근도 제어한다.

문서에 대하여

  • 최초작성일 : 2011년 12월 10일
  • 이 문서는 오라클클럽 코어 오라클 데이터베이스 스터디 모임에서 작성하였습니다.
  • {*}이 문서의 내용은 인사이트(insight) 에서 출간한 'SQL AntiPatterns : 개발자가 알아야 할 25가지 SQL 함정과 해법'를 참고하였습니다.*