# πŸ”§ μ œμ–΄κ΄€λ¦¬ μ™ΈλΆ€ 컀λ„₯μ…˜ 톡합 κΈ°λŠ₯ μ‚¬μš© κ°€μ΄λ“œ ## πŸ“‹ κΈ°λŠ₯ κ°œμš” μ œμ–΄κ΄€λ¦¬ μ‹œμŠ€ν…œμ— μ™ΈλΆ€ λ°μ΄ν„°λ² μ΄μŠ€ 컀λ„₯μ…˜ 연동 κΈ°λŠ₯이 μΆ”κ°€λ˜μ—ˆμŠ΅λ‹ˆλ‹€. 이제 데이터 μ €μž₯ μ•‘μ…˜μ—μ„œ μ™ΈλΆ€ DBλ‚˜ 자기 μžμ‹ μ˜ ν…Œμ΄λΈ”μ— INSERT, UPDATE, DELETE μž‘μ—…μ„ μˆ˜ν–‰ν•  수 μžˆμŠ΅λ‹ˆλ‹€. ## πŸš€ μ£Όμš” κΈ°λŠ₯ ### 1. **닀쀑 컀λ„₯μ…˜ 지원** - 메인 λ°μ΄ν„°λ² μ΄μŠ€ (ν˜„μž¬ μ‹œμŠ€ν…œ) - μ™ΈλΆ€ λ°μ΄ν„°λ² μ΄μŠ€ (MySQL, PostgreSQL, Oracle, SQL Server λ“±) - FROM/TO 컀λ„₯μ…˜μ„ λ…λ¦½μ μœΌλ‘œ 선택 κ°€λŠ₯ ### 2. **μ•‘μ…˜ νƒ€μž…λ³„ 지원** - **INSERT**: μ™ΈλΆ€ DBμ—μ„œ 데이터 쑰회 β†’ λ‹€λ₯Έ DB에 μ‚½μž… - **UPDATE**: 쑰건 확인 ν›„ λŒ€μƒ ν…Œμ΄λΈ” μ—…λ°μ΄νŠΈ - **DELETE**: 쑰건 확인 ν›„ λŒ€μƒ ν…Œμ΄λΈ” 데이터 μ‚­μ œ ### 3. **자기 μžμ‹  ν…Œμ΄λΈ” μž‘μ—…** - 같은 ν…Œμ΄λΈ” λ‚΄μ—μ„œ UPDATE/DELETE μž‘μ—… 지원 - κ°•ν™”λœ μ•ˆμ „μž₯치둜 데이터 손싀 λ°©μ§€ ## πŸ“– μ‚¬μš© 방법 ### 1단계: 컀λ„₯μ…˜ 선택 μ œμ–΄κ΄€λ¦¬μ—μ„œ 데이터 μ €μž₯ μ•‘μ…˜μ„ 생성할 λ•Œ, λ¨Όμ € FROM/TO 컀λ„₯μ…˜μ„ μ„ νƒν•©λ‹ˆλ‹€. ``` πŸ“ 컀λ„₯μ…˜ 선택 ν™”λ©΄ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ FROM 컀λ„₯μ…˜ (μ†ŒμŠ€) β”‚ TO 컀λ„₯μ…˜ (λŒ€μƒ) β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ [ν˜„μž¬ DB] 메인 μ‹œμŠ€ν…œ β”‚ β”‚ β”‚ [MySQL] μ™ΈλΆ€ DB 1 β”‚ β”‚ β”‚ β”‚ [PostgreSQL] μ™ΈλΆ€ DB 2 β”‚ β”‚ β”‚ [Oracle] μ™ΈλΆ€ DB 3 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 2단계: ν…Œμ΄λΈ” 선택 μ„ νƒν•œ 컀λ„₯μ…˜μ—μ„œ μ‚¬μš©ν•  ν…Œμ΄λΈ”μ„ μ„ νƒν•©λ‹ˆλ‹€. ``` πŸ“ ν…Œμ΄λΈ” 선택 ν™”λ©΄ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ FROM ν…Œμ΄λΈ” β”‚ TO ν…Œμ΄λΈ” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”‚ πŸ” [검색: user] β”‚ β”‚ β”‚ πŸ” [검색: order] β”‚ β”‚ β”‚ β”‚ πŸ“Š user_info (15 컬럼) β”‚ β”‚ β”‚ πŸ“Š order_log (8 컬럼) β”‚ β”‚ β”‚ β”‚ πŸ“Š user_auth (5 컬럼) β”‚ β”‚ β”‚ πŸ“Š order_items (12 컬럼)β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ### 3단계: μ•‘μ…˜λ³„ μ„€μ • #### πŸ”„ INSERT μ•‘μ…˜ FROM ν…Œμ΄λΈ”μ˜ 데이터λ₯Ό TO ν…Œμ΄λΈ”μ— μ‚½μž…ν•˜λŠ” ν•„λ“œ 맀핑을 μ„€μ •ν•©λ‹ˆλ‹€. ``` λ§€ν•‘ κ·œμΉ™: βœ… 1:1 λ§€ν•‘: FROM.user_id β†’ TO.customer_id βœ… 1:N λ§€ν•‘: FROM.name β†’ TO.first_name, TO.display_name ❌ N:1 λ§€ν•‘: FROM.first_name, FROM.last_name β†’ TO.name (κΈˆμ§€) ``` #### πŸ”„ UPDATE μ•‘μ…˜ 3κ°€μ§€ μ„€μ • μ˜μ—­μ΄ μžˆμŠ΅λ‹ˆλ‹€: 1. **μ—…λ°μ΄νŠΈ 쑰건**: FROM ν…Œμ΄λΈ”μ—μ„œ μ–΄λ–€ 쑰건을 λ§Œμ‘±ν•  λ•Œ μ‹€ν–‰ν• μ§€ 2. **ν•„λ“œ λ§€ν•‘**: FROM 데이터λ₯Ό TO ν…Œμ΄λΈ”μ˜ μ–΄λ–€ ν•„λ“œμ— μ—…λ°μ΄νŠΈν• μ§€ 3. **WHERE 쑰건**: TO ν…Œμ΄λΈ”μ—μ„œ μ–΄λ–€ λ ˆμ½”λ“œλ₯Ό μ—…λ°μ΄νŠΈν• μ§€ ``` μ˜ˆμ‹œ μ„€μ •: πŸ” μ—…λ°μ΄νŠΈ 쑰건: FROM.status = 'completed' AND FROM.updated_at > '2024-01-01' πŸ“ ν•„λ“œ λ§€ν•‘: FROM.result_value β†’ TO.final_score 🎯 WHERE 쑰건: TO.user_id = FROM.user_id AND TO.status = 'pending' ``` #### πŸ”„ DELETE μ•‘μ…˜ 2κ°€μ§€ μ„€μ • μ˜μ—­κ³Ό μ•ˆμ „μž₯μΉ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€: 1. **μ‚­μ œ 트리거 쑰건**: FROM ν…Œμ΄λΈ”μ—μ„œ μ–΄λ–€ 쑰건을 λ§Œμ‘±ν•  λ•Œ μ‚­μ œν• μ§€ 2. **WHERE 쑰건**: TO ν…Œμ΄λΈ”μ—μ„œ μ–΄λ–€ λ ˆμ½”λ“œλ₯Ό μ‚­μ œν• μ§€ 3. **μ•ˆμ „μž₯치**: μ΅œλŒ€ μ‚­μ œ 개수, 확인 μš”κ΅¬, Dry Run λ“± ``` μ˜ˆμ‹œ μ„€μ •: πŸ”₯ μ‚­μ œ 쑰건: FROM.is_expired = 'Y' AND FROM.cleanup_date < NOW() 🎯 WHERE 쑰건: TO.ref_id = FROM.id AND TO.status = 'inactive' πŸ›‘οΈ μ•ˆμ „μž₯치: μ΅œλŒ€ 100개, 확인 μš”κ΅¬, Dry Run μ‹€ν–‰ ``` ## ⚠️ 자기 μžμ‹  ν…Œμ΄λΈ” μž‘μ—… μ£Όμ˜μ‚¬ν•­ ### UPDATE μž‘μ—… μ‹œ ``` ⚠️ μ£Όμ˜μ‚¬ν•­: - WHERE 쑰건 ν•„μˆ˜ μ„€μ • - μ—…λ°μ΄νŠΈ 쑰건과 WHERE 쑰건 κ²ΉμΉ¨ λ°©μ§€ - λ¬΄ν•œ 루프 μœ„ν—˜ 체크 βœ… μ•ˆμ „ν•œ μ˜ˆμ‹œ: UPDATE user_info SET last_login = NOW(), login_count = login_count + 1 WHERE user_id = 'specific_user' AND status = 'active' ``` ### DELETE μž‘μ—… μ‹œ ``` 🚨 κ°•ν™”λœ μ•ˆμ „μž₯치: - μ΅œλŒ€ μ‚­μ œ 개수 10개둜 μ œν•œ - λΆ€μ • 쑰건(!=, NOT IN, NOT EXISTS) κΈˆμ§€ - WHERE 쑰건 2개 이상 ꢌμž₯ βœ… μ•ˆμ „ν•œ μ˜ˆμ‹œ: DELETE FROM temp_data WHERE created_at < NOW() - INTERVAL '7 days' AND status = 'processed' AND batch_id = 'specific_batch' LIMIT 10 ``` ## πŸ› οΈ μ‹€μ œ μ‚¬μš© μ‹œλ‚˜λ¦¬μ˜€ ### μ‹œλ‚˜λ¦¬μ˜€ 1: μ‚¬μš©μž 둜그인 정보 μ—…λ°μ΄νŠΈ ``` λͺ©μ : μ‚¬μš©μž 둜그인 μ‹œ λ§ˆμ§€λ§‰ 둜그인 μ‹œκ°„κ³Ό 둜그인 횟수 μ—…λ°μ΄νŠΈ μ„€μ •: - FROM: login_logs ν…Œμ΄λΈ” (메인 DB) - TO: user_info ν…Œμ΄λΈ” (메인 DB) - μ•‘μ…˜: UPDATE 쑰건: πŸ” μ—…λ°μ΄νŠΈ 쑰건: login_logs.status = 'success' AND login_logs.created_at > NOW() - INTERVAL '1 minute' πŸ“ ν•„λ“œ λ§€ν•‘: - login_logs.created_at β†’ user_info.last_login - login_logs.user_agent β†’ user_info.last_user_agent 🎯 WHERE 쑰건: user_info.user_id = login_logs.user_id ``` ### μ‹œλ‚˜λ¦¬μ˜€ 2: μ™ΈλΆ€ μ‹œμŠ€ν…œμ—μ„œ μ£Όλ¬Έ 데이터 동기화 ``` λͺ©μ : μ™ΈλΆ€ μ‡Όν•‘λͺ° μ‹œμŠ€ν…œμ˜ μ£Όλ¬Έ 데이터λ₯Ό λ‚΄λΆ€ ERP에 μ €μž₯ μ„€μ •: - FROM: orders ν…Œμ΄λΈ” (μ™ΈλΆ€ MySQL DB) - TO: erp_orders ν…Œμ΄λΈ” (메인 PostgreSQL DB) - μ•‘μ…˜: INSERT λ§€ν•‘: βœ… ν•„λ“œ λ§€ν•‘: - orders.order_id β†’ erp_orders.external_order_id - orders.customer_name β†’ erp_orders.customer_name - orders.total_amount β†’ erp_orders.order_amount - orders.order_date β†’ erp_orders.received_date ``` ### μ‹œλ‚˜λ¦¬μ˜€ 3: 만료된 μž„μ‹œ 데이터 정리 ``` λͺ©μ : 배치 μž‘μ—… μ™„λ£Œ ν›„ μž„μ‹œ 처리 데이터 μžλ™ μ‚­μ œ μ„€μ •: - FROM: batch_jobs ν…Œμ΄λΈ” (메인 DB) - TO: temp_processing_data ν…Œμ΄λΈ” (메인 DB) - μ•‘μ…˜: DELETE 쑰건: πŸ”₯ μ‚­μ œ 쑰건: batch_jobs.status = 'completed' AND batch_jobs.completed_at < NOW() - INTERVAL '1 hour' 🎯 WHERE 쑰건: - temp_processing_data.batch_id = batch_jobs.batch_id - temp_processing_data.status = 'processed' πŸ›‘οΈ μ•ˆμ „μž₯치: μ΅œλŒ€ 100개, Dry Run λ¨Όμ € μ‹€ν–‰ ``` ## πŸ”§ API μ‚¬μš©λ²• ### ν™œμ„± 컀λ„₯μ…˜ 쑰회 ```typescript import { getActiveConnections } from "@/lib/api/multiConnection"; const connections = await getActiveConnections(); // κ²°κ³Ό: [{ id: 0, connection_name: '메인 λ°μ΄ν„°λ² μ΄μŠ€' }, ...] ``` ### ν…Œμ΄λΈ” λͺ©λ‘ 쑰회 ```typescript import { getTablesFromConnection } from "@/lib/api/multiConnection"; const tables = await getTablesFromConnection(connectionId); // κ²°κ³Ό: [{ tableName: 'users', columnCount: 15 }, ...] ``` ### 컬럼 정보 쑰회 ```typescript import { getColumnsFromConnection } from "@/lib/api/multiConnection"; const columns = await getColumnsFromConnection(connectionId, "users"); // κ²°κ³Ό: [{ columnName: 'id', dataType: 'int', isPrimaryKey: true }, ...] ``` ## 🚨 문제 ν•΄κ²° ### 일반적인 였λ₯˜ #### 1. 컀λ„₯μ…˜ μ—°κ²° μ‹€νŒ¨ ``` 였λ₯˜: "컀λ„₯μ…˜μ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€" ν•΄κ²°: μ™ΈλΆ€ 컀λ„₯μ…˜ κ΄€λ¦¬μ—μ„œ ν•΄λ‹Ή 컀λ„₯μ…˜μ΄ ν™œμ„± μƒνƒœμΈμ§€ 확인 ``` #### 2. ν…Œμ΄λΈ” μ ‘κ·Ό κΆŒν•œ λΆ€μ‘± ``` 였λ₯˜: "ν…Œμ΄λΈ”μ— μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€" ν•΄κ²°: λ°μ΄ν„°λ² μ΄μŠ€ μ‚¬μš©μžμ˜ ν…Œμ΄λΈ” κΆŒν•œ 확인 ``` #### 3. λ§€ν•‘ μ œμ•½μ‚¬ν•­ μœ„λ°˜ ``` 였λ₯˜: "λŒ€μƒ 컬럼이 이미 λ§€ν•‘λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€" ν•΄κ²°: N:1 맀핑이 μ•„λ‹Œ 1:N λ§€ν•‘μœΌλ‘œ λ³€κ²½ ``` #### 4. 자기 μžμ‹  ν…Œμ΄λΈ” μž‘μ—… μ‹€νŒ¨ ``` 였λ₯˜: "WHERE 쑰건이 ν•„μˆ˜μž…λ‹ˆλ‹€" ν•΄κ²°: UPDATE/DELETE μž‘μ—… μ‹œ WHERE 쑰건 μΆ”κ°€ ``` ### μ„±λŠ₯ μ΅œμ ν™” 1. **인덱슀 ν™œμš©**: WHERE 쑰건에 μ‚¬μš©λ˜λŠ” μ»¬λŸΌμ— 인덱슀 생성 2. **배치 크기 μ‘°μ •**: λŒ€λŸ‰ 데이터 처리 μ‹œ μ μ ˆν•œ 배치 크기 μ„€μ • 3. **컀λ„₯μ…˜ 풀링**: μ™ΈλΆ€ DB μ—°κ²° μ‹œ 컀λ„₯μ…˜ ν’€ μ΅œμ ν™” ## πŸ“ž 지원 λ¬Έμ œκ°€ λ°œμƒν•˜κ±°λ‚˜ μΆ”κ°€ κΈ°λŠ₯이 ν•„μš”ν•œ 경우: 1. **둜그 확인**: λΈŒλΌμš°μ € 개발자 λ„κ΅¬μ˜ μ½˜μ†” νƒ­ 확인 2. **μ—λŸ¬ λ©”μ‹œμ§€**: μƒμ„Έν•œ μ—λŸ¬ λ©”μ‹œμ§€μ™€ ν•¨κ»˜ 문의 3. **μ„€μ • 정보**: μ‚¬μš©ν•œ 컀λ„₯μ…˜, ν…Œμ΄λΈ”, μ•‘μ…˜ νƒ€μž… 정보 제곡 --- **πŸ“ λ§ˆμ§€λ§‰ μ—…λ°μ΄νŠΈ**: 2024λ…„ 12μ›” **πŸ”§ 버전**: v1.0.0 **πŸ“§ 문의**: μ‹œμŠ€ν…œ κ΄€λ¦¬μž