Conversation
Closed
9 tasks
daycodingdan
left a comment
Collaborator
There was a problem hiding this comment.
📊 리뷰 템플릿
📋 변경점 요약
- 파일 수: 10개 파일 변경 (V1, V10-V15, V2-V9)
- 주요 변경사항:
V1__init_schema.sql파일이 대규모 변경되어 JPA 기반의 새로운 전체 스키마가 반영되었습니다.- 기존에 개별적으로 추가되던 컬럼 및 테이블들이
V1스키마에 통합되었습니다. - 일부 테이블 (
post_like,bookmarks)의UNIQUE제약 조건이 제거되었습니다. VARCHAR컬럼들의 길이가 변경된 부분이 다수 존재합니다.
- 영향 범위: 데이터베이스 전체 스키마, 데이터 무결성, 기존 마이그레이션 스크립트와의 호환성
- 전체 이슈 개수: Critical: 1개, High: 4개, Medium: 3개, Low: 1개
🔍 발견된 이슈 상세보기 (클릭하여 펼치기)
🚨 Critical Issues
- [V10-V15, V2-V9 파일들] Flyway/Liquibase 마이그레이션 충돌 및 중복 스크립트:
V1__init_schema.sql파일이 전체 스키마를 새로 정의하면서, 기존에 순차적으로 적용되던V2,V3, ...,V15등의 incremental SQL 스크립트들과 내용이 중복되거나 충돌합니다. 예를 들어,V10에서is_profile_completed컬럼을 추가하지만V1에는 이미 해당 컬럼이 정의되어 있습니다.- 보안 위험도: 하 (직접적인 보안 취약점은 아님)
- 수정 긴급도: 즉시
- 상세: 이는 배포 시 마이그레이션 오류를 유발하여 시스템 장애로 이어질 수 있는 심각한 문제입니다. 마이그레이션 도구(Flyway/Liquibase)는 스크립트의 순서와 내용 일관성을 엄격하게 관리합니다. 새로운
V1이 적용된 후 기존의 개별 DDL 스크립트들이 다시 실행되려 할 때Duplicate Column,Table Already Exists등의 오류가 발생할 것입니다.
⚠️ High Priority Issues
- [V1__init_schema.sql: post_like, bookmarks 테이블] 데이터 무결성 손실 (UNIQUE 제약 조건 누락):
post_like테이블에서(post_id, user_id)및(comment_id, user_id)에 대한UNIQUE KEY제약 조건이 제거되고 일반INDEX로 변경되었습니다. 이는 한 사용자가 동일한 게시글이나 댓글에 여러 번 '좋아요'를 누르거나, 동일한 게시글을 여러 번 북마크할 수 있게 되어 데이터의 중복 및 비정상적인 카운트 증가로 이어질 수 있습니다.
- 예상 영향: 데이터 무결성 손상, 부정확한 좋아요/북마크 카운트, 비즈니스 로직 오류 가능성.
- [V1__init_schema.sql: verifies 테이블] 민감 데이터 저장 및 관리:
verifies테이블에extracted_text(추출된 텍스트)와image_url(이미지 URL)이 저장됩니다. 특히 신분증과 같은 민감한 정보가 포함될 수 있는 경우, 이 데이터를 일반 텍스트로 DB에 저장하는 것은 심각한 보안 위험을 초래할 수 있습니다.
- 예상 영향: 개인 정보 유출 위험 증가, 규제 준수 문제 발생 (GDPR, 국내 개인정보보호법 등). 데이터 암호화, 접근 제어, 보관 정책 등 추가적인 보안 강화가 필요합니다.
- [V1__init_schema.sql: posts.tag, post_images.image_url, ai_profiles.interest_keywords, reports.description 컬럼] VARCHAR 컬럼 길이 축소로 인한 데이터 잘림 가능성:
posts.tag:VARCHAR(1000)->VARCHAR(255)post_images.image_url:TEXT->VARCHAR(255)ai_profiles.interest_keywords:VARCHAR(1024)->VARCHAR(255)reports.description:TEXT->VARCHAR(255)- 기존 데이터 중 255자(또는 1000자, 1024자)를 초과하는 값이 있을 경우, 스키마 마이그레이션 시 데이터가 잘릴 수 있습니다.
- 예상 영향: 데이터 손실, 데이터 무결성 문제, 애플리케이션에서 예상치 못한 동작 발생.
- [V13__add_board_id_to_popular_posts.sql, V14__add_board_type_and_board_id_to_recommended_posts.sql]
NOT NULL컬럼 추가 시 의미 없는 기본값:board_id가DEFAULT 0,board_type이DEFAULT 'FREE'로 추가되었습니다. 이 컬럼들이 실제 다른 테이블의 ID를 참조하거나 특정 ENUM 값을 가져야 할 경우, 기존 레코드에 할당된0이나'FREE'가 비즈니스적으로 유효하지 않은 값이 될 수 있습니다.
- 예상 영향: 데이터 논리적 불일치, 비즈니스 로직에서 예상치 못한
0또는FREE값 처리 필요.
💡 Medium Priority Issues
- [V1__init_schema.sql: 모든 FOREIGN KEY] FOREIGN KEY
ON DELETE액션 누락:- 새로 생성된
V1__init_schema.sql의 대부분의FOREIGN KEY정의에ON DELETE액션이 명시되어 있지 않습니다. 이 경우 기본값인RESTRICT(NO ACTION과 유사)가 적용되어, 부모 레코드 삭제 시 자식 레코드가 있으면 삭제가 불가능하거나 오류가 발생합니다. 예를 들어, 사용자가 탈퇴할 때 해당 사용자의 모든 게시글, 댓글, 좋아요 등의 데이터가 자동으로 삭제되어야 하는 경우가 일반적입니다.
- 새로 생성된
- 개선 효과: 데이터 일관성 및 무결성 유지, cascade 삭제 로직 간소화.
- [V15__create_password_reset_tokens_table.sql, V1__init_schema.sql] 타임스탬프 컬럼 타입 불일치 (
TIMESTAMPvsDATETIME(6)):V15에서는TIMESTAMP타입을 사용하는 반면,V1의 대부분의created_at,updated_at컬럼은datetime(6)을 사용합니다.datetime(6)은 마이크로초 단위까지 정밀한 시간 저장이 가능하며,TIMESTAMP와 달리 타임존 변환 문제가 없어 일관성 유지를 위해 선호될 수 있습니다.
- 개선 효과: 데이터 타입 일관성 유지, 잠재적인 타임존 관련 문제 방지, 데이터 정밀도 향상.
- [V1__init_schema.sql: 전반적인 TEXT/VARCHAR 사용] TEXT와 VARCHAR(길이) 사용의 일관성:
content필드는TEXT로,violation_reason은VARCHAR(1000)으로,detail_message는TEXT로 사용되는 등 긴 텍스트 필드의 타입이 혼재되어 있습니다.TEXT는 가변 길이가 매우 큰 경우에 적합하며,VARCHAR는 최대 길이가 어느 정도 예상될 때 사용합니다.
- 개선 효과: 데이터베이스 스키마 설계의 일관성 확보, 필드 특성에 맞는 최적화된 타입 사용.
📝 Low Priority Issues
- [전체 .sql 파일] SQL 파일 끝 개행 문자 누락 (
\ No newline at end of file):- 각 SQL 마이그레이션 파일 끝에 개행 문자가 없어
\ No newline at end of file메시지가 표시됩니다. 이는 기능적인 문제는 아니지만, 버전 관리 시스템이나 일부 툴에서 파일 처리 시 예상치 못한 문제를 일으킬 수 있습니다.
- 각 SQL 마이그레이션 파일 끝에 개행 문자가 없어
- 개선 효과: 파일 형식 일관성 유지, 버전 관리 시스템과의 호환성 증대.
💡 개선 방안 및 코드 (클릭하여 펼치기)
📂 [마이그레이션 스크립트 관리]
❌ 개선 전:
V1__init_schema.sql (전체 스키마)
V2__...sql (부분 변경)
V3__...sql (부분 변경)
...
V15__...sql (부분 변경)
✅ 개선 후:
-- Flyway/Liquibase 마이그레이션 전략 재정립 필요
-- 옵션 1: V1을 최신 스키마의 스냅샷으로 하고, 이후 V2...V15 스크립트는 삭제하거나 V1에 통합.
-- 만약 이미 운영 환경에 V1 이전 스크립트들이 적용된 상태라면, V1을 baseline으로 지정하고
-- 이후 변경사항만 incremental하게 적용해야 합니다.
-- 옵션 2: V1을 그대로 두고, V2-V15의 변경사항을 V1에 맞춰 수정하거나, 새로운 V_XX_FIX_... 스크립트를 통해
-- 스키마 불일치를 해소하는 DDL을 추가합니다. (권장하지 않음, 복잡성 증가)
-- 가장 권장되는 방식 (V1이 최신 스키마 전체를 나타내는 경우):
-- 1. 현재 `V1__init_schema.sql`에 모든 최신 스키마 정의를 포함합니다.
-- 2. `V2`부터 `V15`까지의 모든 기존 스크립트들은 삭제하거나, `V1`에 이미 포함된 내용이므로 필요하다면
-- 내용을 `V1` 스크립트에 통합하고 해당 파일들을 삭제합니다.
-- 3. 만약 운영 환경에 이미 V1 이전 버전의 마이그레이션이 적용되어 있고 V1을 새로운 시작점으로 하고 싶다면,
-- Flyway의 `baseline` 기능을 사용하여 V1을 현재 DB의 baseline으로 설정하고
-- 향후 변경사항은 V1 이후의 새로운 incremental 스크립트로 관리해야 합니다.
💡 변경 이유:
- 안정성: 마이그레이션 스크립트의 중복 및 충돌은 배포 실패의 주요 원인입니다. 데이터베이스 스키마 변경 이력의 일관성을 보장하여 안정적인 배포를 가능하게 합니다.
📂 [post_like.sql, bookmarks.sql]
❌ 개선 전:
-- post_like 테이블 (V1__init_schema.sql)
CREATE TABLE `post_like` (
-- ...
KEY `idx_like_post_user` (`post_id`,`user_id`),
KEY `idx_like_comment_user` (`comment_id`,`user_id`),
-- UNIQUE KEY가 없음
);
-- bookmarks 테이블 (V1__init_schema.sql)
CREATE TABLE `bookmarks` (
-- ...
KEY `idx_bookmark_post_user` (`post_id`,`user_id`),
-- UNIQUE KEY가 없음
);✅ 개선 후:
-- post_like 테이블 (V1__init_schema.sql)
CREATE TABLE `post_like` (
-- ...
UNIQUE KEY `uk_post_user_like` (`post_id`,`user_id`), -- 다시 추가
UNIQUE KEY `uk_comment_user_like` (`comment_id`,`user_id`), -- 다시 추가
-- 기존 KEY는 UNIQUE KEY로 대체되거나 추가 유지 가능
);
-- bookmarks 테이블 (V1__init_schema.sql)
CREATE TABLE `bookmarks` (
-- ...
UNIQUE KEY `uk_user_post_bookmark` (`user_id`,`post_id`), -- 다시 추가
-- 기존 KEY는 UNIQUE KEY로 대체되거나 추가 유지 가능
);💡 변경 이유:
- 안정성: 데이터베이스 수준에서 중복 '좋아요' 및 '북마크'를 방지하여 데이터 무결성을 보장하고, 애플리케이션 로직의 복잡성을 줄입니다. 비즈니스 요구사항을 정확히 반영합니다.
📂 [verifies.sql]
❌ 개선 전:
CREATE TABLE verifies (
-- ...
extracted_text TEXT,
image_url VARCHAR(500) NOT NULL,
-- ...
);✅ 개선 후:
-- verifies 테이블: 민감 정보 저장 관련 논의 및 개선 방안
-- 1. image_url: 이미지 자체를 DB에 저장하지 않고, S3와 같은 객체 스토리지에 저장 후 URL만 관리.
-- URL도 만료 시간 등을 가지는 Pre-signed URL 사용 고려.
-- 2. extracted_text: 추출된 민감 텍스트는 DB 저장 시 암호화 (AES256 등) 필수.
-- 또는, 일정 기간 후 자동 삭제되는 정책 적용.
-- 3. DB 접근 제어: verifies 테이블에 대한 접근 권한을 최소화하고, 모든 접근 로깅.
-- 예시 (실제 구현은 더 복잡할 수 있음):
CREATE TABLE verifies (
-- ...
-- extracted_text TEXT, -- 암호화된 텍스트 저장 컬럼으로 변경 (예: VARBINARY)
encrypted_extracted_text VARBINARY(4096), -- 암호화된 텍스트 저장 (길이는 실제 데이터 및 암호화 방식에 따라 조정)
-- image_url VARCHAR(500) NOT NULL, -- S3 등 외부 스토리지 URL만 저장
image_storage_key VARCHAR(255) NOT NULL, -- S3 객체 키 등 실제 이미지 식별자만 저장
-- ...
);💡 변경 이유:
- 보안: 민감한 사용자 정보를 암호화하고, 안전한 스토리지에 분리하여 저장함으로써 데이터 유출 위험을 최소화합니다. 이는 개인 정보 보호 및 컴플라이언스 측면에서 매우 중요합니다.
📂 [posts.sql, post_images.sql, ai_profiles.sql, reports.sql]
❌ 개선 전:
-- posts (tag)
ALTER TABLE `posts`
MODIFY COLUMN `tag` varchar(255) DEFAULT NULL; -- 기존 1000 -> 255
-- post_images (image_url)
CREATE TABLE `post_images` (
`image_url` varchar(255) NOT NULL, -- 기존 TEXT -> 255
-- ...
);
-- ai_profiles (interest_keywords)
CREATE TABLE `ai_profiles` (
`interest_keywords` varchar(255) NOT NULL, -- 기존 1024 -> 255
-- ...
);
-- reports (description)
CREATE TABLE `reports` (
`description` varchar(255) NOT NULL, -- 기존 TEXT -> 255
-- ...
);✅ 개선 후:
-- 데이터 잘림 방지 (V1__init_schema.sql 또는 별도 마이그레이션 스크립트에서)
-- 현재 비즈니스 요구사항과 기존 데이터 길이를 확인 후, 컬럼 길이를 재조정합니다.
-- 만약 255자로 충분하다면, 기존 긴 데이터를 마이그레이션 전에 미리 자르거나,
-- 데이터를 마이그레이션한 후 긴 데이터를 수동으로 수정하는 절차를 고려해야 합니다.
-- posts (tag)
ALTER TABLE `posts`
MODIFY COLUMN `tag` varchar(1000) DEFAULT NULL; -- 원상 복구 또는 필요한 최대 길이로 조정
-- post_images (image_url)
CREATE TABLE `post_images` (
`image_url` varchar(500) NOT NULL, -- URL 길이를 충분히 확보 (실제 URL 길이에 따라 조정)
-- ...
);
-- ai_profiles (interest_keywords)
CREATE TABLE `ai_profiles` (
`interest_keywords` varchar(1024) NOT NULL, -- 원상 복구 또는 필요한 최대 길이로 조정
-- ...
);
-- reports (description)
CREATE TABLE `reports` (
`description` TEXT NOT NULL, -- 원상 복구 또는 필요한 최대 길이로 조정
-- ...
);💡 변경 이유:
- 안정성: 데이터 잘림을 방지하여 기존 데이터의 무결성을 유지하고, 애플리케이션에서 예상치 못한 데이터 손실로 인한 오류를 예방합니다.
📂 [모든 테이블 (FOREIGN KEY 관련)]
❌ 개선 전:
CREATE TABLE `comments` (
-- ...
KEY `FK8omq0tc18jd43bu5tjh6jvraq` (`user_id`),
CONSTRAINT `FK8omq0tc18jd43bu5tjh6jvraq` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
);✅ 개선 후:
CREATE TABLE `comments` (
-- ...
CONSTRAINT `FK8omq0tc18jd43bu5tjh6jvraq` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE, -- ON DELETE CASCADE 추가
CONSTRAINT `FK_comments_parent_comment` FOREIGN KEY (`parent_comment_id`) REFERENCES `comments` (`id`) ON DELETE CASCADE -- 또는 ON DELETE SET NULL
);💡 변경 이유:
- 유지보수성:
ON DELETE액션을 명시하여 데이터의 참조 무결성을 자동으로 관리하고, 애플리케이션에서 수동으로 자식 레코드를 삭제해야 하는 복잡성을 줄입니다. 비즈니스 로직에 따라CASCADE,SET NULL,RESTRICT중 적절한 액션을 선택해야 합니다.
📚 추가 권장사항 (클릭하여 펼치기)
🔧 아키텍처 개선
- 마이그레이션 전략 재정립: 현재
V1__init_schema.sql이 전체 스키마를 포함하고 있어 기존의 incremental 스크립트들과 충돌합니다. Flyway/Liquibase 사용 시V1을 새로운 baseline으로 설정하거나,V1이후의 모든 스크립트를V1에 통합하고 이후 변경 사항을 새로운 스크립트로 관리하는 등 마이그레이션 전략을 명확히 재정립해야 합니다. - 데이터 보관 정책 수립:
verifies테이블과 같이 민감한 정보가 포함된 테이블에 대해 데이터 보관 주기 및 파기 정책을 수립하고, 이를 자동화하는 프로세스를 고려해야 합니다.
🧪 테스트 전략
- 마이그레이션 테스트 강화: 실제 프로덕션 환경과 유사한 환경에서 모든 마이그레이션 스크립트가 순서대로 문제없이 적용되는지 철저하게 테스트해야 합니다. 특히 기존 데이터가 있는 상태에서의
ALTER TABLE및UPDATE작업은 롤백 계획과 함께 신중한 테스트가 필요합니다. - 데이터 무결성 테스트:
UNIQUE제약 조건이 제거된post_like및bookmarks테이블에 대해 중복 데이터 삽입 시나리오를 포함하는 통합 테스트 및 비즈니스 로직 테스트를 강화하여, 애플리케이션 레벨에서 데이터 무결성이 올바르게 보장되는지 확인해야 합니다.
📈 모니터링 및 로깅
- 스키마 변경 로깅: 중요한 스키마 변경 (예: 컬럼 삭제, 타입 변경)은 데이터베이스 관리 시스템 또는 애플리케이션 레벨에서 명확히 로깅하여 추적 가능하게 해야 합니다.
ALTER TABLE성능 모니터링: 대규모 테이블에 대한ALTER TABLE작업은 운영 중 시스템 성능에 영향을 줄 수 있으므로, 해당 작업의 수행 시간과 잠금(lock) 발생 여부를 모니터링해야 합니다.
🔐 보안 강화
- 민감 데이터 암호화 (at Rest):
verifies테이블의extracted_text와 같은 민감 정보는 데이터베이스에 저장 시 반드시 암호화해야 합니다. MySQL의 TDE(Transparent Data Encryption) 또는 애플리케이션 레벨 암호화를 고려할 수 있습니다. - 접근 제어 강화: 민감 데이터가 포함된 테이블에 대한 데이터베이스 사용자 권한을 최소한으로 제한하고, 정기적으로 접근 로그를 검토해야 합니다.
- 비밀번호 재설정 토큰 관리:
password_reset_tokens테이블의 토큰은 강력한 랜덤성을 가져야 하며, 단일 사용(one-time use) 및 매우 짧은 유효 기간을 갖도록 애플리케이션 로직에서 관리해야 합니다.
⚡ 성능 최적화
- 대규모
ALTER TABLE주의:V1__init_schema.sql과 같이 많은ALTER TABLE문이 포함된 스크립트는 운영 환경에서 테이블 락을 유발하여 서비스 중단을 야기할 수 있습니다. 가능한 경우 온라인 DDL (Online DDL) 기능을 활용하거나, 서비스 트래픽이 적은 시간에 수행하고, 다운타임을 최소화하기 위한 전략을 수립해야 합니다.
💬 리뷰 완료: 총 9개의 이슈가 발견되었습니다. Critical 이슈 1개는 배포 전 반드시 수정해주세요. 전체적으로 코드 품질은 중 수준입니다.
테스트 커버리지
|
shienka07
previously approved these changes
Jul 31, 2025
kjyy08
dismissed stale reviews from shienka07 and s0ooo0k
August 11, 2025 13:55
The base branch was changed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#️⃣연관된 이슈
#293
📝작업 내용
enum이 아닌String을 사용하고 있던데enum에 맞게 수정했습니다.✅ 체크리스트