このトピックでは、リレーショナルテーブルからグラフデータベースにデータを同期する方法について説明します。
前提条件
高権限アカウントを使用して、
ganos_graph拡張機能を作成します。説明この拡張機能は、Apache AGE によって提供される機能に依存しています。 この拡張機能をインストールする前に、Apache AGE 拡張機能をインストールして有効にする必要があります。
拡張機能のインストール時に
ERROR: invalid extension name: "ganos_graph"のようなエラーが発生した場合は、お問い合わせください。
CREATE EXTENSION IF NOT EXISTS ganos_graph;グラフとラベルを作成します。
SELECT create_graph('<graph_name>'); SELECT create_vlabel('<graph_name>', '<label_name>'); SELECT create_elabel('<graph_name>', '<label_name>');
グラフデータベースへのデータの同期
トリガーを使用して、リレーショナルデータベースからグラフデータベースへの操作を同期します。リレーショナルデータベースのテーブルで INSERT、UPDATE、または DELETE 操作が実行されると、トリガーはこれらの変更を自動的にキャプチャし、操作をグラフデータベースに同期します。これにより、データ整合性が確保されます。
頂点トリガー
age_create_vertex_insert_trigger
頂点テーブルの INSERT トリガーを作成します。
構文
age_create_vertex_insert_trigger('<graph_name>',
'<label_name>',
'<table_name>',
'<vertex_primary_key_field_name>' default 'id',
'<custom_property_processing_function>')<vertex_primary_key_field_name> は整数である必要があります。
int4(32 ビット整数)またはint8(64 ビット整数)型を使用できます。<custom_property_processing_function> は、リレーショナルテーブルのプロパティ値をグラフの頂点プロパティ値に変換するために指定する関数です。関数の構文:
CREATE OR REPLACE FUNCTION custom_insert_function(NEW RECORD, columns TEXT) RETURNS JSON AS $$ BEGIN RETURN json_build_object('name', NEW.name); /* 名前を返す */ END; $$ LANGUAGE plpgsql;
age_create_vertex_update_trigger
頂点テーブルの UPDATE トリガーを作成します。
構文
age_create_vertex_update_trigger('<graph_name>',
'<label_name>',
'<table_name>',
'<vertex_primary_key_field_name>' default 'id',
'<custom_property_processing_function>')<vertex_primary_key_field_name> は整数である必要があります。
int4(32 ビット整数)またはint8(64 ビット整数)型を使用できます。<custom_property_processing_function> は、リレーショナルテーブルのプロパティ値をグラフの頂点プロパティ値に変換するために指定する関数です。この関数は、古いグラフのプロパティ値の保持をサポートしています。関数の構文:
CREATE OR REPLACE FUNCTION custom_update_function(OLD RECORD, NEW RECORD, columns TEXT) RETURNS JSON AS $$ BEGIN RETURN json_build_object('name_old', OLD.name, 'name_new', NEW.name); /* 古い名前と新しい名前を返す */ END; $$ LANGUAGE plpgsql;
age_create_vertex_delete_trigger
頂点テーブルの DELETE トリガーを作成します。
構文
age_create_vertex_delete_trigger('<graph_name>',
'<label_name>',
'<table_name>',
'<vertex_primary_key_field_name>' default 'id',
'<custom_property_processing_function>')<vertex_primary_key_field_name> は整数である必要があります。
int4(32 ビット整数)またはint8(64 ビット整数)型を使用できます。<custom_property_processing_function> は、頂点を削除するときに追加の操作(削除されたデータの記録やクリーンアップの実行など)を実行するために指定する関数です。関数の構文:
CREATE OR REPLACE FUNCTION custom_delete_function(OLD RECORD, columns TEXT) RETURNS void AS $$ BEGIN RAISE NOTICE 'delete: %', OLD; /* 削除されたレコードをログに記録する */ END; $$ LANGUAGE plpgsql;
辺トリガー
age_create_edge_insert_trigger
辺テーブルの INSERT トリガーを作成します。
構文
age_create_edge_insert_trigger('<graph_name>',
'<edge_label_name>',
'<edge_table_name>',
'<start_vertex_label_name>',
'<end_vertex_label_name>',
'<edge_table_primary_key_field_name>' default 'id',
'<start_vertex_table_primary_key_field_name>' default 'from_id',
'<end_vertex_table_primary_key_field_name>' default 'to_id',
'<custom_property_processing_function>')<primary_key_field_name> パラメーターの値は、整数である必要があります。
int4(32 ビット整数)またはint8(64 ビット整数)型を使用できます。<custom_property_processing_function> は、リレーショナルテーブルのプロパティ値をグラフの辺プロパティ値に変換するために指定する関数です。関数の構文:
CREATE OR REPLACE FUNCTION custom_insert_function(NEW RECORD, columns TEXT) RETURNS JSON AS $$ BEGIN RETURN json_build_object('name', NEW.name); /* 名前を返す */ END; $$ LANGUAGE plpgsql;
age_create_edge_update_trigger
辺テーブルの UPDATE トリガーを作成します。
構文
age_create_edge_update_trigger('<graph_name>',
'<edge_label_name>',
'<edge_table_name>',
'<start_vertex_label_name>',
'<end_vertex_label_name>',
'<edge_table_primary_key_field_name>' default 'id',
'<start_vertex_table_primary_key_field_name>' default 'from_id',
'<end_vertex_table_primary_key_field_name>' default 'to_id',
'<custom_property_processing_function>')<primary_key_field_name> パラメーターの値は、整数である必要があります。
int4(32 ビット整数)またはint8(64 ビット整数)型を使用できます。<custom_property_processing_function> は、リレーショナルテーブルのプロパティ値をグラフの辺プロパティ値に変換するために指定する関数です。関数の構文:
CREATE OR REPLACE FUNCTION custom_update_function(OLD RECORD, NEW RECORD, columns TEXT) RETURNS JSON AS $$ BEGIN RETURN json_build_object('name_old', OLD.name, 'name_new', NEW.name); /* 古い名前と新しい名前を返す */ END; $$ LANGUAGE plpgsql;
age_create_edge_delete_trigger
辺テーブルの DELETE トリガーを作成します。
構文
age_create_edge_delete_trigger ('<graph_name>',
'<edge_label_name>',
'<edge_table_name>',
'<edge_table_primary_key_field_name>' default 'id',
'<custom_property_processing_function>')<edge_table_primary_key_field_name> は整数である必要があります。
int4(32 ビット整数)またはint8(64 ビット整数)型を使用できます。<custom_property_processing_function> は、辺を削除するときに追加の操作を実行するために指定する関数です。関数の構文:
CREATE OR REPLACE FUNCTION custom_delete_function(OLD RECORD, columns TEXT) RETURNS void AS $$ BEGIN RAISE NOTICE 'delete: %', OLD; /* 削除されたレコードをログに記録する */ END; $$ LANGUAGE plpgsql;
例
次の例では、リレーショナルテーブルをグラフの頂点に関連付け、トリガーを作成する SQL 文を示します。リレーショナルテーブルのデータが変更されると (INSERT/UPDATE/DELETE)、トリガーによってグラフの頂点が自動的に更新されます。
リレーショナルテーブル | グラフの頂点 |
person_table | Person |
city_table | City |
lives_in_table | LivesIn |
グラフ構造の作成
SELECT ag_catalog.create_graph('graph_age_create_trigger');
-- 頂点ラベルを作成する
SELECT ag_catalog.create_vlabel('graph_age_create_trigger', 'Person');
SELECT ag_catalog.create_vlabel('graph_age_create_trigger', 'City');
-- 辺ラベルを作成する
SELECT ag_catalog.create_elabel('graph_age_create_trigger', 'LivesIn');リレーショナルテーブルの作成
-- テーブルを作成する
CREATE TABLE person_table (
id SERIAL PRIMARY KEY,
name TEXT,
age INT
);
CREATE TABLE city_table (
id SERIAL PRIMARY KEY,
name TEXT,
population INT
);
CREATE TABLE lives_in_table (
id SERIAL PRIMARY KEY,
person_id INT,
city_id INT,
since DATE
);トリガーの作成
SELECT age_create_vertex_insert_trigger('graph_age_create_trigger', 'Person', 'person_table');
SELECT age_create_vertex_update_trigger('graph_age_create_trigger', 'Person', 'person_table');
SELECT age_create_vertex_delete_trigger('graph_age_create_trigger', 'Person', 'person_table');
SELECT age_create_vertex_insert_trigger('graph_age_create_trigger', 'City', 'city_table');
SELECT age_create_vertex_update_trigger('graph_age_create_trigger', 'City', 'city_table');
SELECT age_create_vertex_delete_trigger('graph_age_create_trigger', 'City', 'city_table');
SELECT age_create_edge_insert_trigger('graph_age_create_trigger', 'LivesIn', 'lives_in_table', 'Person', 'City', 'id', 'person_id', 'city_id');
SELECT age_create_edge_update_trigger('graph_age_create_trigger', 'LivesIn', 'lives_in_table', 'Person', 'City', 'id', 'person_id', 'city_id');
SELECT age_create_edge_delete_trigger('graph_age_create_trigger', 'LivesIn', 'lives_in_table', 'id');データの挿入
-- テーブルにデータを挿入する
INSERT INTO person_table (name, age) VALUES ('Alice', 30);
INSERT INTO person_table (name, age) VALUES ('Bob', 25);
INSERT INTO city_table (name, population) VALUES ('New York', 8419000);
INSERT INTO city_table (name, population) VALUES ('Los Angeles', 3980000);
INSERT INTO lives_in_table (person_id, city_id, since) VALUES (1, 1, '2010-01-01');
INSERT INTO lives_in_table (person_id, city_id, since) VALUES (2, 2, '2015-06-15');データがグラフに挿入されたことを確認します。
SELECT * from cypher('graph_age_create_trigger', $$
MATCH (p1)-[r]->(p2)
RETURN properties(p1), properties(r), properties(p2)$$) as (p agtype, r agtype, p2 agtype);
{"id": 1, "age": 30, "name": "Alice"} | {"id": 1, "since": "2010-01-01", "city_id": 1, "person_id": 1} | {"id": 1, "name": "New York", "population": 8419000}
{"id": 2, "age": 25, "name": "Bob"} | {"id": 2, "since": "2015-06-15", "city_id": 2, "person_id": 2} | {"id": 2, "name": "Los Angeles", "population": 3980000}データの変更
UPDATE person_table SET age = 31 WHERE id = 1;
UPDATE city_table SET population = 100000 WHERE id = 1;
UPDATE lives_in_table SET since = '2025-01-01' WHERE id = 1;データが同期され、更新されたことを確認します。
SELECT * FROM cypher('graph_age_create_trigger', $$
MATCH (p1)-[r]->(p2)
RETURN properties(p1), properties(r), properties(p2)$$) as (p agtype, r agtype, p2 agtype);
{"id": 1, "age": 31, "name": "Alice"} | {"id": 1, "since": "2025-01-01", "city_id": 1, "person_id": 1} | {"id": 1, "name": "New York", "population": 100000}
{"id": 2, "age": 25, "name": "Bob"} | {"id": 2, "since": "2015-06-15", "city_id": 2, "person_id": 2} | {"id": 2, "name": "Los Angeles", "population": 3980000}データの削除
DELETE FROM lives_in_table WHERE person_id = (SELECT id FROM person_table WHERE name = 'Bob' limit 1);
DELETE FROM person_table WHERE name = 'Bob';SELECT * FROM cypher('graph_age_create_trigger', $$
MATCH (p1)-[r]->(p2)
RETURN properties(p1), properties(r), properties(p2)$$) as (p agtype, r agtype, p2 agtype);
{"id": 1, "age": 30, "name": "Alice"} | {"id": 1, "since": "2010-01-01", "city_id": 1, "person_id": 1} | {"id": 1, "name": "New York", "population": 8419000}