Graph DML¶
AkasicDB에서 생성된 그래프에 정점 및 간선을 추가/삭제하고, 속성을 업데이트하는 방법을 안내합니다.
그래프를 변경할 때는 AkasicDB가 제공하는 SQL 함수와 SQL UPDATE를 사용해야 합니다. akasicdb.cypher() 안에서는 CREATE, MERGE, SET, DELETE 절을 지원하지 않습니다.
그래프 준비¶
-- 그래프 'community_graph'를 정의
SELECT akasicdb.define_graph('community_graph');
-- 그래프 정의 'community_graph'에 정점 정의 'person' 추가
SELECT akasicdb.define_vertex(
'community_graph',
'person',
ARRAY['name text', 'age int']
);
-- 그래프 정의 'community_graph'에 간선 정의 'knows' 추가
SELECT akasicdb.define_edge(
'community_graph', 'knows',
'person', 'person',
ARRAY['since timestamptz']
);
-- 그래프 정의 'community_graph'를 기반으로 그래프 생성
SELECT akasicdb.create_graph('community_graph');
Warning
akasicdb.create_graph()의 replace_if_exists 옵션을 사용해 그래프를 재생성하면 기존에 수행한 정점/간선의 추가/삭제 및 속성 업데이트 내역은 모두 사라집니다.
정점/간선 추가¶
Warning
SQL INSERT를 사용하여 정점이나 간선을 추가하려 하면 정상적으로 동작하지 않습니다. 반드시 제공된 함수를 사용해야 합니다.
정점 추가¶
-- 그래프 'community_graph'에 'person' 정점 4개를 추가
SELECT akasicdb.insert_vertex(
'community_graph',
'person',
'{"name": "Alice", "age": 30}'
);
SELECT akasicdb.insert_vertex(
'community_graph',
'person',
'{"name": "Bob", "age": 25}'
);
SELECT akasicdb.insert_vertex(
'community_graph',
'person',
'{"name": "Charlie", "age": 42}'
);
SELECT akasicdb.insert_vertex(
'community_graph',
'person',
'{"name": "Diana", "age": 28}'
);
함수 인자 설명
akasicdb.insert_vertex(
graph_name, -- 정점을 추가할 그래프명
vertex_label, -- 정점 레이블
prop_kv -- 정점의 속성, {"컬럼명":속성값}의 key-value 형태를 가지는 JSON 오브젝트
);
prop_kv는 추가할 정점의 속성을 명시하기 위한 파라미터로, 키(key)가 추가할 정점 레이블의 속성명과 일치해야 합니다. 명시되지 않은 속성은 NULL로 저장됩니다.
정점의 식별자인 vertex_id의 경우 자동으로 배정되며, 함수의 반환값으로 확인할 수 있습니다.
간선 추가¶
-- 그래프 'community_graph'에 정점 ID 1, 2(이 경우 Alice와 Bob)를 연결하는 knows 간선을 추가
SELECT akasicdb.insert_edge(
'community_graph',
'knows', 1, 2,
'{"since": "2020-01-01T00:00:00Z"}'
);
SELECT akasicdb.insert_edge(
'community_graph',
'knows', 2, 4,
'{"since": "2018-09-01T00:00:00Z"}'
);
함수 인자 설명
akasicdb.insert_edge(
graph_name, -- 간선을 추가할 그래프명
edge_label, -- 간선 레이블
src_vid, -- 간선의 출발 정점 ID
dst_vid, -- 간선의 도착 정점 ID
prop_kv -- 간선의 속성, {"컬럼명":속성값}의 key-value 형태를 가지는 JSON 오브젝트
);
주어진 레이블과 속성 정보, 연결할 정점의 ID를 기반으로 새로운 간선을 만들어서 그래프에 추가합니다.
이때 정점 ID는 이미 그래프에 존재하는 정점에 대한 것이어야 합니다.
prop_kv는 추가할 간선의 속성을 명시하기 위한 파라미터로, 키(key)가 추가할 간선 레이블의 속성명과 일치해야 합니다. 명시되지 않은 속성은 NULL로 저장됩니다.
간선의 식별자인 edge_id의 경우 자동으로 배정되며, 함수의 반환값으로 확인할 수 있습니다.
Warning
AkasicDB 커뮤니티 에디션의 경우, 그래프의 정점/간선 수에 제한이 있습니다. 각 정점/간선 레이블 별로 최대 1,000,000 (1M)개의 정점/간선만 저장할 수 있습니다.
정점/간선 삭제¶
Warning
SQL DELETE를 사용하여 정점이나 간선을 제거할 경우 예상대로 동작하지 않을 수 있습니다. 반드시 제공된 함수를 사용해야 합니다.
정점 삭제¶
- 조건부 정점 삭제
-- 그래프 'community_graph'에서 person 레이블의 ID 3번 정점을 삭제
-- 연결된 간선이 없으니 에러 없이 성공
SELECT akasicdb.delete_vertex_restrict(
'community_graph',
'person', 3
);
함수 인자 설명
akasicdb.delete_vertex_restrict(
graph_name, -- 정점을 삭제할 그래프
vertex_label, -- 정점의 레이블
vertex_id -- 삭제할 정점의 ID
);
주어진 레이블과 ID를 가지는 정점을 찾고, 연결된 간선이 없다면 해당 정점을 삭제합니다. 연결된 간선이 있다면 에러(Exception) 메시지를 출력합니다.
정점 삭제에 성공했다면 이 함수는 1을 반환하며, 해당하는 정점이 없어서 삭제하지 못했다면 0을 반환합니다.
- 연쇄형 정점 삭제
-- 그래프 'community_graph'에서 person 레이블의 ID 1번 정점을 삭제
-- 연결된 간선(knows, 1->2)도 함께 삭제됨
SELECT akasicdb.delete_vertex_cascade(
'community_graph',
'person', 1
);
함수 인자 설명
akasicdb.delete_vertex_cascade(
graph_name, -- 정점을 삭제할 그래프
vertex_label, -- 정점의 레이블
vertex_id -- 삭제할 정점의 ID
);
주어진 레이블과 ID를 가지는 정점을 찾고, 연결된 간선이 있다면 해당 간선들까지 모두 삭제합니다.
정점 삭제에 성공했다면 이 함수는 1을 반환하며, 해당하는 정점이 없어서 삭제하지 못했다면 0을 반환합니다.
간선 삭제¶
-- 그래프 'community_graph'에서 knows 레이블의 ID 2번 간선을 삭제
SELECT akasicdb.delete_edge(
'community_graph',
'knows', 2
);
함수 인자 설명
주어진 레이블과 ID를 가지는 간선을 찾아서 삭제합니다.
간선 삭제에 성공했다면 이 함수는 1을 반환하며, 해당하는 간선이 없어서 삭제하지 못했다면 0을 반환합니다.
정점/간선 속성 업데이트¶
-- 그래프 'community_graph'에서 person 레이블의 ID 4번 정점의 속성을 업데이트
UPDATE community_graph.person
SET name = 'Daniel'
WHERE vertex_id = 4;
정점과 간선의 속성을 업데이트할 때는 일반적인 관계형 테이블을 업데이트할 때와 마찬가지로 SQL의 UPDATE 문을 사용할 수 있습니다.
정점 또는 간선의 레이블, 업데이트할 속성과 새 값, 대상 정점/간선을 선택하는 조건을 지정합니다. 각 정점/간선 속성은 그래프 이름을 네임스페이스 이름으로, 레이블을 테이블 이름으로 사용하는 테이블에 저장됩니다.
AkasicDB는 별도의 그래프 속성 업데이트 함수를 제공하지 않습니다. 그래프 속성은 해당 컬럼에 정의된 PostgreSQL 타입으로 저장됩니다.
트랜잭션과 가시성¶
그래프 질의, 그래프 DML 함수, SQL 속성 업데이트는 실행 중인 PostgreSQL 트랜잭션에 포함되며 PostgreSQL의 스냅샷 규칙을 따릅니다. READ COMMITTED에서는 각 명령이 시작될 때 새 스냅샷을 사용하므로, 다른 트랜잭션에서 커밋된 변경 사항은 이후 명령부터 보이고 롤백된 변경 사항은 보이지 않습니다. AkasicDB는 별도의 그래프 전용 트랜잭션 모델을 제공하지 않습니다.