PostgreSQL
강의

PostgreSQL 19의 그래프 기능, 쉽게 이해하기

중년개발자
중년개발자

@loxo

약 6시간 전

3

PostgreSQL 19의 그래프 기능, 쉽게 이해하기

PostgreSQL 19에는 Property Graph(속성 그래프) 기능이 추가됩니다.

한 문장으로 정의하면 다음과 같습니다.

기존 PostgreSQL 테이블을 그대로 두고, 테이블의 행을 정점(Vertex), 테이블 사이의 관계를 간선(Edge)으로 바라보며 검색하는 기능입니다.

별도의 그래프 데이터베이스나 PostgreSQL 확장 기능 없이, 국제 SQL 표준인 SQL/PGQ(SQL Property Graph Queries) 방식으로 그래프 질의를 사용할 수 있게 된 것입니다.

다만 2026년 7월 24일 기준 PostgreSQL 19는 Beta 2 단계이며, 정식 버전은 2026년 9~10월경 출시될 예정입니다. 아직 운영 환경보다는 학습과 검증 목적으로 접근하는 것이 좋습니다. PostgreSQL 19 Beta 2 공식 발표


1. 여기서 말하는 그래프란?

차트나 통계 그래프를 말하는 것이 아닙니다.

사람, 상품, 계좌 같은 대상을 으로 표시하고, 대상 사이의 관계를 으로 연결한 데이터 구조입니다.

그래프 용어로 표현하면 다음과 같습니다.

그래프 용어의미일반 테이블 예
Vertex / Node대상 또는 객체고객, 상품, 계좌
Edge / Relationship대상 사이의 관계주문함, 친구임, 송금함
Label대상이나 관계의 종류customer, product, transferred_to
Property대상이나 관계가 가진 값고객명, 가격, 거래금액

예를 들어 은행 데이터라면 다음과 같이 볼 수 있습니다.

text
(고객A)-[보유함]->(계좌1)-[송금함]->(계좌2)<-[보유함]-(고객B)

기존 SQL에서는 여러 테이블을 JOIN해야 하지만, Property Graph에서는 관계의 모양을 그대로 적어서 찾습니다.


2. PostgreSQL이 그래프 DB로 바뀐 것인가?

정확히 말하면 아닙니다.

PostgreSQL 19의 Property Graph는 Neo4j 같은 전용 그래프 저장 엔진이 아닙니다. 공식 문서에서는 이를 기존 관계형 테이블 위에 놓이는 읽기 전용 뷰와 비슷한 구조로 설명합니다.

  • 데이터는 기존 테이블에 그대로 저장됩니다.
  • CREATE PROPERTY GRAPH가 데이터를 복사하지 않습니다.
  • 그래프 질의는 내부적으로 관계형 조인으로 처리됩니다.
  • 일반 SQL과 그래프 질의를 한 쿼리에서 함께 사용할 수 있습니다.
  • 기존 인덱스, 통계 정보, PostgreSQL 실행 계획을 그대로 이용합니다.

즉, Property Graph는 새로운 저장 방식이라기보다 다음에 가깝습니다.

기존 테이블을 그래프 관점으로 해석하는 선언과 새로운 질의 문법

PostgreSQL 19 Property Graph 공식 문서


3. 기존 테이블을 그래프로 바꾸는 방법

고객, 주문, 상품 테이블이 있다고 가정하겠습니다.

text
customers - customer_id - name orders - order_id - ordered_at products - product_id - name - price customer_orders - customer_id - order_id order_items - order_id - product_id - quantity

이를 그래프로 바라보면 다음과 같습니다.

고객, 주문, 상품은 독립적인 대상이므로 정점이 됩니다.

customer_orders, order_items는 두 대상을 연결하는 역할이므로 간선이 됩니다.

sql
CREATE PROPERTY GRAPH shop_graph VERTEX TABLES ( customers KEY (customer_id) LABEL customer PROPERTIES (customer_id, name), orders KEY (order_id) LABEL "order" PROPERTIES (order_id, ordered_at), products KEY (product_id) LABEL product PROPERTIES (product_id, name, price) ) EDGE TABLES ( customer_orders SOURCE KEY (customer_id) REFERENCES customers (customer_id) DESTINATION KEY (order_id) REFERENCES orders (order_id) LABEL placed, order_items SOURCE KEY (order_id) REFERENCES orders (order_id) DESTINATION KEY (product_id) REFERENCES products (product_id) LABEL contains PROPERTIES (quantity) );

이 명령은 새로운 그래프 데이터를 만들지 않습니다. 어떤 테이블을 정점과 간선으로 해석할지만 등록합니다.


4. 그래프를 어떻게 조회하는가?

고객이 주문한 상품을 찾는 패턴은 다음과 같습니다.

text
(고객)-[주문함]->(주문)-[포함함]->(상품)

PostgreSQL 19에서는 이를 GRAPH_TABLE, MATCH 문법으로 표현합니다.

sql
SELECT result.customer_name, result.order_id, result.product_name, result.quantity FROM GRAPH_TABLE ( shop_graph MATCH (c IS customer) -[p IS placed]-> (o IS "order") -[i IS contains]-> (prd IS product) COLUMNS ( c.name AS customer_name, o.order_id AS order_id, prd.name AS product_name, i.quantity AS quantity ) ) AS result;

그래프 패턴은 다음처럼 읽으면 됩니다.

text
(c IS customer) 고객 정점 -[p IS placed]-> 주문했다는 방향 관계 (o IS "order") 주문 정점 -[i IS contains]-> 상품을 포함한다는 관계 (prd IS product) 상품 정점

GRAPH_TABLE의 결과는 일반 테이블처럼 취급할 수 있습니다. 따라서 외부에서 JOIN, WHERE, ORDER BY, 집계 함수 등을 다시 사용할 수 있습니다. PostgreSQL 19 Graph Queries 공식 문서


5. 기존 JOIN과 무엇이 다른가?

기존 SQL은 테이블을 중심으로 생각합니다.

sql
SELECT c.name, o.order_id, p.name FROM customers c JOIN customer_orders co ON co.customer_id = c.customer_id JOIN orders o ON o.order_id = co.order_id JOIN order_items oi ON oi.order_id = o.order_id JOIN products p ON p.product_id = oi.product_id;

그래프 질의는 관계의 형태를 중심으로 생각합니다.

sql
MATCH (c IS customer) -[IS placed]-> (o IS "order") -[IS contains]-> (p IS product)
기존 SQLProperty Graph
어떤 테이블을 조인할지 생각어떤 관계를 따라갈지 생각
테이블과 FK 조건 중심정점과 간선 패턴 중심
정형화된 집계에 강함연결 관계 탐색에 읽기 쉬움
긴 다중 JOIN이 발생관계를 그림처럼 표현

성능이 자동으로 빨라지는 기능은 아닙니다. 그래프 패턴 역시 내부적으로는 기존 테이블의 조인으로 실행됩니다.

따라서 그래프 질의가 느리다면 기존 SQL과 마찬가지로 다음을 확인해야 합니다.

  • 간선 테이블의 출발점·도착점 컬럼 인덱스
  • 기본키와 외래키
  • EXPLAIN (ANALYZE, BUFFERS)
  • 통계 정보와 데이터 분포
  • 불필요하게 넓은 탐색 범위

6. 어디에 유용한가?

연결 자체가 중요한 데이터에 적합합니다.

금융 이상거래 탐지

text
고객 → 계좌 → 송금 → 계좌 → 고객
  • 여러 계좌를 거쳐 자금이 순환하는 패턴
  • 하나의 기기에서 여러 명의 계좌로 로그인한 관계
  • 동일 전화번호·주소·기기를 공유하는 고객 집단
  • 특정 계좌를 중심으로 연결된 거래 상대방

추천 시스템

text
사용자 → 구매 → 상품 → 카테고리 ← 상품 ← 구매 ← 다른 사용자
  • 같은 상품을 구매한 사용자
  • 사용자가 자주 구매한 카테고리
  • 유사 사용자가 구매한 다른 상품

조직과 권한 분석

text
사용자 → 소속 조직 → 역할 → 접근 권한 → 시스템
  • 특정 사용자가 접근 가능한 시스템
  • 과도한 권한을 가진 사용자
  • 역할을 여러 번 상속받아 생긴 간접 권한

SNS·커뮤니티

text
회원 → 팔로우 → 회원 → 작성 → 게시물
  • 친구의 친구
  • 공통 팔로워
  • 특정 사용자 주변의 연결 집단

지식 그래프와 AI/RAG

text
문서 → 언급 → 회사 → 개발 → 제품 → 사용 → 기술

문서 청크만 벡터 검색하는 방식에 관계 탐색을 더할 수 있습니다. 다만 PostgreSQL 19 Property Graph 자체가 벡터 검색이나 GraphRAG 전체 기능을 제공하는 것은 아닙니다. pgvector, 임베딩 생성, 검색 로직은 별도로 필요합니다.


7. 모델링할 때 가장 중요한 기준

독립적으로 의미가 있는 데이터는 정점

다음과 같은 데이터는 보통 정점이 적합합니다.

  • 고객
  • 계좌
  • 상품
  • 주문
  • 게시물
  • 회사

두 대상을 연결하는 것이 주목적이면 간선

다음과 같은 연결 테이블은 간선에 적합합니다.

  • 친구 관계
  • 팔로우
  • 고객과 주문 연결
  • 주문과 상품 연결
  • 사용자와 역할 연결

사건 자체가 중요하면 정점으로 만들기

은행 거래를 단순히 다음과 같이 만들 수도 있습니다.

text
(출금계좌)-[송금 10만원]->(입금계좌)

그러나 거래에 승인 상태, 환율, 채널, 시간, 지급사유코드 등 많은 정보가 있고 거래 자체를 분석해야 한다면 거래를 정점으로 두는 편이 자연스럽습니다.

text
(출금계좌)-[출금]->(거래)-[입금]->(입금계좌)

판단 기준은 간단합니다.

관계가 중요한가, 아니면 사건 자체가 중요한가?

관계가 중요하면 간선, 사건의 속성과 생명주기가 중요하면 정점으로 설계합니다.


8. 알아두면 유용한 실전 팁

① ID를 검색하려면 Property에 명시하기

KEY는 정점의 식별자이지만 자동으로 조회 가능한 속성이 되는 것은 아닙니다. 명시적인 PROPERTIES 목록을 사용한다면 검색하거나 반환할 ID도 포함해야 합니다.

sql
KEY (customer_id) PROPERTIES (customer_id, name)

② 간선 테이블의 양쪽 컬럼에 인덱스 만들기

sql
CREATE INDEX idx_customer_orders_customer ON customer_orders (customer_id); CREATE INDEX idx_customer_orders_order ON customer_orders (order_id);

그래프 질의도 결국 조인을 수행하므로 연결 컬럼의 인덱스가 중요합니다.

③ 방향을 업무 의미에 맞게 정하기

text
(고객)-[소유함]->(계좌)

처럼 자연스럽게 읽히도록 Source와 Destination을 정의하면 쿼리가 훨씬 이해하기 쉬워집니다. 질의할 때는 정방향, 역방향, 양방향 모두 표현할 수 있습니다.

sql
-- 정방향 (customer)-[owns]->(account) -- 역방향 (account)<-[owns]-(customer) -- 양방향 (person)-[friend]-(person)

④ Label은 명사와 동사로 구별하기

  • 정점: customer, account, product
  • 간선: owns, transferred_to, contains

이렇게 하면 MATCH가 문장처럼 읽힙니다.

EXPLAIN으로 실제 실행 계획 확인하기

sql
EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM GRAPH_TABLE ( shop_graph MATCH ... COLUMNS (...) ) AS g;

그래프 문법만 보고 전용 그래프 탐색 엔진이 동작한다고 생각하면 안 됩니다. 실제로 어떤 조인과 스캔이 발생하는지 확인해야 합니다.

⑥ 그래프와 일반 SQL을 섞어서 사용하기

GRAPH_TABLE 결과를 일반 테이블처럼 사용할 수 있다는 점이 PostgreSQL 방식의 큰 장점입니다.

sql
SELECT g.product_name, SUM(g.quantity) AS total_quantity FROM GRAPH_TABLE ( shop_graph MATCH (c IS customer) -[IS placed]-> (o IS "order") -[i IS contains]-> (p IS product) COLUMNS ( p.name AS product_name, i.quantity AS quantity ) ) AS g GROUP BY g.product_name ORDER BY total_quantity DESC;

그래프는 관계를 찾고, 일반 SQL은 집계와 정렬을 담당하도록 나누면 좋습니다.


9. 현재 PostgreSQL 19의 중요한 한계

가장 큰 제한은 가변 길이 경로 탐색을 아직 지원하지 않는다는 점입니다.

예를 들어 다음과 같은 질문입니다.

text
친구 관계를 1~3단계 따라가라 연결이 끝날 때까지 계속 탐색하라 A에서 B까지 가능한 경로를 찾아라

성숙한 그래프 질의 언어에서는 간선 반복 횟수를 지정할 수 있지만, 현재 PostgreSQL 19 구현에서는 각 단계를 직접 적어야 합니다.

sql
-- 2단계 관계는 2개의 간선을 직접 작성 MATCH (a IS person) -[IS friend]-> (b IS person) -[IS friend]-> (c IS person)

깊이를 알 수 없는 계층이나 네트워크를 탐색하려면 기존 방식인 WITH RECURSIVE를 사용해야 합니다.

이 때문에 PostgreSQL 19 Property Graph는 현재 다음 용도에 더 적합합니다.

  • 깊이가 정해진 관계 패턴
  • 긴 JOIN을 이해하기 쉽게 표현
  • 기존 관계형 데이터에 그래프 관점 추가
  • SQL 집계와 관계 탐색의 결합

반대로 다음 용도에는 아직 전용 그래프 DB가 더 적합할 수 있습니다.

  • 깊이가 불명확한 다단계 탐색
  • 최단 경로 계산
  • 매우 큰 네트워크의 반복 순회
  • 그래프 알고리즘 중심의 서비스
  • 실시간으로 수십 단계 관계를 탐색하는 시스템

참고 글에서도 이 가변 길이 경로 미지원 문제를 핵심 한계로 지적하고 있습니다. Understanding Postgres 19 Property Graphs


10. PostgreSQL 19 그래프의 핵심 결론

PostgreSQL 19의 Property Graph는 PostgreSQL을 완전히 새로운 그래프 데이터베이스로 바꾸는 기능이 아닙니다.

기존 관계형 테이블을 정점과 간선으로 선언하고, 복잡한 JOIN을 관계 패턴 형태로 표현할 수 있게 만든 SQL 표준 기능입니다.

따라서 가장 좋은 사용 방식은 다음과 같습니다.

  • 기존 PostgreSQL 데이터를 그대로 유지한다.
  • 관계가 중요한 일부 영역만 Property Graph로 선언한다.
  • 고정된 깊이의 관계는 MATCH로 조회한다.
  • 집계와 정렬은 일반 SQL로 처리한다.
  • 깊이가 불명확한 탐색은 재귀 CTE를 사용한다.
  • 전용 그래프 알고리즘이 핵심이라면 Neo4j·Memgraph·Apache AGE 등과 비교한다.

현재 단계에서 가장 정확한 평가는 이렇습니다.

“PostgreSQL 안에 그래프 DB가 들어왔다”기보다는, “PostgreSQL이 기존 테이블을 그래프 언어로 읽는 방법을 갖게 됐다”에 가깝습니다.

#PostgreSQL#Property Graph#SQL/PGQ#Database#그래프 데이터베이스

댓글 0

Ctrl + Enter를 눌러 등록할 수 있습니다
※ AI 다듬기는 내용을 정제하는 보조 기능이며, 최종 내용은 사용자가 확인해야 합니다.