웹 개발
관계형 데이터 중복 문제 운영 점검
데이터베이스에서 관계형 데이터가 중복될 때 원인을 찾고 해결하는 방법.
데이터베이스에서 관계형 데이터를 다루다 보면 중복이 생긴다. 같은 사용자의 프로필이 여러 개 있거나, 게시물이 중복되거나, 댓글 수가 실제보다 많이 나오는 경우들이다. 혼자 개발할수록 확인한 값과 바꾼 값을 따로 남기는 습관이 중요하다.
목표 명확히 하기
먼저 정확히 무엇이 중복되었는지 파악해야 한다. 같은 데이터가 몇 개인지, 왜 중복되었는지를 명확히 이해하지 않고는 삭제할 수 없다.
현재 상태 파악
로그를 먼저 확인하자. 언제부터 문제가 생겼는지, 어떤 작업 후에 증상이 나타났는지:
sudo journalctl -n 100 --since "2 days ago"
만약 마이그레이션을 실행한 후 문제가 생겼다면, 마이그레이션이 제대로 작동했는지 확인해야 한다.
설정 확인과 제약 조건
데이터베이스의 제약 조건을 확인해보자. 특히 UNIQUE 제약이 제대로 설정되어 있는지:
-- PostgreSQL
\d users
-- MySQL
DESCRIBE users;
만약 UNIQUE 제약이 없다면, 같은 데이터가 여러 개 들어올 수 있다는 뜻이다. 이 경우 응용 로직에서 중복을 방지해야 한다.
관계 테이블 검증
관계 테이블(예: user_post)에 중복된 행이 있는지 확인하자:
SELECT user_id, post_id, COUNT(*) as count
FROM user_posts
GROUP BY user_id, post_id
HAVING COUNT(*) > 1;
이 쿼리로 중복된 관계를 찾을 수 있다.
수정 전 백업
데이터를 수정하기 전에 반드시 백업을 떠야 한다:
pg_dump -U postgres mydb > backup.sql
만약 뭔가 잘못되면 이 백업으로 복구할 수 있다.
중복 제거 쿼리
실제로 중복을 제거할 때는 트랜잭션을 사용해서 천천히 진행하자:
BEGIN;
-- 중복 찾기
WITH ranked_duplicates AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY user_id, post_id ORDER BY id) as rn
FROM user_posts
)
DELETE FROM user_posts
WHERE id IN (SELECT id FROM ranked_duplicates WHERE rn > 1);
-- 결과 확인
SELECT COUNT(*) FROM user_posts;
COMMIT; -- 또는 ROLLBACK;
사용자 영향 확인
데이터를 수정한 후 실제로 사용자가 보는 화면이 제대로 나오는지 확인해야 한다:
- 게시물 개수가 맞게 나오는가?
- 사용자 프로필이 여러 개로 보이지는 않는가?
- 댓글 수나 좋아요 수가 정확한가?
재발 방지
중복이 다시 생기지 않도록 방지 조치를 취해야 한다:
- 데이터베이스에 UNIQUE 제약을 추가한다.
- 응용 로직에서 중복을 확인한다.
- 정기적으로 데이터 무결성을 점검한다.
작은 점검을 규칙적으로 하면 나중에 더 큰 문제를 피할 수 있다.