# 🎯 **μ΅œμ’… E-R λ‹€μ΄μ–΄κ·Έλž¨ (v2)** ## **πŸ“Š μ΅œμ’… ν…Œμ΄λΈ” ꡬ성 (총 12개)** | **번호** | **ν…Œμ΄λΈ”λͺ…** | **μ£Όμš” 속성** | **μ„€λͺ…** | | -------- | --------------------- | ------------------------------------------------------------------- | ------------------------- | | 1 | **users** | user_id, email, name, role, api_key, password_hash | μ‚¬μš©μž 계정 | | 2 | **document_types** | doc_type_id, type_name, model_name, sorting_method | λ¬Έμ„œ νƒ€μž… μ •μ˜ **(μˆ˜μ •)** | | 3 | **projects** | project_id, user_id, doc_type_id, project_name, total_pages, status | ν”„λ‘œμ νŠΈ/μ„Έμ…˜ | | 4 | **pages** | page_id, project_id, page_number, image_path, analysis_status | νŽ˜μ΄μ§€ 정보 | | 5 | **layout_elements** | element_id, page_id, class_name, bbox_x/y/width/height | λ ˆμ΄μ•„μ›ƒ μš”μ†Œ **(μˆ˜μ •)** | | 6 | **text_contents** | text_id, element_id, ocr_text, ocr_confidence | OCR κ²°κ³Ό | | 7 | **ai_descriptions** | ai_desc_id, element_id, description, ai_model | AI μ„€λͺ… | | 8 | **question_groups** | question_group_id, page_id, anchor_element_id, start_y, end_y | 문제 κ·Έλ£Ή **(μˆ˜μ •)** | | 9 | **question_elements** | qe_id, question_group_id, element_id, order_in_question | 문제-μš”μ†Œ λ§€ν•‘ | | 10 | **text_versions** | version_id, page_id, user_id, content, version_number, version_type | ν…μŠ€νŠΈ 버전 관리 | | 11 | **formatting_rules** | rule_id, doc_type_id, class_name, prefix, suffix, indent_level | ν¬λ§·νŒ… κ·œμΉ™ | | 12 | **combined_results** | combined_id, project_id, combined_text, combined_stats | 톡합 λ¬Έμ„œ μΊμ‹œ | ## **πŸ”· μ΅œμ’… E-R λ‹€μ΄μ–΄κ·Έλž¨ (μ‹œκ°ν™”)** ``` β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ users β”‚ │─────────────────────────────────────│ β”‚ PK: user_id β”‚ β”‚ email (UNIQUE) β”‚ β”‚ name β”‚ β”‚ role (admin/teacher/student) β”‚ β”‚ api_key (μ•”ν˜Έν™”) β”‚ β”‚ password_hash β”‚ β”‚ created_at β”‚ β”‚ updated_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ 1:N (ν•œ μ‚¬μš©μžλŠ” μ—¬λŸ¬ ν”„λ‘œμ νŠΈ 생성) ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ document_types (μˆ˜μ •) β”‚ │───────────────────────────────────────────────────────────────│ β”‚ PK: doc_type_id β”‚ β”‚ type_name (worksheet/document/form) UNIQUE β”‚ β”‚ model_name (SmartEyeSsen/DocLayout-YOLO) β”‚ (μˆ˜μ •) β”‚ sorting_method (question_based/reading_order) β”‚ β”‚ description β”‚ β”‚ created_at, updated_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ 1:N (ν•œ νƒ€μž…μœΌλ‘œ μ—¬λŸ¬ ν”„λ‘œμ νŠΈ) ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ projects β”‚ │───────────────────────────────────────────────────────────────│ β”‚ PK: project_id β”‚ β”‚ FK: user_id β†’ users(user_id) β”‚ β”‚ FK: doc_type_id β†’ document_types(doc_type_id) β”‚ β”‚ project_name β”‚ β”‚ total_pages (μžλ™ 계산) β”‚ β”‚ analysis_mode (auto/manual/hybrid) β”‚ β”‚ status (created/in_progress/completed/error) β”‚ β”‚ created_at, updated_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ 1:N β”‚ 1:1 β”‚ β”‚ ↓ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ pages β”‚ β”‚ combined_results β”‚ │───────────────────────────────────────│ │─────────────────────────────────│ β”‚ PK: page_id β”‚ β”‚ PK: combined_id β”‚ β”‚ FK: project_id β†’ projects(project_id) β”‚ β”‚ FK: project_id (UNIQUE) β”‚ β”‚ page_number β”‚ β”‚ combined_text (LONGTEXT) β”‚ β”‚ image_path β”‚ β”‚ combined_stats (JSON) β”‚ β”‚ image_width, image_height β”‚ β”‚ generated_at β”‚ β”‚ analysis_status (pending/ β”‚ β”‚ updated_at β”‚ β”‚ processing/completed/error) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ processing_time β”‚ β”‚ created_at, analyzed_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β”‚ 1:N β”‚ 1:N β”‚ β”‚ ↓ ↓ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ layout_elements (μˆ˜μ •) β”‚ β”‚ text_versions β”‚ │────────────────────────────────│ │──────────────────────────────────────│ β”‚ PK: element_id β”‚ β”‚ PK: version_id β”‚ β”‚ FK: page_id β†’ pages(page_id) β”‚ β”‚ FK: page_id β†’ pages(page_id) β”‚ β”‚ class_name β”‚ β”‚ FK: user_id β†’ users(user_id) β”‚ β”‚ confidence β”‚ β”‚ content (TEXT) β”‚ β”‚ bbox_x, bbox_y β”‚ β”‚ version_number β”‚ β”‚ bbox_width, bbox_height β”‚ β”‚ version_type (original/ β”‚ β”‚ area (μžλ™ 계산) β”‚ β”‚ auto_formatted/user_edited) β”‚ β”‚ y_position (μžλ™ 계산) β”‚ β”‚ is_current (TRUE/FALSE) β”‚ β”‚ x_position (μžλ™ 계산) β”‚ β”‚ created_at β”‚ (μ‚­μ œ)β”‚ (order_index) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ created_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ 1:1 (OCR) β”‚ 1:1 (AI) β”‚ 1:N (μžμ‹ μš”μ†Œ) β”‚ 1:1 (액컀) β”‚ β”‚ β”‚ β”‚ ↓ ↓ ↓ ↓ (관계 μΆ”κ°€) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ text_contents β”‚ β”‚ ai_descriptions β”‚ β”‚ question_elements β”‚ β”‚ question_groups (μˆ˜μ •) β”‚ │─────────────────────│ │─────────────────────│ │──────────────────────────│ │────────────────────────│ β”‚ PK: text_id β”‚ β”‚ PK: ai_desc_id β”‚ β”‚ PK: qe_id β”‚ β”‚ PK: question_group_id β”‚ β”‚ FK: element_id β”‚ β”‚ FK: element_id β”‚ β”‚ FK: question_group_id β”‚ β”‚ FK: page_id β”‚ β”‚ (UNIQUE) β”‚ β”‚ (UNIQUE) β”‚ β”‚ FK: element_id β”‚ β”‚ FK: anchor_element_id β”‚ (μˆ˜μ •) β”‚ ocr_text (TEXT) β”‚ β”‚ description β”‚ β”‚ order_in_question β”‚ β”‚ (UNIQUE) β”‚ β”‚ ocr_engine β”‚ β”‚ ai_model β”‚ β”‚ created_at β”‚ β”‚ start_y, end_y β”‚ β”‚ ocr_confidence β”‚ β”‚ prompt_used β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ element_count β”‚ β”‚ language β”‚ β”‚ created_at β”‚ β”‚ β”‚ created_at β”‚ β”‚ created_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ N:1 β”‚ (μ‚­μ œ) (question_number) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ ↑ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ 1:N (그룹은 μ—¬λŸ¬ μžμ‹ μš”μ†Œλ₯Ό 가짐) β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ formatting_rules β”‚ │─────────────────────────────────────────────────────│ β”‚ PK: rule_id β”‚ β”‚ FK: doc_type_id β†’ document_types(doc_type_id) β”‚ β”‚ class_name β”‚ β”‚ prefix, suffix β”‚ β”‚ indent_level β”‚ β”‚ font_size, font_weight β”‚ β”‚ created_at, updated_at β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ ``` ## **πŸ”— 관계(Relationships) 상세 μ„€λͺ… (μˆ˜μ •)** ### **1️⃣ users ↔ projects (1:N)** ``` - ν•œ μ‚¬μš©μžλŠ” μ—¬λŸ¬ ν”„λ‘œμ νŠΈ 생성 κ°€λŠ₯ - ν•œ ν”„λ‘œμ νŠΈλŠ” ν•œ λͺ…μ˜ μ‚¬μš©μžμ—κ²Œλ§Œ 속함 - FK: projects.user_id β†’ users.user_id - ON DELETE CASCADE: μ‚¬μš©μž μ‚­μ œ μ‹œ ν”„λ‘œμ νŠΈλ„ μ‚­μ œ ``` ### **2️⃣ document_types ↔ projects (1:N)** ``` - ν•œ λ¬Έμ„œ νƒ€μž…(worksheet/document)으둜 μ—¬λŸ¬ ν”„λ‘œμ νŠΈ 생성 κ°€λŠ₯ - ν•œ ν”„λ‘œμ νŠΈλŠ” ν•˜λ‚˜μ˜ λ¬Έμ„œ νƒ€μž…λ§Œ 가짐 - FK: projects.doc_type_id β†’ document_types.doc_type_id - ON DELETE RESTRICT: νƒ€μž… μ‚¬μš© 쀑이면 μ‚­μ œ λΆˆκ°€ ``` ### **3️⃣ projects ↔ pages (1:N)** ``` - ν•œ ν”„λ‘œμ νŠΈλŠ” μ—¬λŸ¬ νŽ˜μ΄μ§€ 포함 - ν•œ νŽ˜μ΄μ§€λŠ” ν•˜λ‚˜μ˜ ν”„λ‘œμ νŠΈμ—λ§Œ 속함 - FK: pages.project_id β†’ projects.project_id - ON DELETE CASCADE: ν”„λ‘œμ νŠΈ μ‚­μ œ μ‹œ νŽ˜μ΄μ§€λ„ μ‚­μ œ - 트리거: νŽ˜μ΄μ§€ μΆ”κ°€ μ‹œ projects.total_pages μžλ™ 증가 ``` ### **4️⃣ projects ↔ combined_results (1:1)** ``` - ν•œ ν”„λ‘œμ νŠΈλŠ” ν•˜λ‚˜μ˜ 톡합 κ²°κ³Ό μΊμ‹œλ§Œ 가짐 - ν•œ 톡합 κ²°κ³ΌλŠ” ν•˜λ‚˜μ˜ ν”„λ‘œμ νŠΈμ—λ§Œ 속함 - FK: combined_results.project_id β†’ projects.project_id (UNIQUE) - ON DELETE CASCADE: ν”„λ‘œμ νŠΈ μ‚­μ œ μ‹œ μΊμ‹œλ„ μ‚­μ œ ``` ### **5️⃣ pages ↔ layout_elements (1:N)** ``` - ν•œ νŽ˜μ΄μ§€λŠ” μ—¬λŸ¬ λ ˆμ΄μ•„μ›ƒ μš”μ†Œ 포함 - ν•œ μš”μ†ŒλŠ” ν•˜λ‚˜μ˜ νŽ˜μ΄μ§€μ—λ§Œ 속함 - FK: layout_elements.page_id β†’ pages.page_id - ON DELETE CASCADE: νŽ˜μ΄μ§€ μ‚­μ œ μ‹œ μš”μ†Œλ„ μ‚­μ œ ``` ### **6️⃣ pages ↔ text_versions (1:N)** ``` - ν•œ νŽ˜μ΄μ§€λŠ” μ—¬λŸ¬ ν…μŠ€νŠΈ 버전 가짐 (1, 2, 3, ...) - ν•œ 버전은 ν•˜λ‚˜μ˜ νŽ˜μ΄μ§€μ—λ§Œ 속함 - FK: text_versions.page_id β†’ pages.page_id - ON DELETE CASCADE: νŽ˜μ΄μ§€ μ‚­μ œ μ‹œ λͺ¨λ“  버전 μ‚­μ œ - UNIQUE KEY: (page_id, version_number) - νŽ˜μ΄μ§€ λ‚΄ 버전 번호 쀑볡 λ°©μ§€ ``` ### **7️⃣ layout_elements ↔ text_contents (1:1)** ``` - ν•œ λ ˆμ΄μ•„μ›ƒ μš”μ†ŒλŠ” ν•˜λ‚˜μ˜ OCR 결과만 가짐 - ν•œ OCR κ²°κ³ΌλŠ” ν•˜λ‚˜μ˜ μš”μ†Œμ—λ§Œ 속함 - FK: text_contents.element_id β†’ layout_elements.element_id (UNIQUE) - ON DELETE CASCADE: μš”μ†Œ μ‚­μ œ μ‹œ OCR 결과도 μ‚­μ œ ``` ### **8️⃣ layout_elements ↔ ai_descriptions (1:1)** ``` - ν•œ λ ˆμ΄μ•„μ›ƒ μš”μ†Œ(figure/table/flowchart)λŠ” ν•˜λ‚˜μ˜ AI μ„€λͺ…λ§Œ 가짐 - ν•œ AI μ„€λͺ…은 ν•˜λ‚˜μ˜ μš”μ†Œμ—λ§Œ 속함 - FK: ai_descriptions.element_id β†’ layout_elements.element_id (UNIQUE) - ON DELETE CASCADE: μš”μ†Œ μ‚­μ œ μ‹œ AI μ„€λͺ…도 μ‚­μ œ ``` ### **9️⃣ pages ↔ question_groups (1:N)** ``` - ν•œ νŽ˜μ΄μ§€λŠ” μ—¬λŸ¬ 문제 κ·Έλ£Ή 포함 - ν•œ 문제 그룹은 ν•˜λ‚˜μ˜ νŽ˜μ΄μ§€μ—λ§Œ 속함 - FK: question_groups.page_id β†’ pages.page_id - ON DELETE CASCADE: νŽ˜μ΄μ§€ μ‚­μ œ μ‹œ 문제 그룹도 μ‚­μ œ ``` ### **πŸ”Ÿ (μ‹ κ·œ) layout_elements ↔ question_groups (1:1)** ``` - '액컀' μš”μ†Œμ™€ '문제 κ·Έλ£Ή' κ°„μ˜ 관계 - ν•œ λ ˆμ΄μ•„μ›ƒ μš”μ†Œ(액컀)λŠ” ν•˜λ‚˜μ˜ 문제 그룹만 생성 κ°€λŠ₯ - ν•œ 문제 그룹은 ν•˜λ‚˜μ˜ 액컀 μš”μ†Œμ— μ˜ν•΄ 생성됨 - FK: question_groups.anchor_element_id β†’ layout_elements.element_id - ON DELETE CASCADE: 액컀 μš”μ†Œ μ‚­μ œ μ‹œ, κ·Έλ£Ή 및 ν•˜μœ„ μš”μ†Œ λ§€ν•‘(question_elements)도 연쇄 μ‚­μ œ ``` ### **1️⃣1️⃣ question_groups ↔ question_elements (1:N)** ``` - '문제 κ·Έλ£Ή'κ³Ό 'μžμ‹ μš”μ†Œ' λ§€ν•‘ κ°„μ˜ 관계 - ν•œ 문제 그룹은 μ—¬λŸ¬ μžμ‹ μš”μ†Œ(ν…μŠ€νŠΈ, κ·Έλ¦Ό, 선택지 λ“±)λ₯Ό 포함 - ν•œ λ§€ν•‘ λ ˆμ½”λ“œλŠ” ν•˜λ‚˜μ˜ 문제 κ·Έλ£Ήμ—λ§Œ 속함 - FK: question_elements.question_group_id β†’ question_groups.question_group_id - ON DELETE CASCADE: 문제 κ·Έλ£Ή μ‚­μ œ μ‹œ 맀핑도 μ‚­μ œ ``` ### **1️⃣2️⃣ layout_elements ↔ question_elements (N:1)** ``` - 'μžμ‹ μš”μ†Œ'와 'λ§€ν•‘' κ°„μ˜ 관계 - ν•œ λ ˆμ΄μ•„μ›ƒ μš”μ†Œ(μžμ‹)λŠ” ν•˜λ‚˜μ˜ 문제 κ·Έλ£Ήμ—λ§Œ 속함 (N:1) - (ν•œ λ¬Έμ œλŠ” μ—¬λŸ¬ μžμ‹ μš”μ†Œλ₯Ό 가짐) - FK: question_elements.element_id β†’ layout_elements.element_id - ON DELETE CASCADE: μžμ‹ μš”μ†Œ μ‚­μ œ μ‹œ 맀핑도 μ‚­μ œ - UNIQUE KEY: (question_group_id, element_id) - 쀑볡 λ§€ν•‘ λ°©μ§€ ``` ### **1️⃣3️⃣ document_types ↔ formatting_rules (1:N)** ``` - ν•œ λ¬Έμ„œ νƒ€μž…μ€ μ—¬λŸ¬ ν¬λ§·νŒ… κ·œμΉ™ 가짐 - ν•œ κ·œμΉ™μ€ ν•˜λ‚˜μ˜ λ¬Έμ„œ νƒ€μž…μ—λ§Œ 속함 - FK: formatting_rules.doc_type_id β†’ document_types.doc_type_id - ON DELETE CASCADE: νƒ€μž… μ‚­μ œ μ‹œ κ·œμΉ™λ„ μ‚­μ œ - UNIQUE KEY: (doc_type_id, class_name) - νƒ€μž…λ³„ 클래슀 κ·œμΉ™ 쀑볡 λ°©μ§€ ```