Postgres 19의 프로퍼티 그래프 이해하기
요약
Postgres 19는 기존 테이블 구조를 활용하여 '프로퍼티 그래프' 기능을 도입했습니다. 이 기능은 데이터를 복사하거나 별도의 엔진을 만들지 않고, 관계형 조인(JOIN)으로 컴파일되어 기존 옵티마이저와 인덱스를 그대로 사용합니다. 이를 통해 개발자는 SQL/PGQ에서 그래프 패턴을 작성하며 데이터베이스 내의 관계를 효율적으로 탐색할 수 있습니다.
핵심 포인트
- 프로퍼티 그래프는 데이터를 복사하지 않고, JOIN 기반으로 작동하여 성능 최적화가 용이함.
- 기존 테이블 구조(차원/팩트)를 정점과 간선으로 자연스럽게 모델링 가능함.
- 그래프 질의는 고정된 관계 패턴 탐색에 적합하며, 가변 길이 경로는 지원하지 않음.
- CREATE PROPERTY GRAPH로 선언하는 것은 기존 외래 키 구조를 그래프 형태로 읽는 방법 정의임.
- Postgres 19의
프로퍼티 그래프는 기존 테이블을 정점과 간선으로 선언하고MATCH
로 고정된 관계 패턴을 검색하는 SQL/PGQ 기능으로, 데이터를 복사하거나 별도 그래프 실행 엔진을 만들지 않음
- 그래프 패턴은
관계형 조인으로 컴파일되어 기존 옵티마이저·인덱스·통계를 그대로 사용하므로, 느린 순회도 일반 조인과 같은 방식으로 분석하고 최적화할 수 있음 - 차원 테이블은 정점, 순수 조인 테이블은 간선으로 자연스럽게 대응하지만, 여러 외래 키와 자체 속성을 가진
팩트 테이블은 이벤트를 나타내는 허브 정점으로 모델링하는 편이 적합함 - 하나의 테이블을 서로 다른 별칭으로 정점과 여러 간선에 동시에 선언할 수 있어,
results
의 기존 외래 키를 이용한 별도 간선 테이블을 생성·저장할 필요가 없음
- Postgres 19는
가변 길이 경로를 지원하지 않으므로 최단 경로·N홉 도달성·PageRank에는 맞지 않으며, 관계 구조를 미리 아는 고정 길이 탐색에 적합함
관계형 스키마를 그래프로 읽는 방식
- 정규화된 관계형 스키마에서
drivers
, constructors
, circuits
같은 차원 테이블은 엔터티를 담고, 팩트 테이블은 경기 결과나 예선 세션 같은 이벤트를 기록함
-
각 행은 잠재적인
정점이고, 외래 키는 다른 행을 가리키는 잠재적인 간선임 -
ER 다이어그램은 스키마 수준의 그래프에 해당함
-
실제 행과 외래 키 관계는 인스턴스 수준의 그래프에 해당함
-
“각 결과에 해당하는 constructor를 찾는다”는 요청은 관계형 SQL에서
results JOIN constructors ON ...
로 작성하는 그래프 순회임
- SQL/PGQ는 그래프 자체를 새로 추가하지 않고, 조인을 직접 나열하는 대신
그래프 형태로 질문을 작성하게 해줌 - RelBench 방식은 테이블을 pandas로 가져와 메모리에서 PyTorch 그래프로 구성하지만, Postgres 프로퍼티 그래프는 데이터베이스 안의 기존 테이블 관계를 그대로 사용함
- PyG의 예제도 주로 평면 파일이나 메모리 내 그래프를 사용함
- Formula 1 데이터셋으로 실험한 코드는 GitHub 저장소에서 확인할 수 있음
프로퍼티 그래프의 구성
CREATE PROPERTY GRAPH
는 기존 테이블 위에 만드는 이름 있는 선언 객체임
VERTEX TABLES
는 행을 정점으로 읽을 테이블을 지정함
EDGE TABLES
는 행을 연결 관계로 읽을 테이블을 지정함
- 각 정점 테이블에는 다음 요소를 정의함
KEY
: 정점의 식별자로, 대부분 기본 키를 사용함
LABEL
: MATCH
에서 사용할 정점 유형 이름임
PROPERTIES
: 그래프 질의에서 접근할 수 있는 열 목록임
- 각 간선 테이블에는
SOURCE
와 DESTINATION
을 지정하며, 두 값은 각각 정점의 키를 참조함
CREATE PROPERTY GRAPH
는 데이터를 이동하거나 복사하지 않음
-
행은 원래 테이블에 그대로 남아 있음
-
선언은 기존 외래 키 구조를 그래프로 읽는 방법만 정의함
-
프로퍼티 그래프의 구조적 요소는
정점과 간선 두 종류뿐임 -
레이블과 프로퍼티는 정점 또는 간선에 속하는 속성임
psql
에서 각 요소의 Element Kind
는 vertex
또는 edge
중 하나임
MATCH
로 고정된 패턴 질의하기
- 그래프 질의는
GRAPH_TABLE(...)
안에 MATCH
패턴을 작성하는 방식임
- 다음 패턴은 driver에서 result를 거쳐 race로 이어지는 관계를 나타냄
MATCH (d IS driver)<-[IS of_driver]-(res IS result)-[IS in_race]->(ra IS race)
COLUMNS
절은 그래프 질의가 외부로 반환할 열을 지정함
- 바깥쪽
SELECT
에서는 GRAPH_TABLE(...)
의 결과를 일반 테이블처럼 조회할 수 있음
- 패턴에 방향과 레이블이 포함되어 관계를 문장처럼 읽을 수 있으므로, 동일한 다중 조인보다 구조를 파악하기 쉬움
실행 시 관계형 조인으로 변환되는 구조
MATCH
는 Postgres에 별도로 덧붙인 그래프 실행 엔진이 아니라 관계형 조인으로 컴파일되는 문법임
- driver–result–race 패턴에
EXPLAIN
을 실행하면 기반 테이블을 대상으로 한 4개의 해시 조인이 나타남
-
직접 작성한 조인과 마찬가지로 다음 요소를 사용함
-
기존 Postgres 옵티마이저
-
기존 인덱스
-
기존 통계
-
그래프 순회가 느리다면 원인과 최적화 방법도 일반 조인이 느린 경우와 같음
psql
에서도 테이블과 유사한 명령으로 그래프를 조사할 수 있음
\dG
: 프로퍼티 그래프 목록을 표시함
\d f1
: 각 정점과 간선, 기반 테이블, 요소 종류, 간선의 출발·도착 정점을 보여줌
\d+ f1
: 전체 CREATE PROPERTY GRAPH
문을 재구성하며, 간선 테이블의 기본 키에서 추론한 간선 키도 포함함
키와 프로퍼티의 차이
- 정점의
KEY
로 지정한 열이 자동으로 프로퍼티가 되지는 않음
driver_id
를 정점 키로만 지정한 뒤 d.driver_id = 1
로 필터링하면, 해당 열이 질의 가능한 프로퍼티가 아니므로 실패함
- 키는 정점을 식별하지만 질의에 노출하지는 않음
- ID 열을 필터링하거나 반환하려면
PROPERTIES
목록에 명시적으로 추가해야 함
Postgres 19의 가변 길이 경로 제약
- Postgres 19는 간선을 1~3회 따라가는 식의
요소 패턴 수량자를 지원하지 않음
ERROR: element pattern quantifier is not supported
- 두 홉을 탐색하려면
MATCH
에 간선 패턴 두 개를 명시해야 함
- 임의 길이의 경로는 프로퍼티 그래프 문법으로 표현할 수 없음
- 깊이가 열려 있는 탐색은 기반 테이블에 대한
재귀 CTE로 처리해야 하며, 이 경우 프로퍼티 그래프 문법을 벗어남
기존 테이블을 정점과 간선으로 매핑하기
차원 테이블은 정점
drivers
, constructors
, circuits
처럼 안정적인 기본 키와 속성을 가진 엔터티 테이블은 정점으로 직접 대응함
-
기본 키를 정점 키로 사용하고 필요한 열을 프로퍼티로 노출하면 됨
순수 조인 테이블은 간선
student_courses(student_id, course_id)
같은 다대다 브리지 테이블은 두 엔터티를 연결하는 것이 본래 역할이므로 간선으로 자연스럽게 대응함
- 한쪽 외래 키를 출발 정점, 다른 쪽 외래 키를 도착 정점으로 선언함
- 조인 테이블의 각 행 자체가 하나의 관계이므로 별도의 그래프용 데이터 변환이 필요하지 않음
- 이 구조에서는
students
와 courses
가 정점이고, student_courses
가 enrolled_in
간선이 됨
팩트 테이블은 이벤트 정점
results
행은 driver, race, constructor라는 세 엔터티를 가리키면서 grid
, position
, points
, status
같은 자체 데이터도 가짐
- SQL/PGQ 간선은 출발점 하나와 도착점 하나를 가진
이항 관계이므로, 세 개의 외래 키를 가진 행 전체를 단일 간선으로 만들 수 없음 - 팩트 행 자체가 분석 대상이라면 해당 테이블을 정점으로 선언하는 편이 적합함
results
정점은 이벤트와 그 속성을 보유함
results_driver
, results_race
, results_constructor
같은 좁은 간선이 외부 엔터티와 연결함
- 이 모델은
driver <- result -> race
같은 허브 구조를 만들며, result 정점에서 멈춰 필터링하거나 속성을 조회할 수 있음
- 관계 자체가 관심 대상이면 간선으로, 고유 속성을 가진 특정 행이나 이벤트가 관심 대상이면 정점으로 모델링함
- 조인 테이블은 관계를 나타내고, 팩트 테이블은 이벤트를 나타냄
하나의 테이블을 정점과 간선으로 동시에 사용하기
- “정점 또는 간선”이라는 구분은 기반 테이블이 아니라 그래프의 각
요소 선언에 적용됨 - 하나의 테이블을 서로 다른 별칭으로
VERTEX TABLES
와 EDGE TABLES
양쪽에 선언할 수 있음
results
를 result 정점으로 사용하면서 같은 테이블을 다음 간선 별칭으로 재사용할 수 있음
results AS res_driver
: result에서 driver로 연결함
results AS res_race
: result에서 race로 연결함
results AS res_constr
: result에서 constructor로 연결함
- 각 간선 별칭은
results
에 이미 존재하는 기본 키와 외래 키 열을 사용함
- 별도의
results_driver
, results_race
, results_constructor
테이블을 만들 필요가 없으며, 별칭은 데이터를 저장하지 않음
- 외래 키가 세 개인 팩트 테이블은 하나의 다중 종점 간선이 아니라, 각각 출발점과 도착점이 하나인 간선 별칭 세 개로 선언해야 함
- 이 방식은 세 개의 물리 테이블이나 뷰 대신 하나의 기반 테이블에 대한 세 개의 선언적 별칭을 사용함
프로퍼티 이름과 타입 충돌
PROPERTIES
를 생략하면 SQL/PGQ는 테이블의 모든 열을 프로퍼티로 노출함
results
와 qualifying
에 모두 number
열이 있지만 각각 double precision
과 bigint
라면 다음 오류가 발생함
ERROR: property "number" data type mismatch: double precision vs. bigint
- 그래프 전체에서 같은 이름의 프로퍼티는 하나의 타입을 가져야 하므로, 서로 다른 타입의 동명 열이 충돌함
- 필요한 열만
PROPERTIES
에 명시하면 충돌하는 열을 그래프에서 제외할 수 있음
- 키가 자동으로 프로퍼티가 되지 않는 문제와 타입 충돌은 모두
명시적인 프로퍼티 허용 목록으로 해결 가능함
적합한 질의와 부적합한 질의
고정된 관계 패턴
-
프로퍼티 그래프는 “X와 이 특정 패턴으로 연결된 대상을 찾아라”라는 질문에 적합함
-
Formula 1 그래프에서는 다음과 같은 질의를 작성할 수 있음
-
특정 driver가 어느 constructor에서 경주했는지 탐색함
-
driver에서 result와 race를 거쳐 다른 result와 driver로 이어지는 패턴으로 경쟁자를 찾음
-
출발 순위가 10위 밖이고 driver가 Italian인 결과처럼 구조와 속성 조건을 함께 필터링함
-
관계의 모양을 미리 알고 그 구조가
고정되고 유한할 때 검색·필터링·집계 문법의 가독성이 높아짐 -
여러 번의 자기 조인이 필요한 질의도 하나의
MATCH
패턴으로 읽기 쉽게 표현할 수 있음
경로 자체가 미지수인 문제
-
다음 문제는 Postgres 19 프로퍼티 그래프에 맞지 않음
-
두 driver 사이의 최단 경로
-
N홉 안에서 도달할 수 있는 모든 대상
-
깊이를 미리 알 수 없는 연결 탐색
-
이런 질의는 가변 길이 순회가 필요하므로 기반 테이블에 대한 재귀 CTE를 사용해야 함
PageRank, 커뮤니티 탐지, 중심성 계산 같은 그래프 알고리듬도 패턴 매칭과 다른 문제이므로 이 기능의 범위에 속하지 않음 -
프로퍼티 그래프는 경로 구조를 알고 있을 때 연결 대상을 찾지만, X와 Y가 어떤 경로로 연결됐는지 모르는 상태에서 경로를 발견하거나 그래프의 구조적 중요도를 계산하지는 못함
도입 전 판단할 점
-
SQL/PGQ는 기존 외래 키 구조 위에 놓이는
선언적 오버레이이며, 별도로 선택하지 않는 한 추가 데이터를 저장하지 않음 -
주요 이점은 두 가지임
-
고정된 형태의 순회를 관계형 조인보다 읽기 쉽게 작성할 수 있음
-
스키마를 그래프로 문서화하는 이름 있는 객체를 제공함
-
가장 큰 제약은 가변 길이 경로가 없어 깊거나 개방된 탐색을 재귀 SQL로 처리해야 한다는 점임
-
테이블 자체가 본질적으로 정점이나 간선인 것은 아니며, 각 그래프에서 그 행을 정점·간선 또는 양쪽으로 읽을지 결정할 수 있음
-
Postgres 19에서 기존 스키마에 고정된 그래프 패턴을 질의하려는 경우, 별도 그래프 데이터베이스로 데이터를 옮기기 전에
CREATE PROPERTY GRAPH
와 MATCH
를 검토할 수 있음
- 알 수 없는 깊이를 탐색하려면 재귀 CTE가 필요하지만, 어느 방식을 사용하든 데이터가 Postgres를 떠날 필요는 없음
- 실제 도입 전에는 필요한 성능이 나오는지 직접 테스트해야 함
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기