mariadb-ddl-rules.mdc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # MariaDB 호환 DDL 스크립트 작성 규칙
  2. ## 📋 기본 원칙
  3. **모든 DDL 스크립트는 MariaDB 호환성을 최우선으로 작성한다.**
  4. ## 🔧 MariaDB 전용 구문 규칙
  5. ### 1. 컬럼 삭제 (DROP COLUMN)
  6. #### ❌ 사용 금지 (MySQL 8.0+ 전용)
  7. ```sql
  8. ALTER TABLE table_name DROP COLUMN IF EXISTS column_name;
  9. ```
  10. #### ❌ 문제 있는 동적 SQL (MariaDB에서 불안정)
  11. ```sql
  12. -- 이 방식은 MariaDB에서 PREPARE/EXECUTE 오류 발생 가능
  13. SET @sql = (SELECT IF(...));
  14. PREPARE stmt FROM @sql;
  15. EXECUTE stmt;
  16. DEALLOCATE PREPARE stmt;
  17. ```
  18. #### ✅ MariaDB 안전 방식 (권장)
  19. ```sql
  20. -- 1. 컬럼 존재 여부 확인 (정보성)
  21. SELECT COUNT(*) as column_exists
  22. FROM INFORMATION_SCHEMA.COLUMNS
  23. WHERE TABLE_SCHEMA = 'database_name'
  24. AND TABLE_NAME = 'table_name'
  25. AND COLUMN_NAME = 'column_name';
  26. -- 2. 사용자 안내 메시지 제공
  27. SELECT
  28. CASE
  29. WHEN COUNT(*) > 0 THEN '⚠️ 컬럼이 존재합니다. 다음 명령을 별도로 실행하세요: ALTER TABLE table_name DROP COLUMN column_name;'
  30. ELSE '✅ 컬럼이 존재하지 않습니다.'
  31. END as column_check
  32. FROM INFORMATION_SCHEMA.COLUMNS
  33. WHERE TABLE_SCHEMA = 'database_name'
  34. AND TABLE_NAME = 'table_name'
  35. AND COLUMN_NAME = 'column_name';
  36. -- 3. 주석으로 수동 실행 명령 제공
  37. -- ALTER TABLE `table_name` DROP COLUMN `column_name`;
  38. ```
  39. ### 2. 인덱스 생성
  40. #### ✅ 권장 방식
  41. ```sql
  42. -- MariaDB에서 지원하는 안전한 인덱스 생성
  43. CREATE INDEX IF NOT EXISTS `index_name` ON `table_name` (`column1`, `column2`);
  44. ```
  45. #### ❌ 주의사항
  46. ```sql
  47. -- MariaDB 오래된 버전에서는 IF NOT EXISTS 미지원할 수 있음
  48. -- 이 경우 DROP INDEX IF EXISTS 후 CREATE INDEX 사용
  49. DROP INDEX IF EXISTS `index_name` ON `table_name`;
  50. CREATE INDEX `index_name` ON `table_name` (`column1`, `column2`);
  51. ```
  52. ### 3. 외래키 제약조건
  53. #### ✅ 안전한 외래키 처리
  54. ```sql
  55. -- 외래키 체크 임시 비활성화 (TRUNCATE 시 필요)
  56. SET FOREIGN_KEY_CHECKS = 0;
  57. -- 작업 수행
  58. TRUNCATE TABLE `child_table`;
  59. TRUNCATE TABLE `parent_table`;
  60. -- 외래키 체크 재활성화
  61. SET FOREIGN_KEY_CHECKS = 1;
  62. ```
  63. ### 4. 테이블 수정 (ALTER TABLE)
  64. #### ✅ 단계별 안전한 수정
  65. ```sql
  66. -- 1. 백업 테이블 생성
  67. CREATE TABLE IF NOT EXISTS `table_backup_YYYYMMDD` AS
  68. SELECT * FROM `original_table`;
  69. -- 2. 컬럼 추가
  70. ALTER TABLE `original_table`
  71. ADD COLUMN IF NOT EXISTS `new_column` varchar(50) DEFAULT NULL;
  72. -- 3. 컬럼 수정 (MariaDB 호환)
  73. ALTER TABLE `original_table`
  74. MODIFY COLUMN `existing_column` varchar(100) NOT NULL;
  75. ```
  76. ### 5. 데이터 타입
  77. #### ✅ MariaDB 호환 데이터 타입
  78. ```sql
  79. -- 문자열
  80. varchar(255) COLLATE utf8mb4_unicode_ci
  81. text COLLATE utf8mb4_unicode_ci
  82. -- 숫자
  83. bigint(20)
  84. int(11)
  85. decimal(10,2)
  86. -- 날짜/시간
  87. datetime DEFAULT current_timestamp()
  88. timestamp DEFAULT current_timestamp() ON UPDATE current_timestamp()
  89. -- 불린
  90. char(1) DEFAULT 'N' -- 'Y'/'N' 방식 권장
  91. ```
  92. ## 📝 DDL 스크립트 템플릿
  93. ### 기본 구조
  94. ```sql
  95. -- ============================================================================
  96. -- [작업 설명]
  97. -- 작성일: YYYY-MM-DD
  98. -- 목적: [목적 설명]
  99. -- 호환성: MariaDB 10.x+
  100. -- ============================================================================
  101. USE database_name;
  102. -- 1. 백업 생성 (필수)
  103. CREATE TABLE IF NOT EXISTS `backup_table_YYYYMMDD` AS
  104. SELECT * FROM `original_table`;
  105. -- 2. 외래키 체크 비활성화 (필요시)
  106. SET FOREIGN_KEY_CHECKS = 0;
  107. -- 3. 작업 수행
  108. -- ... DDL 작업 ...
  109. -- 4. 외래키 체크 재활성화 (필요시)
  110. SET FOREIGN_KEY_CHECKS = 1;
  111. -- 5. 컬럼 존재 확인 및 안내 (필요시)
  112. SELECT
  113. CASE
  114. WHEN COUNT(*) > 0 THEN '⚠️ 추가 작업이 필요합니다: [수동 명령]'
  115. ELSE '✅ 모든 작업이 완료되었습니다.'
  116. END as manual_check
  117. FROM INFORMATION_SCHEMA.COLUMNS
  118. WHERE TABLE_SCHEMA = 'database_name'
  119. AND TABLE_NAME = 'table_name'
  120. AND COLUMN_NAME = 'column_name';
  121. -- 6. 테이블 구조 확인
  122. DESCRIBE `modified_table`;
  123. -- 7. 완료 메시지
  124. SELECT '작업 완료' as message;
  125. SELECT '백업 테이블: backup_table_YYYYMMDD' as backup_info;
  126. ```
  127. ## 🚨 주의사항
  128. ### 1. 백업 필수
  129. - 모든 DDL 작업 전 백업 테이블 생성
  130. - 백업 테이블명: `원본테이블명_BACKUP_YYYYMMDD` 형식
  131. ### 2. 동적 SQL 제한
  132. - MariaDB에서 PREPARE/EXECUTE 구문은 불안정할 수 있음
  133. - 가능하면 정적 SQL 사용하고, 필요시 수동 실행 안내
  134. ### 3. 트랜잭션 제한
  135. - DDL은 자동 커밋되므로 롤백 불가
  136. - 중요한 작업은 단계별로 분리하여 실행
  137. ### 4. 외래키 처리
  138. - TRUNCATE 전 반드시 외래키 체크 비활성화
  139. - 작업 완료 후 즉시 재활성화
  140. ### 5. 컬럼/인덱스 존재 확인
  141. - 중복 생성 방지를 위해 존재 여부 확인
  142. - INFORMATION_SCHEMA 활용하여 확인 후 안내
  143. ## ✅ 검증 체크리스트
  144. DDL 스크립트 작성 시 다음 사항을 확인:
  145. - [ ] MariaDB 호환 구문 사용
  146. - [ ] 동적 SQL 대신 정적 SQL + 수동 안내 방식 사용
  147. - [ ] 백업 테이블 생성 포함
  148. - [ ] 외래키 처리 포함 (필요시)
  149. - [ ] 컬럼 존재 확인 및 안내 메시지 포함
  150. - [ ] 테이블 구조 확인 포함
  151. - [ ] 완료 메시지 포함
  152. - [ ] 주석으로 작업 내용 명시
  153. ## 🔍 테스트 방법
  154. ```sql
  155. -- 1. 구문 검사
  156. -- DDL 스크립트를 테스트 DB에서 먼저 실행
  157. -- 2. 백업 확인
  158. SELECT COUNT(*) FROM backup_table_YYYYMMDD;
  159. -- 3. 구조 확인
  160. DESCRIBE modified_table;
  161. -- 4. 제약조건 확인
  162. SHOW CREATE TABLE modified_table;
  163. -- 5. 수동 작업 확인
  164. -- 스크립트 실행 후 안내 메시지에 따라 추가 작업 수행
  165. ```
  166. **모든 DDL 스크립트는 이 규칙을 준수하여 MariaDB 호환성을 보장한다.**
  167. description:
  168. globs:
  169. alwaysApply: false
  170. ---