Create Graph
AkasicDB에서 그래프 분석을 수행하기 위한 준비 단계인 그래프 생성 과정을 안내합니다. SQL 질의를 이용해 그래프 스키마를 정의하고, 관계형 데이터로부터 그래프를 생성하는 방법을 설명합니다.
1. 테이블 준비
아래 질의는 관계형 스키마만을 포함합니다. 각 테이블에 데이터를 채우는 질의는 아래의 “테이블 데이터 채우기” 부분을 펼쳐서 확인할 수 있습니다.
CREATE TABLE store (
s_id integer PRIMARY KEY,
name varchar(50),
manager varchar(40)
);
CREATE TABLE item (
i_no integer PRIMARY KEY,
name varchar(50),
price decimal(7,2)
);
CREATE TABLE customer (
c_id integer PRIMARY KEY,
first_name varchar(20),
last_name varchar(30)
);
CREATE TABLE orders (
c_id integer,
i_no integer,
s_id integer
);
ALTER TABLE orders ADD CONSTRAINT fk_orders_customer
FOREIGN KEY (c_id) REFERENCES customer(c_id);
ALTER TABLE orders ADD CONSTRAINT fk_orders_item
FOREIGN KEY (i_no) REFERENCES item(i_no);
ALTER TABLE orders ADD CONSTRAINT fk_orders_store
FOREIGN KEY (s_id) REFERENCES store(s_id);
테이블 데이터 채우기
INSERT INTO store (s_id, name, manager)
VALUES
(1, 'ought', 'William Ward'),
(2, 'able', 'Scott Smith'),
(3, 'able', 'Scott Smith'),
(4, 'ese', 'Edwin Adams'),
(5, 'anti', 'Edwin Adams');
INSERT INTO item (i_no, name, price)
VALUES
(1, 'ought', 27.02),
(2, 'able', 1.12),
(3, 'pri', 7.11),
(4, 'ese', 1.35),
(5, 'anti', 4.00),
(6, 'cally', 0.85),
(7, 'ation', 9.94),
(8, 'eing', 2.76),
(9, 'n st', 4.46),
(10, 'barought', 8.94),
(11, 'oughtought', 54.87),
(12, 'ableought', 6.54),
(13, 'priought', 8.76),
(14, 'eseought', 1.85),
(15, 'antiought', 2.57),
(16, 'callyought', 0.31),
(17, 'ationought', 6.49),
(18, 'eingought', 0.87),
(19, 'n stought', 10.61),
(20, 'barable', 29.35);
INSERT INTO customer (c_id, first_name, last_name)
VALUES
(1, 'Javier', 'Lewis'),
(2, 'Amy', 'Moses'),
(3, 'Latisha', 'Hamilton'),
(4, 'Michael', 'White'),
(5, 'Robert', 'Moran'),
(6, 'Brunilda', 'Sharp'),
(7, 'Fonda', 'Wiles'),
(8, 'Ollie', 'Shipman'),
(9, 'Karl', 'Gilbert'),
(10, 'Albert', 'Brunson'),
(11, 'Betty', 'Williams'),
(12, 'Margaret', 'Farias'),
(13, 'Rosalinda', 'Grimes'),
(14, 'Jack', 'Wilcox'),
(15, 'Margie', 'Browning'),
(16, 'Lee', 'Stovall'),
(17, 'Brad', 'Lynch'),
(18, 'Andre', 'Moore'),
(19, 'Stanton', 'Dallas'),
(20, 'Naomi', 'Barnett'),
(21, 'Victor', 'Martinez'),
(22, 'Paul', 'Morris'),
(23, 'Nancy', 'Mccormick'),
(24, 'Monique', 'Baker'),
(25, 'Shawn', 'Prather'),
(26, 'Edith', 'Hernandez'),
(27, 'Margaret', 'Collins'),
(28, 'Pamela', 'Luna'),
(29, 'William', 'Craig'),
(30, 'Kenneth', 'Wood');
INSERT INTO orders (c_id, i_no, s_id)
VALUES
(9,7,4),
(11,14,1),
(16,12,3),
(17,17,3),
(6,14,4),
(18,14,4),
(27,14,4),
(12,17,4),
(28,8,1),
(22,5,2),
(23,14,4),
(24,14,1),
(24,3,5),
(4,8,3),
(10,8,4),
(4,18,3),
(28,15,5),
(12,2,2),
(15,18,1),
(12,20,1),
(16,10,3),
(17,1,4),
(24,19,3),
(6,10,5),
(30,6,1),
(19,12,4),
(21,5,4),
(7,17,3),
(26,9,2),
(25,16,3),
(13,9,5),
(17,15,1),
(29,7,2),
(25,4,2),
(5,6,3),
(18,9,2),
(10,1,4),
(22,16,4),
(12,10,5),
(20,15,3),
(19,7,2),
(10,11,1),
(3,6,2),
(17,12,5),
(18,5,5),
(19,18,5),
(23,8,1),
(6,13,1),
(9,18,1),
(3,5,1),
(17,6,4),
(9,11,4),
(14,3,4),
(23,12,1),
(25,6,3),
(7,10,4),
(14,4,5),
(11,4,1),
(9,10,5),
(17,16,3),
(11,7,4),
(26,4,2),
(7,18,2),
(19,2,5),
(22,18,2),
(26,7,3),
(27,3,5),
(8,17,4),
(26,2,4),
(6,6,5),
(27,6,3),
(22,20,3),
(27,6,2),
(30,2,5),
(13,18,3),
(6,18,2),
(28,7,1),
(27,12,5),
(5,8,1),
(27,11,3),
(9,10,5),
(27,2,2),
(8,18,5),
(22,5,2),
(27,16,5),
(29,9,5),
(30,2,4),
(30,8,5),
(29,3,4),
(30,20,4),
(22,5,2),
(4,1,1),
(29,8,3),
(19,6,2),
(15,17,5),
(15,15,3),
(6,20,1),
(14,15,4),
(18,13,3),
(18,15,4);
2. 그래프 스키마 정의
2.1 그래프 정의 추가
- 새로운 그래프 정의 추가
-- 그래프 'retail_graph'를 정의
SELECT akasicdb.define_graph('retail_graph');
함수 인자 설명
akasicdb.define_graph(
graph_name -- 정의할 그래프의 이름
);
- 기존 그래프 정의 복사 (정점, 간선 정의 포함)
-- 그래프 정의 'retail_graph'를 복사한 새로운 그래프 'retail_graph2'를 정의
SELECT akasicdb.copy_graph(
'retail_graph',
'retail_graph2'
);
함수 인자 설명
akasicdb.copy_graph(
src_graph_name, -- 복사할 그래프 정의 이름
dst_graph_name -- 새로 정의할 그래프의 이름
);
2.2 정점 정의 추가
-- item 테이블로부터 v_item 정점을 정의
SELECT akasicdb.define_vertex(
'retail_graph',
'v_item',
'item'
);
-- store 테이블에 대한 질의로부터 v_store 정점을 정의
SELECT akasicdb.define_vertex(
'retail_graph',
'v_store',
'store',
'SELECT name FROM store'
);
함수 인자 설명
akasicdb.define_vertex(
graph_name, -- 정점 정의를 추가할 그래프 정의의 이름
vertex_label, -- 추가할 정점의 레이블
vertex_table, -- 정점으로 변환될 튜플들이 저장된 테이블
query -- (옵션) 정점으로 변환될 튜플들을 필터링하고, 정점에 속성을 부여하기 위한 질의
);
기본적으로
vertex_table의 모든 컬럼이 정점의 속성으로 저장됩니다. 단,query파라미터를 사용할 경우, 해당 질의의SELECT절에 기술된 컬럼들이 정점의 속성으로 사용됩니다. 이때, 각 속성의 이름은 ‘{기존 컬럼명}_‘으로 저장됩니다.
query파라미터는 아래의 규칙을 따라야 합니다.
SELECT-FROM-WHERE형태의 질의로 단일 테이블에 대한 질의이어야 합니다.ORDER BY,GROUP BY,WITH를 포함한 다른 절들은 지원되지 않습니다.WHERE절에는 단순 이항 표현식(예:A.x = B.y AND A.x = 100)의AND연산만 허용됩니다.SELECT절에는 단순 열 참조(예:A.x), 산술 연산(예:A.x+B.y*C.z), 함수 호출(예:abs(),substr())이 지원됩니다.
Note
정점을 생성하면 사용자가 지정한 속성 외에도
vertex_id라는 속성이 저장됩니다. 이 값은 각 정점의 식별자(identifier)로, 그래프 연산 시 사용하기 위해 생성된 내부 ID입니다. 원본 테이블의 PK 값을 그래프 내에서 직접 사용해야 할 경우, 정점 정의 시에 PK를 속성으로 지정하시기 바랍니다.
2.3 간선 정의 추가
-- v_store, v_item 정점을 연결하는 sell 간선을 정의
SELECT akasicdb.define_edge(
'retail_graph',
'sell',
'v_store', 'store s',
'v_item', 'item i',
'SELECT null FROM store s, orders o, item i
WHERE s.s_id = o.s_id AND i.i_no = o.i_no'
);
함수 인자 설명
akasicdb.define_edge(
graph_name, -- 간선 정의를 추가할 그래프 정의 이름
edge_label, -- 추가할 간선의 레이블
src_vertex_label, -- 출발 정점의 레이블
src_table, -- query 파라미터 내에서 출발 정점에 해당하는 테이블
dst_vertex_label, -- 도착 정점의 레이블
dst_table, -- query 파라미터 내에서 도착 정점에 해당하는 테이블
query -- 출발 정점과 도착 정점간의 관계를 정의한 질의
);
정점 정의와 마찬가지로,
query의SELECT절에 기술된 컬럼들이 간선의 속성으로 사용됩니다. 이때, 각 속성의 이름은 ‘{기존 컬럼명}_‘으로 저장됩니다.또한, SELECT 절이 null이라면, 해당 간선은 속성이 없는 간선이 됩니다.
query파라미터는 다음과 같은 규칙을 따라야 합니다.
SELECT-FROM-WHERE형태의 질의로src_Table과dst_Table간의 join 관계를 포함해야만 합니다.- Aggregation(
GROUP BY와HAVING)을 지원합니다.ORDER BY,WITH,LIMIT을 포함함 다른 절들은 지원하지 않습니다.WHERE와HAVING절에는 단순 이항 표현식(예:A.x = B.y AND A.x = 100)의AND연산만 허용됩니다.SELECT와GROUP_BY절에는 단순 열 참조(예:A.x), 산술연산(예:A.x+B.y*C.z), 집계연산(예:COUNT(),AVG()), 함수 호출(예:abs(),substr())이 지원됩니다.
Note
간선을 생성하면 사용자가 지정한 속성 외에도
src_vertex_id,dst_vertex_id,edge_id라는 속성이 저장됩니다. 이 중<src/dst>_vertex_id의 경우 간선이 연결하는 시작/끝 정점의 식별자이며,edge_id는 각 간선의 식별자입니다. 이 속성들은 정점의vertex_id와 마찬가지로 그래프 연산 시 사용하기 위해 생성된 내부 ID입니다. 원본 테이블의 PK 값을 그래프 내에서 직접 사용해야 할 경우, 간선 정의 시에 PK를 속성으로 지정하시기 바랍니다.
2.1 그래프 정의 삭제
-- 그래프 정의 'retail_graph'를 삭제
SELECT akasicdb.undefine_graph('retail_graph');
함수 인자 설명
akasicdb.undefine_graph(
graph_name -- 삭제할 그래프 정의의 이름
);
그래프 정의를 삭제할 경우, 해당 그래프 정의에 포함된 정점/간선 정의 또한 삭제됩니다.
2.2 정점 정의 삭제
-- 그래프 정의 'retail_graph'로부터 정점 정의 'v_item' 삭제
SELECT akasicdb.undefine_vertex('retail_graph', 'v_item');
함수 인자 설명
akasicdb.undefine_vertex(
graph_name, -- 정점 정의를 제거할 그래프 정의
vertex_label -- 제거할 정점 정의의 레이블
);
정점 정의를 삭제할 경우, 해당 정점 정의와 연결된 간선 정의 또한 삭제됩니다.
2.3 간선 정의 삭제
-- 그래프 정의 'retail_graph'로부터 간선 정의 'sell' 삭제
SELECT akasicdb.undefine_edge('retail_graph', 'sell');
함수 인자 설명
akasicdb.undefine_edge(
graph_name, -- 간선 정의를 제거할 그래프 정의
edge_label -- 제거할 간선 정의의 레이블
);
3. 그래프 생성 및 삭제
3.1 그래프 생성
-- 그래프 정의 `retail_graph`를 기반으로 그래프 생성
SELECT akasicdb.create_graph('retail_graph');
-- 이미 retail_graph가 생성되어 있을 경우, 이를 제거하고 재생성
SELECT akasicdb.create_graph('retail_graph', replace_if_exists:=true);
함수 인자 설명
akasicdb.create_graph(
graph_name, -- 생성할 그래프의 이름 (= 그래프 생성에 필요한 그래프 정의의 이름)
replace_if_exists -- (옵션) true 혹은 false, 기본값은 false
-- true일 경우, 이미 존재하는 그래프를 제거하고 다시 그래프를 생성
-- false일 경우, 이미 그래프가 존재한다면 에러를 반환
);
그래프가 생성된 후에도 그래프 스키마 정의 질의를 사용하여 그래프 정의를 수정할 수 있습니다. 그러나 그래프의 정의만 수정될 뿐 이미 생성된 그래프는 수정되지 않습니다.
수정된 그래프 정의를 그래프 데이터에 반영하기 위해서는,
replace_if_exists옵션을 사용해서 그래프를 재생성해야 합니다.
⚠️ 주의 사항
AkasicDB 커뮤니티 에디션의 경우, 그래프의 정점/간선 수에 제한이 있습니다. 각 정점/간선 레이블 별로 최대 1,000,000 (1M)개의 정점/간선만 생성할 수 있습니다.
3.2 그래프 삭제
-- 생성된 그래프 'retail_graph'만 삭제
SELECT akasicdb.delete_graph('retail_graph');
-- 생성된 그래프와, 그래프 정의까지 모두 삭제
SELECT akasicdb.delete_graph('retail_graph', remove_definition:=true);
함수 인자 설명
akasicdb.delete_graph(
graph_name -- 삭제할 그래프의 이름
remove_definition -- (옵션) true 혹은 false, 기본값은 false
-- true일 경우, 그래프 정의까지 제거
-- false일 경우, 생성된 그래프만 제거하고, 그래프 정의는 유지
);