Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions 08장/조혜린.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# 8장. 다양한 데이터 기술을 적절하게 사용하는 방법

## 1. 자료형과 형식의 이해

데이터는 구조가 명확하게 정의된 정형 데이터와 구조가 유동적인 비정형 데이터로 구분할 수 있음. JSON, XML, CSV, YAML 등은 데이터를 표현하고 교환하는 형식으로, 각각의 특성과 사용 목적에 따라 적절한 형식을 선택해야 함.

날짜와 시간 데이터는 시간대와 형식 차이를 고려해야 하며, 대규모 데이터는 전체를 메모리에 적재하기보다 스트리밍 방식으로 처리하는 것이 효율적일 수 있음.

## 2. 효과적인 데이터 저장

데이터베이스는 데이터의 구조, 관계, 조회 패턴, 일관성 및 확장성 요구사항을 고려해 선택해야 함.

- **관계형 DB:** 데이터 간 관계와 무결성, 트랜잭션 관리에 적합.
- **문서 DB:** 구조가 다양하거나 변경이 잦은 데이터에 적합.
- **키-값 저장소:** 단순한 데이터의 빠른 조회에 적합.
- **그래프 DB:** 데이터 간 복잡한 연결 관계를 표현하는 데 적합.
- **벡터 DB:** 의미적 유사성을 기반으로 데이터를 검색하는 데 적합.

모든 기술을 사용하는 것이 아니라 현재 서비스의 요구사항에 적합한 데이터 저장 방식을 선택하는 것이 중요함.

실제 AI 평가 결과를 저장하는 DB를 다루고 있는데, 대량의 데이터를 관리하다 보니 테이블을 최소한으로 유지해야 한다는 요구사항이 있었다. 이 과정에서 데이터의 의미와 책임을 기준으로 테이블을 분리하는 것과 성능 및 리소스를 고려해 테이블을 분리하지 않는 것 사이에서 어떤 선택이 더 적절한지 고민하게 되는 것 같다.

기존에는 관심사와 책임을 명확하게 구분하는 것이 좋은 설계라고 생각했기 때문에 웬만하면 분리하는 방향으로 갔을 것이디ㅏ. 하지만 실제로 대규모 데이터를 다루는 환경에서는 구조적인 명확성뿐 아니라 조회 성능과 저장 비용 등도 함께 고려해야 한다.

그렇다고 성능을 위해 테이블을 분리하지 않는 것이 항상 좋은 선택인지도 잘 모르겠다. 아직 데이터베이스에 대한 이해가 충분하지 않아 두 관점 사이에서 어떤 기준으로 판단해야 할지 어렵다. 결국 좋은 DB 설계는 단순히 테이블을 분리하거나 합치는 문제가 아니라, 데이터의 특성과 실제 사용 방식을 이해한 뒤 적절한 구조를 결정하는 과정이 아닐까 싶다.

## 3. 데이터 영속성 및 관리

데이터 접근 로직과 비즈니스 로직을 분리하기 위해 Repository 패턴을 활용할 수 있음. ORM은 객체와 관계형 데이터베이스를 연결해 데이터 접근을 추상화하지만, 실제 생성되는 SQL과 성능을 이해하는 것도 중요함.
데이터베이스 연결은 커넥션 풀을 활용해 효율적으로 관리할 수 있으며, 트랜잭션은 여러 데이터 작업이 하나의 작업 단위로 일관성 있게 처리되도록 보장함.

## 4. 일관성 모델 및 캐시 전략

데이터 일관성은 시스템의 요구사항에 따라 적절한 수준을 선택해야 함. ACID는 트랜잭션의 안정성을 보장하기 위한 특성이며, 분산 시스템에서는 CAP 정리와 다양한 일관성 모델을 고려해야 함.

캐시는 자주 조회하는 데이터를 빠르게 제공해 데이터베이스 부하와 응답 시간을 줄이는 방법. Cache-aside, Write-through, Write-behind 등 다양한 전략이 있으며, 데이터 변경 시 캐시와 원본 데이터 사이의 일관성을 유지하는 것이 중요함.

캐시도 적절하게 활용한다면 좋은 성능 개선 방법이 될 수 있다고 생각한다. 불필요한 쿼리 연산이나 API 요청을 줄이고, 이미 조회한 데이터를 재사용할 수 있다는 점에서 효율적이라고 생각한다.

다만 캐시를 추가하는 것 자체가 목적이 되어서는 안 될 것 같다. 캐시 역시 별도의 관리 비용과 데이터 일관성 문제가 발생할 수 있으므로, 먼저 불필요한 연산이나 요청을 줄일 수 있는지 확인하고 필요한 상황에서 도입하는 것이 중요하다고 생각한다.

## 5. 데이터 증가 대책

데이터와 요청량이 증가하면 수직·수평 확장, 읽기 전용 복제본, 샤딩 등을 통해 시스템을 확장할 수 있음.
다만 확장 기술은 운영 복잡성과 관리 비용을 증가시킬 수 있으므로, 현재 시스템의 병목과 실제 요구사항을 확인한 뒤 적절한 방식을 선택해야 함.

## 6. 데이터 질의와 성능 관리

효율적인 데이터 조회를 위해 필요한 데이터만 조회하고, 적절한 인덱스와 페이지네이션을 활용해야 함. 인덱스는 조회 성능을 개선할 수 있지만 저장 공간과 쓰기 비용이 증가하므로 필요한 곳에 적용해야 함.

`EXPLAIN`, `EXPLAIN ANALYZE` 등을 통해 실제 쿼리 실행 계획을 확인하고, 데이터베이스 모니터링과 성능 측정을 바탕으로 병목을 분석해야 함. 또한 애플리케이션 코드에서 데이터를 처리하는 방식과 데이터베이스에서 직접 처리하는 방식을 비교해 성능과 복잡성 사이의 균형을 고려해야 함.

실제로 대량의 AI 평가 결과를 조회하는 과정에서 성능 문제가 있던 적이 있었다. 많은 데이터 안에 있는 JSON 내의 글자를 찾는 쿼리 연산이였는데 여기서 문제가 생겼었다. 아예 쿼리 연산을 없애고 관련 값을 따로 테이블 스키마로 빼서 해결했던 것 같다.
같은 데이터를 조회하더라도 쿼리를 어떻게 작성하느냐에 따라 성능 차이가 크게 발생할 수 있는 걸 느겼었다. 단순히 코드의 실행 속도를 개선하는 것이 아니라, 데이터가 어떤 구조로 저장되어 있고 어떤 방식으로 조회되는지 이해하는 것이 중요한 것 같다.

## 7. 데이터 이전과 변환

기존 시스템의 데이터를 새로운 시스템으로 이전할 때는 데이터의 무결성과 서비스 안정성을 유지해야 함. 일괄 이전과 점진적 이전은 각각 장단점이 있으며, 데이터 규모와 서비스 중단 가능성 등을 고려해 선택해야 함.

ETL은 데이터 추출(Extract), 변환(Transform), 적재(Load)의 과정이며, 시스템 간 데이터 동기화에는 메시지 큐나 CDC 등을 활용할 수 있음.

데이터베이스 스키마 변경 시에는 마이그레이션 도구를 활용해 변경 이력을 관리하고, 기존 데이터와 애플리케이션의 호환성 및 복구 방안을 함께 고려해야 함.

실제로 기존 DB 구조를 변경해야 하는 상황이 있었는데, 이미 운영 중인 시스템에 영향을 줄 수 있다는 점이 걱정되어 기존 테이블을 직접 변경하는 대신 View를 생성하는 방식으로 해결했었다.
운영 중인 DB를 잘못 수정했다가 예상하지 못한 문제가 발생할 수 있다는 부담이 컸다. 그래서 기존 구조를 최대한 유지하면서 요구사항을 충족할 수 있는 방법을 선택했지만, 한편으로는 데이터베이스에 대한 이해가 충분했다면 다른 방법도 검토할 수 있지 않았을까 하는 생각이 들었다.

물론 운영 중인 시스템의 안정성을 우선으로 고려하는 것은 중요하다. 다만 DB에 대한 이해가 부족해서 변경 자체를 피하는 것과, 여러 방법의 영향과 위험성을 비교한 뒤 의도적으로 변경하지 않는 것은 다르다고 생각한다.

앞으로는 기존 구조를 유지하는 것이 정말 적절한 선택인지, 스키마를 변경하더라도 안전하게 적용할 방법은 없는지 판단할 수 있는 역량을 갖추고 싶다.

DB를 잘 모르는 상태로 보다보니까 8장은 다시 한 번 읽어야할 것 같다. 1회독을 하고 정리를 하긴 했지만 내 머릿속에 흡수된 게 많이 없는 것 같다. 화이팅
Loading