# Memgraph 데이터 모델 설계 ## 1. 프로젝트 목표 본 프로젝트의 최종 목표는 Job 실행 순서를 최적화하여 전체 공정의 **소요 시간(Duration)**과 **비용(Cost)**을 최소화하는 최적의 **시나리오(Scenario)**를 찾는 것입니다. 이를 위해 Memgraph 데이터베이스에 공정 데이터를 모델링하고, 다양한 분석 쿼리를 실행할 수 있는 기반을 마련합니다. ## 2. 데이터 모델 (Graph Schema) ### 2.1. 노드 (Nodes) | 노드 레이블 | 설명 | 주요 속성 (Properties) | | ---------------- | -------------------------------------------------------------------- | ---------------------------------------------------- | | `Job` | 실행되어야 할 개별 작업 단위. `JobType`의 인스턴스. | `id`, `name`, `description`, `duration`, `cost` | | `JobType` | `Job`의 유형을 정의하는 템플릿. (예: '용접', '조립', '검사') | `type_id`, `name` | | `Object` | `Job` 수행에 사용되거나 `Job`의 결과로 나오는 객체. `ObjectType`의 인스턴스. | `id`, `name`, `unit_price`, `quantity` | | `ObjectType` | `Object`의 유형을 정의하는 템플릿. (예: '부품A', '반제품B') | `type_id`, `name` | | `Activity` | `Job`과 `Object` 간의 n:m 관계를 연결하는 중간 노드. | `id`, `name`, `description` | | `Status` | `Job`, `Object`, `Activity`의 현재 상태. (예: '대기', '진행중', '완료') | `status_id`, `name` | | `Scenario` | 특정 순서로 배열된 `Job`들의 집합. 다른 `Scenario`로부터 파생될 수 있음. | `id`, `name`, `description`, `total_duration`, `total_cost` | ### 2.2. 관계 (Relationships) | 관계 타입 | 시작 노드 | 끝 노드 | 설명 | | -------------- | ---------------- | ---------------- | ----------------------------------------------------------------- | | `IS_A` | `Job` | `JobType` | `Job`이 어떤 `JobType`에 속하는지 정의 (상속) | | `IS_A` | `Object` | `ObjectType` | `Object`가 어떤 `ObjectType`에 속하는지 정의 (상속) | | `PRECEDES` | `Job` (선행) | `Job` (후행) | `Job` 실행의 선후 관계 정의 (A -[:PRECEDES]-> B: A가 B보다 먼저) | | `INCLUDES` | `Scenario` | `Job` | `Scenario`에 어떤 `Job`들이 포함되는지 정의 | | `PERFORMS` | `Job` | `Activity` | `Job`이 어떤 `Activity`를 수행하는지 연결 | | `ACTS_ON` | `Activity` | `Object` | `Activity`가 어떤 `Object`에 영향을 주는지 연결 | | `HAS_STATUS` | `Job`, `Object`, `Activity` | `Status` | 각 노드의 현재 상태를 나타냄 | | `DELTA_FROM` | `Scenario` (파생) | `Scenario` (기반) | `Scenario`가 어떤 기반 `Scenario`로부터의 증분으로 정의되는지 표시 | ### 3. 스키마 다이어그램 (Mermaid) ```mermaid graph TD subgraph "Core Entities" J1(Job 1) J2(Job 2) A1(Activity) O1(Object) end subgraph "Types & Status" JT(JobType) OT(ObjectType) ST(Status) end subgraph "Scenario" S1(Scenario Base) S2(Scenario Delta) end J1 -- IS_A --> JT J1 -- PRECEDES --> J2 O1 -- IS_A --> OT J1 -- PERFORMS --> A1 A1 -- ACTS_ON --> O1 J1 -- HAS_STATUS --> ST O1 -- HAS_STATUS --> ST A1 -- HAS_STATUS --> ST S2 -- INCLUDES --> J1 S2 -- INCLUDES --> J2 S2 -- DELTA_FROM --> S1 ``` ### 4. 주요 Cypher 쿼리 예시 - **특정 Job의 모든 선행 Job 찾기:** ```cypher MATCH (j:Job {id: 'target_job_id'})<-[:PRECEDES*]-(predecessor) RETURN predecessor; ``` - **특정 시나리오의 총 예상 소요 시간 및 비용 계산:** ```cypher MATCH (s:Scenario {id: 'scenario_id'})-[:INCLUDES]->(j:Job) RETURN s.name, sum(j.duration) AS total_duration, sum(j.cost) AS total_cost; ``` - **Critical Path 찾기 (가장 오래 걸리는 Job 경로):** ```cypher MATCH path = (start:Job)-[:PRECEDES*]->(end:Job) WHERE NOT EXISTS ((start)<-[:PRECEDES]-()) AND NOT EXISTS ((end)-[:PRECEDES]->()) WITH nodes(path) AS jobs_in_path UNWIND jobs_in_path AS job WITH path, sum(job.duration) AS path_duration RETURN path, path_duration ORDER BY path_duration DESC LIMIT 1; ```