Skip to content

Chore: DB 기존 SQL 삭제 및 RDS 스키마 반영 #293#294

Merged
kjyy08 merged 5 commits into
mainfrom
chore/sql
Aug 21, 2025
Merged

Chore: DB 기존 SQL 삭제 및 RDS 스키마 반영 #293#294
kjyy08 merged 5 commits into
mainfrom
chore/sql

Conversation

@kjyy08

@kjyy08 kjyy08 commented Jul 27, 2025

Copy link
Copy Markdown
Member

#️⃣연관된 이슈

#293

📝작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요(이미지 첨부 가능) - (작성 시 지우기)

  • RDS DDL 내려받아 기존 마이그레이션 SQL 파일 모두 삭제하고 RDS에 맞게 초기 스키마 파일 적용했습니다.
    • 이 과정에서 일부 코드가 enum이 아닌 String을 사용하고 있던데 enum에 맞게 수정했습니다.

✅ 체크리스트

  • 코드 점검 완료했습니다
  • 문서/주석 최신화 완료했습니다

@kjyy08 kjyy08 self-assigned this Jul 27, 2025
@kjyy08 kjyy08 added the Chore 빌드 관련 코드 수정 label Jul 27, 2025
@kjyy08 kjyy08 linked an issue Jul 27, 2025 that may be closed by this pull request
9 tasks

@daycodingdan daycodingdan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📊 리뷰 템플릿

📋 변경점 요약

  • 파일 수: 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_idDEFAULT 0, board_typeDEFAULT '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] 타임스탬프 컬럼 타입 불일치 (TIMESTAMP vs DATETIME(6)):
    • V15에서는 TIMESTAMP 타입을 사용하는 반면, V1의 대부분의 created_at, updated_at 컬럼은 datetime(6)을 사용합니다. datetime(6)은 마이크로초 단위까지 정밀한 시간 저장이 가능하며, TIMESTAMP와 달리 타임존 변환 문제가 없어 일관성 유지를 위해 선호될 수 있습니다.
  • 개선 효과: 데이터 타입 일관성 유지, 잠재적인 타임존 관련 문제 방지, 데이터 정밀도 향상.
  • [V1__init_schema.sql: 전반적인 TEXT/VARCHAR 사용] TEXT와 VARCHAR(길이) 사용의 일관성:
    • content 필드는 TEXT로, violation_reasonVARCHAR(1000)으로, detail_messageTEXT로 사용되는 등 긴 텍스트 필드의 타입이 혼재되어 있습니다. TEXT는 가변 길이가 매우 큰 경우에 적합하며, VARCHAR는 최대 길이가 어느 정도 예상될 때 사용합니다.
  • 개선 효과: 데이터베이스 스키마 설계의 일관성 확보, 필드 특성에 맞는 최적화된 타입 사용.

📝 Low Priority Issues

  • [전체 .sql 파일] SQL 파일 끝 개행 문자 누락 (\ No newline at end of file):
    • 각 SQL 마이그레이션 파일 끝에 개행 문자가 없어 \ No newline at end of file 메시지가 표시됩니다. 이는 기능적인 문제는 아니지만, 버전 관리 시스템이나 일부 툴에서 파일 처리 시 예상치 못한 문제를 일으킬 수 있습니다.
  • 개선 효과: 파일 형식 일관성 유지, 버전 관리 시스템과의 호환성 증대.
💡 개선 방안 및 코드 (클릭하여 펼치기)

📂 [마이그레이션 스크립트 관리]

❌ 개선 전:

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 TABLEUPDATE 작업은 롤백 계획과 함께 신중한 테스트가 필요합니다.
  • 데이터 무결성 테스트: UNIQUE 제약 조건이 제거된 post_likebookmarks 테이블에 대해 중복 데이터 삽입 시나리오를 포함하는 통합 테스트 및 비즈니스 로직 테스트를 강화하여, 애플리케이션 레벨에서 데이터 무결성이 올바르게 보장되는지 확인해야 합니다.

📈 모니터링 및 로깅

  • 스키마 변경 로깅: 중요한 스키마 변경 (예: 컬럼 삭제, 타입 변경)은 데이터베이스 관리 시스템 또는 애플리케이션 레벨에서 명확히 로깅하여 추적 가능하게 해야 합니다.
  • 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개는 배포 전 반드시 수정해주세요. 전체적으로 코드 품질은 수준입니다.


s0ooo0k
s0ooo0k previously approved these changes Jul 27, 2025

@s0ooo0k s0ooo0k left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

확인했급니다!

@github-actions

github-actions Bot commented Jul 27, 2025

Copy link
Copy Markdown

테스트 결과

562 tests  ±0   562 ✅ ±0   1m 7s ⏱️ +4s
146 suites ±0     0 💤 ±0 
146 files   ±0     0 ❌ ±0 

Results for commit 6d06ac1. ± Comparison against base commit 1aba057.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jul 27, 2025

Copy link
Copy Markdown

테스트 커버리지

Overall Project 61.37% 🍏

There is no coverage information present for the Files changed

shienka07
shienka07 previously approved these changes Jul 31, 2025
@kjyy08
kjyy08 changed the base branch from develop to main August 11, 2025 13:55
@kjyy08
kjyy08 dismissed stale reviews from shienka07 and s0ooo0k August 11, 2025 13:55

The base branch was changed.

@kjyy08
kjyy08 merged commit 9658fe2 into main Aug 21, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Chore 빌드 관련 코드 수정

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chore: 서버 마이그레이션 작업

4 participants