| 용어 | 설명 | 비고 |
|---|---|---|
| Cypher | Neo4j에서 사용하는 그래프 질의 언어 | SQL에 대응되는 Neo4j 전용 언어 |
| CQL (Cypher Query Language) | Cypher의 공식 명칭 또는 별칭 | Cypher = CQL |
즉, Cypher = CQL이고, 둘 다 같은 것을 가리킵니다. Neo4j 문서에서도 혼용되지만, "Cypher"라는 이름이 더 널리 쓰입니다.
| SQL | Cypher |
|---|---|
SELECT * FROM users | MATCH (u:User) RETURN u |
JOIN 사용 | ()-[]->()로 관계 탐색 |
| 테이블 기반 | 노드와 관계 기반 |
Neo4j는 **그래프 데이터베이스(Graph Database)**로, 관계형 데이터베이스(RDBMS)와는 다른 구조로 데이터를 저장하고 조회합니다. 핵심 개념만 먼저 간단히 설명하면 다음과 같습니다:
| 구성요소 | 설명 | 예시 |
|---|---|---|
| 노드(Node) | 데이터의 주체 (객체) | 사람, 제품, 회사 등 |
| 관계(Relationship) | 노드 간의 연결 및 방향성 있는 관계 | 친구이다(FRIEND), 일한다(WORKS_AT) |
| 속성(Properties) | 노드나 관계에 부여된 키-값 쌍의 정보 | 이름: "Alice", 나이: 30 |
| 레이블(Label) | 노드의 유형을 분류하는 태그 | :Person, :Company |
(:Person {name: "Alice"}) -[:FRIEND]-> (:Person {name: "Bob"})
(:Person {name: "Alice"}) -[:WORKS_AT]-> (:Company {name: "Neo4j"})
이 구조는 다음과 같은 의미를 가집니다:
| 특징 | 설명 |
|---|---|
| 직접 연결된 관계 탐색이 빠름 | 조인(Join) 없이 관계를 따라가므로 빠름 |
| 스키마 유연함 | RDB처럼 테이블 구조 강제 없음 |
| Cypher 언어 사용 | 그래프 질의 언어 (SQL 유사) |
// 노드 생성
CREATE (:Person {name: "Alice", age: 30})
CREATE (:Person {name: "Bob", age: 25})

// 관계 생성
MATCH (a:Person {name: "Alice"}), (b:Person {name: "Bob"})
CREATE (a)-[:FRIEND]->(b)

// 관계 조회
MATCH (a:Person)-[:FRIEND]->(b:Person)
RETURN a.name, b.name

**리팩토링(Refactoring)**은 **코드나 쿼리의 "기능은 그대로 유지하면서 구조나 표현을 더 깔끔하고 효율적으로 바꾸는 것"**임.
🎯 관계형 모델(SQL 기반)을 Neo4j 그래프 모델(Cypher 기반)로 리팩토링하라

Download SQLite sample database
chinook.db에 있는 주요 테이블들:| 테이블 이름 | 설명 (추정) |
|---|---|
albums | 앨범 정보 |
artists | 아티스트 정보 |
customers | 고객 |
employees | 직원 |
genres | 장르 |
invoices | 인보이스 (청구서) |
invoice_items | 청구 내역 항목 |
media_types | 미디어 타입 |
playlists | 재생 목록 |
playlist_track | 재생 목록과 트랙 간 관계 |
tracks | 트랙 (노래 등) |
sqlite_sequence / sqlite_stat1 | SQLite 내부 메타 정보 (사용 안 함) |
Node로 바꿀 테이블:
Artist, Album, Track, Genre, Customer, Invoice, PlaylistRelationship으로 바꿀 외래키 연결:
(:Artist)-[:CREATED]->(:Album)(:Album)-[:CONTAINS]->(:Track)(:Track)-[:HAS_GENRE]->(:Genre)(:Customer)-[:MADE]->(:Invoice)(:Invoice)-[:INCLUDES]->(:Track) (invoice_items 통해 연결)(:Playlist)-[:HAS]->(:Track)artists(ArtistId) → albums(ArtistId)albums(AlbumId) → tracks(AlbumId)CREATE (:Artist {id: 1, name: "AC/DC"});
CREATE (:Album {id: 1, title: "For Those About To Rock We Salute You"});
MATCH (a:Artist {id: 1}), (b:Album {id: 1})
CREATE (a)-[:CREATED]->(b);
CREATE (:Track {
id: 1,
name: "For Those About To Rock (We Salute You)",
composer: "Angus Young, Malcolm Young, Brian Johnson",
milliseconds: 343719,
bytes: 11170334,
price: 0.99
});
MATCH (al:Album {id: 1}), (t:Track {id: 1})
CREATE (al)-[:CONTAINS]->(t);