본문 바로가기

선택 심화: 분산·객체·멀티미디어 데이터

단편화·복제와 객체/JSON·멀티미디어 저장의 책임을 구분하고 작은 자체 예제로 저장 방식의 조건을 비교합니다.

데이터가 커지거나 형태가 달라졌다고 관계형 DB를 즉시 버려야 하는 것은 아닙니다. 어떤 사실을 저장하고 어떤 일관성·조회·수명 규칙이 필요한지 먼저 정합니다. 이 절은 실제 분산 클러스터를 구축하는 안내가 아니라 저장 방식의 판단을 위한 선택 심화입니다.

수평·수직 단편화

수평 단편화는 같은 열 구조의 행들을 나누는 것입니다. 회원 번호 홀짝으로 두 조각을 나누면 각 회원은 한 조각에 속하고 두 조각을 합쳐 전체 회원을 복원할 수 있습니다. 수직 단편화는 속성을 나누는 것입니다. 연락처와 프로필을 분리하더라도 같은 회원인지 JOIN할 공통 키를 보존해야 합니다.

단편화할 때는 원래 사실의 누락이 없는 완전성, 다시 전체를 만드는 재구성 가능성, 의도한 중복/비중복 조건을 확인합니다. 수직 분해의 공통 키 중복은 복원에 필요합니다. 행을 나눈 모든 표가 실제로 다른 서버에 있다는 뜻은 아닙니다.

한 서버에서 단편화의 논리만 관찰
CREATE DATABASE IF NOT EXISTS cs_db_lab;
USE cs_db_lab;
DROP TABLE IF EXISTS cs_frag_members;
CREATE TABLE cs_frag_members(id INT PRIMARY KEY,name VARCHAR(20) NOT NULL,city VARCHAR(20) NOT NULL);
INSERT INTO cs_frag_members VALUES(1,'민','서울'),(2,'준','부산'),(3,'솔','대전');
WITH odd_part AS (SELECT * FROM cs_frag_members WHERE MOD(id,2)=1),
even_part AS (SELECT * FROM cs_frag_members WHERE MOD(id,2)=0),
restored AS (SELECT * FROM odd_part UNION ALL SELECT * FROM even_part)
SELECT * FROM restored ORDER BY id;
WITH identity_part AS (SELECT id,name FROM cs_frag_members),
location_part AS (SELECT id,city FROM cs_frag_members)
SELECT i.id,i.name,l.city FROM identity_part AS i
JOIN location_part AS l ON l.id=i.id ORDER BY i.id;

두 결과는 원본 세 행입니다. 한 서버의 CTE 조회여서 네트워크 장애, 서버별 복제 지연, 분산 트랜잭션을 검증한 것은 아닙니다. 번호 분포가 한쪽에 쏠리면 저장·조회 부하도 쏠리므로 나누는 규칙은 실제 접근 패턴과 함께 검토합니다.

복제와 분산 트랜잭션

복제는 같은 사실의 사본을 여러 위치에 두는 것입니다. 단편화와 다르게 같은 행이 의도적으로 여러 곳에 있을 수 있습니다. 주 서버에서 커밋한 직후 지연된 사본을 읽으면 이전 값이 보일 수 있습니다. “복제본이 있으므로 항상 최신”이라는 결론은 복제 방식과 읽기 정책을 빠뜨립니다.

여러 저장 위치를 한 작업으로 바꾸면 전체 커밋 여부를 조율해야 합니다. 2단계 커밋은 참여자를 준비시킨 뒤 결과를 확정하는 원리이며, 장애 중 대기·복구 문제와 운영 비용이 있습니다. 단일 InnoDB 트랜잭션 두 개를 차례로 커밋한다고 자동으로 분산 원자성이 생기지 않습니다. 반대로 모든 업무가 즉시 전역 트랜잭션을 요구하지도 않습니다. 주문 접수와 알림처럼 재시도·멱등 처리가 가능한 후속 작업은 책임을 나누어 설계할 수 있습니다.

준비 투표·조정자의 영속 결정·불확실 상태의 대기를 실제 XA 상태로 이어 보려면 분산 트랜잭션과 XA 복구를 읽습니다. 별도 새 datadir의 단일 참여자 엔진 복구 실험이며, 이 절의 논리 단편화 SQL과 다중 서버 네트워크 장애 실험을 구분합니다.

객체 모델과 저장 모델

객체지향 데이터 모델은 객체 정체성·속성·메서드·상속을 다룹니다. 객체관계 DB의 확장 타입과 일반 SQL 테이블을 ORM으로 읽어 객체로 만드는 것은 다른 층의 선택입니다. MySQL 테이블에 type 열이나 JSON을 넣었다고 메서드 실행과 객체 정체성까지 지원하는 객체 DB가 되는 것은 아닙니다.

기존 상속 모델은 구체/단일/조인 테이블로 객체의 데이터를 관계 구조에 표현합니다. 각 방식은 FK·유형 제약·조회 비용이 다릅니다. 객체와 테이블의 1:1 대응을 고정 규칙으로 생각하지 않습니다.

멀티미디어의 원본과 설명 데이터

이미지의 원본 바이트, 해상도·포맷 같은 구조 정보, 검색용 제목·태그·권리/출처 같은 설명 정보는 역할이 다릅니다. 원본을 BLOB로 DB 안에 둘 수도, 별도 객체 저장소에 두고 DB에는 식별자·키·해시·수명을 저장할 수도 있습니다. 별도 저장의 경우 DB 행 커밋과 원본 업로드가 서로 실패할 수 있어 후보/완료 상태와 재시도·고아 정리 규칙을 정해야 합니다.

방식장점이 드러나는 조건확인할 비용·규칙
관계형 열과 자식 표값·관계·제약이 명확함JOIN·쓰기 소유권
JSON항목별로 확장 구조가 다름스키마 검증·조회 경로·인덱스
DB 내부 BLOB원본과 행의 관리 경계를 모으려 함큰 백업·전송·복원 비용
외부 원본+DB 메타데이터대용량 원본의 배포/수명을 분리함업로드·행 불일치와 삭제 순서

유형 이름만으로 제품을 추천하지 않습니다. 실제 워크로드·필요한 무결성·복원 방법을 비교합니다. 검색 인덱스와 요약은 원본에서 다시 만들 수 있는 파생물인지도 표시합니다.

독립 문제와 풀이

회원별 이름과 도시를 따로 저장하면서 도시 표에서 id를 제거하면 무엇을 복원할 수 없나요? 미디어 원본 업로드 성공 뒤 DB 등록이 실패했을 때 어떤 상태가 남나요? 복제 사본에서 새 글이 안 보인다는 현상이 반드시 원본 커밋 실패를 뜻하나요?

힌트

연결 키, 두 저장소의 성공 시점, 사본의 적용 시점을 따로 추적합니다.

풀이

id가 없으면 어느 도시가 어느 회원의 사실인지 안전하게 JOIN할 수 없습니다. 업로드만 성공하면 DB에서 참조하지 않는 원본이 남아 요청 ID·후보 기록으로 재등록하거나 보존 기간 뒤 정리할 정책이 필요합니다. 사본의 반영 지연도 가능하므로 원본 커밋 증거와 사본의 적용 위치를 구분합니다.

분산·객체·멀티미디어는 새로운 이름보다 사실의 위치, 복원 조건, 실패 경계로 비교하면 기존 SQL·트랜잭션·모델링 지식과 연결됩니다.