This commit is contained in:
2026-07-05 21:27:23 +09:00
parent 23d907265a
commit 3abc2edba6
83 changed files with 10351 additions and 1217 deletions
+516
View File
@@ -0,0 +1,516 @@
-- =============================================================================
-- MariaDB 데이터베이스 스키마 생성 SQL (오류 수정 완)
-- Aislo (아이슬로) — AI + Slotti 산림 도로 설계 자동화 시스템
--
-- DB 명: aislo_db
-- DBMS: MariaDB 10.6+
-- 실행 순서:
-- 1. DATABASE 생성 (aislo_db)
-- 2. CREATE TABLE (각 테이블)
-- 3. CREATE INDEX (인덱싱)
-- 4. ALTER TABLE ADD CONSTRAINT (외래키)
-- =============================================================================
-- 0. 데이터베이스 생성
-- =============================================================================
CREATE DATABASE IF NOT EXISTS aislo_db
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
USE aislo_db;
-- 1. 테이블 생성 (순서 중요: FK 참조 테이블이 먼저 생성되어야 함)
-- =============================================================================
/* --------- 1-1. 사용자 & 인증 그룹 --------- */
-- users: 시스템 사용자
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
email VARCHAR(255) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(255) NOT NULL,
position VARCHAR(100), -- 직급 (과장, 대리, 사원)
department VARCHAR(100), -- 부서명 (설계팀, 영업팀)
phone VARCHAR(20), -- 연락처 (010-1234-5678)
company_id INT, -- 소속 회사 (FK는 later)
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL -- 소프트 삭제
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- companies: 회사 정보
CREATE TABLE IF NOT EXISTS companies (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL UNIQUE,
business_registration_number VARCHAR(20) UNIQUE, -- 사업자등록번호
business_address VARCHAR(255), -- 사업장 주소
business_owner VARCHAR(100), -- 사업주 이름
business_status VARCHAR(50), -- 기업 상태 (활동중, 폐업, 휴업)
created_by INT, -- 생성자 (FK는 later)
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-2. 프로젝트 그룹 --------- */
-- projects: 설계 프로젝트
CREATE TABLE IF NOT EXISTS projects (
id CHAR(36) PRIMARY KEY COMMENT 'UUID',
user_id INT NOT NULL, -- 프로젝트 소유자 (FK는 later)
company_id INT NOT NULL, -- 소속 회사 (FK는 later)
name VARCHAR(255) NOT NULL,
region VARCHAR(100), -- 지역명 (울진군 금강송면)
road_type VARCHAR(100), -- 임도 종류 (간선임도, 지선임도, 산불진화임도, 계류보전)
project_year INT, -- 사업 연도
estimated_length_m FLOAT, -- 추정 연장 (m)
memo TEXT,
status VARCHAR(50) DEFAULT 'NEW', -- NEW, FILE_UPLOADED, WF1_ANALYZING, ..., DONE
crs_epsg INT DEFAULT 5178, -- 좌표계 (한국 표준)
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
deleted_at TIMESTAMP NULL DEFAULT NULL,
storage_path VARCHAR(500) -- storage/회사/사용자/project_uuid
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- project_versions: 프로젝트 버전 이력
CREATE TABLE IF NOT EXISTS project_versions (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
version_num INT NOT NULL,
snapshot_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
status VARCHAR(50),
data JSON, -- 설계 데이터 스냅샷
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-3. 파일 & 입력 데이터 그룹 --------- */
-- input_files: 사용자 업로드 원본 파일
CREATE TABLE IF NOT EXISTS input_files (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
file_type VARCHAR(50), -- las, tif, tfw, prj, dxf, dwg, other
original_filename VARCHAR(255) NOT NULL,
raw_file_path VARCHAR(500) NOT NULL, -- storage/.../B03_FileInput/input/...
file_size_mb FLOAT,
upload_by INT, -- FK는 later
upload_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
crs_epsg INT,
metadata JSON, -- resolution_m, data_range, ...
status VARCHAR(50) DEFAULT 'UPLOADED' -- UPLOADED, PROCESSED, ARCHIVED
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- processed_point_cloud: 변환된 포인트클라우드 데이터
CREATE TABLE IF NOT EXISTS processed_point_cloud (
id INT AUTO_INCREMENT PRIMARY KEY,
input_file_id INT NOT NULL, -- FK는 later
project_id CHAR(36) NOT NULL, -- FK는 later
process_type VARCHAR(50), -- filtered, sampled, classified
processed_file_path VARCHAR(500), -- storage/.../B04_wf1_Surface/processed/...
converted_format VARCHAR(50), -- ply, laz, las 등
converted_file_path VARCHAR(500), -- storage/.../B04_wf1_Surface/processed/...
point_count INT,
min_z FLOAT,
max_z FLOAT,
mean_z FLOAT,
x_min FLOAT,
x_max FLOAT,
y_min FLOAT,
y_max FLOAT,
density_per_sqm FLOAT,
classification_summary JSON, -- ground, vegetation, building, ...
processing_params JSON,
processed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
status VARCHAR(50) DEFAULT 'PROCESSING' -- PROCESSING, COMPLETE, FAILED
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-4. 지표면 & 분석 결과 그룹 --------- */
-- surface_models: WF1 지표면 분석 결과
CREATE TABLE IF NOT EXISTS surface_models (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
model_type VARCHAR(50), -- dem_grid, tin, mesh_triangulated, contour_lines
source_file_id INT, -- FK는 later
processed_cloud_id INT, -- FK는 later
status VARCHAR(50) DEFAULT 'PROCESSING', -- PROCESSING, COMPLETE, FAILED
crs_epsg INT,
resolution_m FLOAT,
model_file_path VARCHAR(500), -- storage/.../B04_wf1_Surface/models/...
generation_params JSON, -- filter_type, algorithm, params
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
completed_at TIMESTAMP NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- terrain_layers: WF1 지형 레이어
CREATE TABLE IF NOT EXISTS terrain_layers (
id INT AUTO_INCREMENT PRIMARY KEY,
surface_model_id INT NOT NULL, -- FK는 later
layer_name VARCHAR(100), -- 지표, 제1층, 제2층
geometry_type VARCHAR(50), -- POINTCLOUD, GRID, MESH, CONTOUR
layer_file_path VARCHAR(500), -- storage/.../B04_wf1_Surface/models/...
file_format VARCHAR(50), -- geojson, geotiff, ply, obj
file_size_mb FLOAT,
statistics JSON, -- min_z, max_z, mean_slope, point_count
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-5. 경로 & 설계 그룹 --------- */
-- routes: WF2 경로 설계 결과
CREATE TABLE IF NOT EXISTS routes (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
surface_model_id INT, -- FK는 later
status VARCHAR(50) DEFAULT 'DRAFT', -- DRAFT, CONFIRMED, ARCHIVED
start_chainage_m FLOAT,
end_chainage_m FLOAT,
total_length_m FLOAT,
grade_percent JSON, -- [2.5, 1.8, 3.2, ...] 각 구간 경사도
constraints JSON, -- max_grade, min_radius, avoidance_zones
algorithm_params JSON, -- cost_weights, ...
route_data_path VARCHAR(500), -- storage/.../B05_wf2_Route/route/...
computed_at TIMESTAMP NULL DEFAULT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- route_points: 웹 렌더링용 경로 포인트 샘플
CREATE TABLE IF NOT EXISTS route_points (
id INT AUTO_INCREMENT PRIMARY KEY,
route_id INT NOT NULL, -- FK는 later
chainage_m FLOAT,
elevation_m FLOAT,
slope_percent FLOAT,
sequence_num INT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- route_statistics: 경로 통계
CREATE TABLE IF NOT EXISTS route_statistics (
id INT AUTO_INCREMENT PRIMARY KEY,
route_id INT NOT NULL, -- FK는 later
min_slope FLOAT,
max_slope FLOAT,
mean_slope FLOAT,
cut_volume_m3 FLOAT,
fill_volume_m3 FLOAT,
tree_cutting_volume FLOAT,
cost_score FLOAT
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-6. 종단면 & 횡단면 그룹 --------- */
-- longitudinal_sections: WF3 종단면
CREATE TABLE IF NOT EXISTS longitudinal_sections (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
route_id INT NOT NULL, -- FK는 later
computed_at TIMESTAMP NULL DEFAULT NULL,
data JSON, -- chainages, elevations, grades, design_elevations
longitudinal_file_path VARCHAR(500), -- storage/.../B06_wf3_ProfileCross/longitudinal/...
status VARCHAR(50) DEFAULT 'DRAFT' -- DRAFT, CONFIRMED
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- cross_sections: WF3 횡단면
CREATE TABLE IF NOT EXISTS cross_sections (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
route_id INT NOT NULL, -- FK는 later
chainage_m FLOAT,
sequence_num INT,
data JSON, -- left_slope, right_slope, width_m, cut_volume_m3, fill_volume_m3, structures, notes
cross_section_file_path VARCHAR(500), -- storage/.../B06_wf3_ProfileCross/cross_sections/...
status VARCHAR(50) DEFAULT 'DRAFT' -- DRAFT, CONFIRMED
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-7. 설계 & 구조물 그룹 --------- */
-- structures: WF4 상세 설계 - 구조물
CREATE TABLE IF NOT EXISTS structures (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
cross_section_id INT, -- FK는 later
structure_type VARCHAR(100), -- 낙석방지책, 돌붙임, 계간수로, 낙차공
chainage_m FLOAT,
location VARCHAR(50), -- LEFT, CENTER, RIGHT
length_m FLOAT,
width_m FLOAT,
height_m FLOAT,
material VARCHAR(100), -- 강재, 콘크리트, 목재, 돌
quantity INT,
unit_price FLOAT,
design_notes JSON,
structure_data_path VARCHAR(500), -- storage/.../B07_wf4_DesignDetail/structures/...
last_modified_by INT, -- FK는 later
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-8. 수량 산출 그룹 --------- */
-- quantity_items: WF5 수량 산출
CREATE TABLE IF NOT EXISTS quantity_items (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
category VARCHAR(100), -- 토공, 구조물, 포장, 배수, 녹화, 안전시설
item_name VARCHAR(255),
unit VARCHAR(50), -- m3, 개, m, m2
quantity_design FLOAT,
quantity_actual FLOAT,
unit_price FLOAT,
total_price FLOAT, -- quantity_actual × unit_price
standard_reference VARCHAR(255),
computed_at TIMESTAMP NULL DEFAULT NULL,
quantity_data_path VARCHAR(500), -- storage/.../B08_wf5_Quantity/quantities/...
data JSON -- formula, source, ...
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-9. 산출물 & 문서 그룹 --------- */
-- outputs: WF6 최종 산출물 세트
CREATE TABLE IF NOT EXISTS outputs (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
output_type VARCHAR(100), -- estimation_excel, drawing_dxf, report_pdf, all_bundle
status VARCHAR(50) DEFAULT 'GENERATING', -- GENERATING, COMPLETE, FAILED
generated_by INT, -- FK는 later
generated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
version INT DEFAULT 1,
outputs_directory_path VARCHAR(500), -- storage/.../B09_wf6_Estimation/v1/
metadata JSON -- template_used, company_name, project_name, total_cost, generation_time_sec
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- output_files: 최종 산출 파일
CREATE TABLE IF NOT EXISTS output_files (
id INT AUTO_INCREMENT PRIMARY KEY,
output_id INT NOT NULL, -- FK는 later
file_type VARCHAR(50), -- xlsx, pdf, dxf, dwg, json, zip
original_filename VARCHAR(255),
output_file_path VARCHAR(500), -- storage/.../B09_wf6_Estimation/v1/...
file_size_mb FLOAT,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
download_count INT DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/* --------- 1-10. 변경 이력 & 감시 그룹 --------- */
-- audit_logs: 보안 감시 로그
CREATE TABLE IF NOT EXISTS audit_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT, -- FK는 later
action VARCHAR(100), -- CREATE, READ, UPDATE, DELETE, EXPORT, DOWNLOAD
entity_type VARCHAR(100), -- projects, routes, structures, outputs
entity_id VARCHAR(36),
timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
ip_address VARCHAR(45),
details JSON -- old_value, new_value, reason
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- change_logs: 설계 변경 이력
-- [★오류 수정]: 외래키 ON DELETE SET NULL 조건을 위해 changed_by 컬럼을 NULL 가능으로 변경
CREATE TABLE IF NOT EXISTS change_logs (
id INT AUTO_INCREMENT PRIMARY KEY,
project_id CHAR(36) NOT NULL, -- FK는 later
changed_by INT NULL, -- NOT NULL 에서 NULL로 변경 완료
changed_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
entity_type VARCHAR(100), -- routes, cross_sections, structures, quantity_items
entity_id INT,
old_value JSON,
new_value JSON,
reason VARCHAR(255)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
-- =============================================================================
-- 2. 외래키(FK) 제약조건 추가
-- =============================================================================
ALTER TABLE users
ADD CONSTRAINT fk_users_company_id
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE SET NULL;
ALTER TABLE companies
ADD CONSTRAINT fk_companies_created_by
FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE projects
ADD CONSTRAINT fk_projects_user_id
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE RESTRICT,
ADD CONSTRAINT fk_projects_company_id
FOREIGN KEY (company_id) REFERENCES companies(id) ON DELETE RESTRICT;
ALTER TABLE project_versions
ADD CONSTRAINT fk_project_versions_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE input_files
ADD CONSTRAINT fk_input_files_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_input_files_upload_by
FOREIGN KEY (upload_by) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE processed_point_cloud
ADD CONSTRAINT fk_processed_point_cloud_input_file_id
FOREIGN KEY (input_file_id) REFERENCES input_files(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_processed_point_cloud_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE surface_models
ADD CONSTRAINT fk_surface_models_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_surface_models_source_file_id
FOREIGN KEY (source_file_id) REFERENCES input_files(id) ON DELETE SET NULL,
ADD CONSTRAINT fk_surface_models_processed_cloud_id
FOREIGN KEY (processed_cloud_id) REFERENCES processed_point_cloud(id) ON DELETE SET NULL;
ALTER TABLE terrain_layers
ADD CONSTRAINT fk_terrain_layers_surface_model_id
FOREIGN KEY (surface_model_id) REFERENCES surface_models(id) ON DELETE CASCADE;
ALTER TABLE routes
ADD CONSTRAINT fk_routes_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_routes_surface_model_id
FOREIGN KEY (surface_model_id) REFERENCES surface_models(id) ON DELETE SET NULL;
ALTER TABLE route_points
ADD CONSTRAINT fk_route_points_route_id
FOREIGN KEY (route_id) REFERENCES routes(id) ON DELETE CASCADE;
ALTER TABLE route_statistics
ADD CONSTRAINT fk_route_statistics_route_id
FOREIGN KEY (route_id) REFERENCES routes(id) ON DELETE CASCADE;
ALTER TABLE longitudinal_sections
ADD CONSTRAINT fk_longitudinal_sections_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_longitudinal_sections_route_id
FOREIGN KEY (route_id) REFERENCES routes(id) ON DELETE CASCADE;
ALTER TABLE cross_sections
ADD CONSTRAINT fk_cross_sections_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_cross_sections_route_id
FOREIGN KEY (route_id) REFERENCES routes(id) ON DELETE CASCADE;
ALTER TABLE structures
ADD CONSTRAINT fk_structures_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_structures_cross_section_id
FOREIGN KEY (cross_section_id) REFERENCES cross_sections(id) ON DELETE SET NULL,
ADD CONSTRAINT fk_structures_last_modified_by
FOREIGN KEY (last_modified_by) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE quantity_items
ADD CONSTRAINT fk_quantity_items_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE outputs
ADD CONSTRAINT fk_outputs_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_outputs_generated_by
FOREIGN KEY (generated_by) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE output_files
ADD CONSTRAINT fk_output_files_output_id
FOREIGN KEY (output_id) REFERENCES outputs(id) ON DELETE CASCADE;
ALTER TABLE audit_logs
ADD CONSTRAINT fk_audit_logs_user_id
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE change_logs
ADD CONSTRAINT fk_change_logs_project_id
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
ADD CONSTRAINT fk_change_logs_changed_by
FOREIGN KEY (changed_by) REFERENCES users(id) ON DELETE SET NULL;
-- =============================================================================
-- 3. 인덱스 생성 (성능 최적화)
-- =============================================================================
-- 사용자/회사 인덱싱
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_company_id ON users(company_id);
CREATE INDEX idx_companies_name ON companies(name);
-- 프로젝트 인덱싱
CREATE INDEX idx_projects_user_id ON projects(user_id);
CREATE INDEX idx_projects_company_id ON projects(company_id);
CREATE INDEX idx_projects_status ON projects(status);
CREATE INDEX idx_projects_created_at ON projects(created_at DESC);
CREATE INDEX idx_projects_storage_path ON projects(storage_path);
-- 파일 인덱싱
CREATE INDEX idx_input_files_project_id ON input_files(project_id);
CREATE INDEX idx_input_files_file_type ON input_files(file_type);
CREATE INDEX idx_input_files_raw_file_path ON input_files(raw_file_path);
CREATE INDEX idx_processed_point_cloud_input_file_id ON processed_point_cloud(input_file_id);
CREATE INDEX idx_processed_point_cloud_project_id ON processed_point_cloud(project_id);
CREATE INDEX idx_processed_point_cloud_converted_file_path ON processed_point_cloud(converted_file_path);
-- 지표면 모델 인덱싱
CREATE INDEX idx_surface_models_project_id ON surface_models(project_id);
CREATE INDEX idx_surface_models_status ON surface_models(status);
CREATE INDEX idx_surface_models_model_file_path ON surface_models(model_file_path);
CREATE INDEX idx_terrain_layers_surface_model_id ON terrain_layers(surface_model_id);
CREATE INDEX idx_terrain_layers_layer_file_path ON terrain_layers(layer_file_path);
-- 경로 인덱싱
CREATE INDEX idx_routes_project_id ON routes(project_id);
CREATE INDEX idx_routes_status ON routes(status);
CREATE INDEX idx_routes_route_data_path ON routes(route_data_path);
CREATE INDEX idx_route_points_route_id ON route_points(route_id);
CREATE INDEX idx_route_statistics_route_id ON route_statistics(route_id);
-- 단면 인덱싱
CREATE INDEX idx_longitudinal_sections_project_id ON longitudinal_sections(project_id);
CREATE INDEX idx_longitudinal_sections_route_id ON longitudinal_sections(route_id);
CREATE INDEX idx_longitudinal_sections_file_path ON longitudinal_sections(longitudinal_file_path);
CREATE INDEX idx_cross_sections_project_id ON cross_sections(project_id);
CREATE INDEX idx_cross_sections_route_id ON cross_sections(route_id);
CREATE INDEX idx_cross_sections_chainage_m ON cross_sections(chainage_m);
CREATE INDEX idx_cross_sections_file_path ON cross_sections(cross_section_file_path);
-- 구조물/수량 인덱싱
CREATE INDEX idx_structures_project_id ON structures(project_id);
CREATE INDEX idx_structures_cross_section_id ON structures(cross_section_id);
CREATE INDEX idx_structures_file_path ON structures(structure_data_path);
CREATE INDEX idx_quantity_items_project_id ON quantity_items(project_id);
CREATE INDEX idx_quantity_items_category ON quantity_items(category);
CREATE INDEX idx_quantity_items_file_path ON quantity_items(quantity_data_path);
-- 산출물 인덱싱
CREATE INDEX idx_outputs_project_id ON outputs(project_id);
CREATE INDEX INDEX idx_outputs_version ON outputs(version);
CREATE INDEX idx_outputs_directory_path ON outputs(outputs_directory_path);
CREATE INDEX idx_output_files_output_id ON output_files(output_id);
CREATE INDEX idx_output_files_output_file_path ON output_files(output_file_path);
-- 감시/이력 인덱싱
CREATE INDEX idx_audit_logs_user_id ON audit_logs(user_id);
CREATE INDEX idx_audit_logs_timestamp ON audit_logs(timestamp DESC);
CREATE INDEX idx_audit_logs_entity_type ON audit_logs(entity_type);
CREATE INDEX idx_change_logs_project_id ON change_logs(project_id);
CREATE INDEX idx_change_logs_changed_by ON change_logs(changed_by);
CREATE INDEX idx_change_logs_changed_at ON change_logs(changed_at DESC);
-- =============================================================================
-- 5. 생성 완료 메시지
-- =============================================================================
-- 모든 테이블과 인덱스가 정상적으로 생성되었으면 아래의 SELECT를 실행하여 확인할 수 있습니다:
-- SELECT table_name FROM information_schema.tables WHERE table_schema='public';
-- SELECT indexname FROM pg_indexes WHERE schemaname='public';