우리에게 너무나 익숙한 '휴지통'. 파일을 삭제하면 잠시 머무는 이 공간을 데이터베이스로 구현해 본다면 어떤 모습일까요? 오늘은 우리 주변의 친숙한 개념인 휴지통을 예시로, 관계형 데이터베이스 관리 시스템(RDBMS)의 대표주자인 Oracle을 사용하여 데이터베이스를 설계하고 구현하는 과정을 상세히 알아보겠습니다.
이 과정을 통해 RDBMS의 핵심 개념인 테이블, 관계, 제약조건 등을 쉽고 명확하게 이해할 수 있을 것입니다.
1. 휴지통의 핵심 기능 분석 및 데이터 모델링
먼저 휴지통의 작동 방식을 분석하여 데이터로 표현할 요소를 추출해야 합니다.
- 어떤 파일이 삭제되었는가? (파일 이름, 파일 크기, 파일 종류 등)
- 어디에 있던 파일인가? (원래 경로)
- 언제 삭제되었는가?
- 실제 파일 데이터 (선택 사항)
이러한 요소들을 바탕으로 우리는 두 개의 핵심 테이블을 설계할 수 있습니다. 바로 삭제된 파일의 정보를 담는 TRASH_ITEMS 테이블과 파일의 원래 위치 정보를 관리하는 ORIGINAL_LOCATIONS 테이블입니다.
테이블 구조 설계
ORIGINAL_LOCATIONS (원본 위치 정보)
컬럼명 | 데이터 타입 | 제약조건 | 설명 |
LOCATION_ID | NUMBER | Primary Key | 위치를 식별하는 고유 번호 |
DRIVE_LETTER | CHAR(1) | NOT NULL | 드라이브 문자 (예: C, D) |
FILE_PATH | VARCHAR2(4000) | NOT NULL | 파일을 제외한 전체 경로 |
TRASH_ITEMS (휴지통 항목 정보)
컬럼명 | 데이터 타입 | 제약조건 | 설명 |
FILE_ID | NUMBER | Primary Key | 파일을 식별하는 고유 번호 |
FILE_NAME | VARCHAR2(255) | NOT NULL | 삭제된 파일의 이름 |
FILE_SIZE | NUMBER | 파일 크기 (Bytes) | |
DELETED_TIME | DATE | NOT NULL | 파일이 삭제된 시간 |
FILE_CONTENT | BLOB | 파일의 실제 이진 데이터 (선택) | |
LOCATION_ID | NUMBER | Foreign Key | ORIGINAL_LOCATIONS 테이블 참조 |
2. Oracle SQL로 테이블 생성하기 (DDL)
이제 설계한 모델을 바탕으로 Oracle SQL의 데이터 정의 언어(DDL)를 사용하여 실제 테이블을 생성해 보겠습니다. 각 파일과 위치에 고유한 번호를 자동으로 부여하기 위해 시퀀스(Sequence)도 함께 생성합니다.
-- 원본 위치 정보 테이블 생성
CREATE TABLE ORIGINAL_LOCATIONS (
LOCATION_ID NUMBER CONSTRAINT PK_LOCATION_ID PRIMARY KEY,
DRIVE_LETTER CHAR(1) NOT NULL,
FILE_PATH VARCHAR2(4000) NOT NULL
);
-- 휴지통 항목 정보 테이블 생성
CREATE TABLE TRASH_ITEMS (
FILE_ID NUMBER CONSTRAINT PK_FILE_ID PRIMARY KEY,
FILE_NAME VARCHAR2(255) NOT NULL,
FILE_SIZE NUMBER,
DELETED_TIME DATE DEFAULT SYSDATE NOT NULL,
FILE_CONTENT BLOB,
LOCATION_ID NUMBER,
CONSTRAINT FK_LOCATION FOREIGN KEY (LOCATION_ID)
REFERENCES ORIGINAL_LOCATIONS(LOCATION_ID)
);
-- 고유 ID 생성을 위한 시퀀스 생성
CREATE SEQUENCE SEQ_LOCATION_ID;
CREATE SEQUENCE SEQ_FILE_ID;
설계 포인트:
- 정규화: 파일의 원래 위치 정보(DRIVE_LETTER, FILE_PATH)가 중복해서 저장될 수 있으므로, 별도의 ORIGINAL_LOCATIONS 테이블로 분리하여 데이터 중복을 최소화했습니다.
- 관계 설정: TRASH_ITEMS 테이블의 LOCATION_ID가 ORIGINAL_LOCATIONS 테이블의 LOCATION_ID를 참조하도록 외래 키(Foreign Key) 관계를 설정하여 데이터의 무결성을 보장합니다.
- 데이터 타입: 파일 이름과 경로는 가변 길이 문자열이므로 VARCHAR2를, 파일 크기와 ID는 숫자를 의미하는 NUMBER를 사용했습니다. 특히 실제 파일 내용을 저장할 수 있도록 대용량 이진 데이터를 위한 BLOB(Binary Large Object) 타입을 지정했습니다.
- 자동화: DEFAULT SYSDATE를 사용하여 파일이 삭제되는 시점의 시간이 자동으로 기록되도록 하였고, SEQUENCE를 통해 기본 키(Primary Key) 값이 중복 없이 자동으로 증가하도록 구현했습니다.
3. 휴지통 기능 구현하기 (DML)
테이블이 준비되었으니, 이제 실제 휴지통의 동작을 데이터 조작 언어(DML)로 구현해 봅시다.
1) 파일 삭제 (휴지통으로 보내기)
C:\MyData\report.docx 파일을 삭제하는 상황을 가정해 보겠습니다.
-- 1. 원본 위치 정보 저장 (이미 존재하는 경로라면 생략)
INSERT INTO ORIGINAL_LOCATIONS (LOCATION_ID, DRIVE_LETTER, FILE_PATH)
VALUES (SEQ_LOCATION_ID.NEXTVAL, 'C', '/MyData');
-- 2. 휴지통에 파일 정보 추가
INSERT INTO TRASH_ITEMS (FILE_ID, FILE_NAME, FILE_SIZE, LOCATION_ID)
VALUES (SEQ_FILE_ID.NEXTVAL, 'report.docx', 102400, SEQ_LOCATION_ID.CURRVAL);
-- 변경사항 확정
COMMIT;
- SEQ_LOCATION_ID.NEXTVAL: 시퀀스에서 새로운 위치 ID를 가져와 ORIGINAL_LOCATIONS 테이블에 삽입합니다.
- SEQ_LOCATION_ID.CURRVAL: 방금 사용한 그 위치 ID를 TRASH_ITEMS 테이블에 삽입하여 두 테이블을 연결합니다.
2) 휴지통 내용 조회
휴지통에 어떤 파일들이 있는지, 원래 어디에 있었는지 확인하는 쿼리입니다.
SELECT
t.FILE_ID,
t.FILE_NAME,
t.FILE_SIZE,
t.DELETED_TIME,
o.DRIVE_LETTER || ':' || o.FILE_PATH AS ORIGINAL_PATH
FROM
TRASH_ITEMS t
JOIN
ORIGINAL_LOCATIONS o ON t.LOCATION_ID = o.LOCATION_ID
ORDER BY
t.DELETED_TIME DESC;
- JOIN: TRASH_ITEMS 테이블과 ORIGINAL_LOCATIONS 테이블을 LOCATION_ID를 기준으로 연결하여, 각 파일의 상세 정보와 원본 경로를 함께 조회합니다.
3) 파일 복원
FILE_ID가 1인 파일을 복원하는 경우, 단순히 TRASH_ITEMS 테이블에서 해당 데이터를 삭제하면 됩니다.
DELETE FROM TRASH_ITEMS
WHERE FILE_ID = 1;
COMMIT;
4) 휴지통 비우기
휴지통의 모든 항목을 삭제합니다. DELETE 보다 훨씬 빠른 TRUNCATE 명령어를 사용하는 것이 효율적입니다.
TRUNCATE TABLE TRASH_ITEMS;
-- (주의: TRUNCATE는 롤백이 불가능합니다.)
이처럼 간단한 예시를 통해, 우리가 일상적으로 사용하는 '휴지통' 기능이 RDBMS의 원칙에 따라 어떻게 체계적으로 데이터를 구조화하고 관리할 수 있는지 확인할 수 있습니다. 이 기본 모델을 확장하면 사용자별 휴지통, 자동 비우기 정책 등 더 복잡한 기능도 구현할 수 있을 것입니다.