1. 개발 초기 환경 구성을 위한 플레이스홀더(Placeholder) 활용
프로젝트 초기 단계에서는 실제 데이터가 준비되지 않은 경우가 많다. 이때, 디자인 레이아웃과 기능 개발을 원활하게 진행하기 위해 임시 데이터를 채워 넣는 플레이스홀더(Placeholder)를 사용한다. 본 프로젝트에서는 텍스트와 이미지에 각각 로렘 입숨과 픽숨을 활용했다.
가. 로렘 입숨 (Lorem Ipsum)
로렘 입숨은 출판 및 그래픽 디자인 분야에서 의미 없는 텍스트를 채우기 위해 사용하는 표준 더미(dummy) 텍스트다. 개발 과정에서는 다음과 같은 목적으로 사용한다.
- 콘텐츠 독립적 디자인 검증: 실제 문구가 정해지기 전에 텍스트가 들어갈 공간의 레이아웃, 폰트, 크기, 색상 등이 디자인 시안대로 올바르게 표현되는지 확인할 수 있다.
- 기능 개발 집중: 개발자는 텍스트 내용이 아닌, 데이터가 화면에 렌더링되는 기능 자체에 집중하여 개발을 진행할 수 있다.
나. 픽숨 포토 (Picsum Photos)
픽숨(https://picsum.photos)은 간단한 URL 요청만으로 지정된 크기의 고품질 이미지를 제공하는 무료 서비스다.
사용법:
https://picsum.photos/{가로}/{세로}형식의 URL을 호출하면 해당 크기의 랜덤 이미지를 반환한다.seed값을 추가하여 특정 URL이 항상 같은 이미지를 반환하도록 고정할 수도 있다.https://picsum.photos/seed/book1/200/300
활용 목적:
- 서버 리소스 절약: 개발 단계에서 이미지 파일을 직접 서버에 업로드하고 관리할 필요가 없어 리소스를 절약할 수 있다.
- 동적 이미지 테스트: 다양한 크기와 비율의 이미지가 UI에 미치는 영향을 손쉽게 테스트할 수 있다.
- 빠른 프로토타이핑: 데이터베이스에 이미지 URL만 저장하면 되므로, 실제 이미지 데이터 없이도 빠르게 프로토타입을 완성할 수 있다.
2. 데이터베이스 테이블 분리: books와 book_details
초기 설계에서는 도서의 모든 정보를 하나의 books 테이블에 저장했다. 하지만 시스템의 성능과 유지보수성을 고려하여, 이를 books와 book_details 두 개의 테이블로 분리하는 리팩토링을 진행했다.
가. 테이블 분리의 필요성
하나의 큰 테이블을 두 개 이상의 작은 테이블로 나누는 주된 이유는 성능 최적화와 데이터 관리의 효율성을 높이기 위함이다.
조회 성능 최적화 및 트래픽 감소 (핵심 이유)
- 문제 상황: 도서 목록 조회 API는 메인 화면 등 여러 곳에서 빈번하게 호출된다. 이 화면에서는
id,title,author,summary,price,image_url,likes등 비교적 가벼운 정보만 필요하다. - 비효율: 만약 하나의 테이블에
description(상세 설명),table_of_contents(목차)와 같이 용량이 큰TEXT타입의 데이터까지 모두 포함되어 있다면, 목록 조회 시 불필요한 대용량 데이터를 함께 읽어오게 된다. 이는 데이터베이스 I/O(입출력) 부하를 증가시키고, 네트워크 트래픽 낭비를 초래하여 API 응답 시간을 느리게 만들고, 시간과 비용을 증가시킨다. - 해결: 테이블을 분리함으로써, 목록 조회 시에는 가벼운 정보가 담긴
books테이블만 조회하고, 사용자가 특정 도서를 클릭하여 상세 정보를 요청할 때만book_details테이블을JOIN하여 조회한다. 이로써 시스템 전반의 성능이 크게 향상된다.
- 문제 상황: 도서 목록 조회 API는 메인 화면 등 여러 곳에서 빈번하게 호출된다. 이 화면에서는
데이터 정규화 원칙 준수
- 테이블 분리는 데이터베이스 정규화(Normalization) 원칙과도 맞닿아 있다. 자주 사용되는 데이터와 그렇지 않은 데이터를 분리함으로써 데이터 모델을 더 명확하게 만든다. 이는 데이터의 일관성을 유지하고 중복을 최소화하는 데 도움이 된다. 본 사례는 1:1 관계에서 접근 빈도가 다른 속성을 분리하는 좋은 예시다.
유지보수성 및 확장성 향상
- 테이블의 책임과 역할이 명확해진다.
books테이블은 도서의 핵심 식별 정보를,book_details는 부가적인 상세 정보를 담당한다. - 향후 '출판사 서평', '저자 인터뷰' 등 새로운 상세 정보 필드를 추가해야 할 경우, 핵심 쿼리에 영향을 주지 않고
book_details테이블만 수정하면 되므로 시스템 확장성이 좋아진다.
- 테이블의 책임과 역할이 명확해진다.
나. 테이블 분리 방법
기존 books 테이블을 books와 book_details로 분리하는 과정은 다음과 같다.
신규 테이블(
book_details) 생성- 먼저 상세 정보를 담을
book_details테이블을 생성한다. 이때book_id를 기본 키(Primary Key)로 설정하고, 이 키가books테이블의id를 참조하는 외래 키(Foreign Key)가 되도록 하여 1:1 관계를 맺는다.
CREATE TABLE `book_details` ( `book_id` INT NOT NULL, `description` TEXT NULL, `table_of_contents` TEXT NULL, `form` VARCHAR(50) NULL, `isbn` VARCHAR(13) NOT NULL, PRIMARY KEY (`book_id`), CONSTRAINT `fk_book_details_books` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON DELETE CASCADE );- 먼저 상세 정보를 담을
데이터 마이그레이션(Migration)
- 기존
books테이블에 있던 상세 정보 컬럼의 데이터들을 새로 생성한book_details테이블로 복사한다.
INSERT INTO book_details (book_id, description, table_of_contents, form, isbn) SELECT id, description, table_of_contents, form, isbn FROM books;- 기존
기존 테이블(
books)에서 컬럼 삭제- 데이터가
book_details로 안전하게 이전된 것을 확인한 후,books테이블에서 더 이상 필요 없는 컬럼들을 삭제한다.
ALTER TABLE books DROP COLUMN description, DROP COLUMN table_of_contents, DROP COLUMN form, DROP COLUMN isbn;- 데이터가
위와 같은 과정을 통해 데이터 손실 없이 안전하게 테이블 구조를 개선하고, 시스템의 성능과 유지보수성을 높일 수 있었다.
'Programmers' 카테고리의 다른 글
| [30일차]COUNT, AS, 서브쿼리, EXISTS (0) | 2025.10.22 |
|---|---|
| [29일차]SQL 시간 범위 검색, parent_id, 페이지네이션 (0) | 2025.10.21 |
| [과제] 도서 전체 및 상세 조회 API 구현 흐름, 결과 (0) | 2025.10.20 |
| [27일차]Node.js 프로젝트 구조, 암호화 인증 시스템 (0) | 2025.10.17 |
| [과제]회원가입, 로그인 API 구현 흐름, 결과 (0) | 2025.10.17 |