※ 本記事は、Jayant Sharmaによる”Get started with property graphs in Oracle Database 23c Free – Developer Release“を翻訳したものです。

2023年4月13日


Oracle Database 23c Free – Developer Releaseは、世界中の企業が毎日信頼している、業界をリードするOracle Databaseの無料提供です。その新機能は、SQL:2023で定義されたGRAPH_TABLEやMATCHなどの構成を使用して、SQLでプロパティ・グラフを作成および問い合せるためのサポートです。これにより、データ内の接続を追跡するための単純なSQL問合せを記述できます。

このブログでは、VirtualBox VMおよびデモ・データセットを使用して2つの既存の表にプロパティを作成し、GRAPH_TABLEおよびMATCH句の構成を使用して問い合せます。

前提条件

•    Oracle Database 23c Free – Developer ReleaseでVirtualBox VMをダウンロードして設定します。
•    Bank Graph Datasetの内容をローカル・ディレクトリにダウンロードします(例: downloads/bankgraphdataset )。
•    VMを起動します。

シナリオ

サンプル・データは、合成銀行口座および送金を含む2つのCSVファイルで構成されます。ゴールは、循環支払チェーンがあるかどうかを判断することです。つまり、3、4または5の中間勘定科目を通過した後に同じ勘定科目で開始および終了する一連の送金です。

ステップ

•    ユーザーを作成し、必要なロールと権限を付与します。
•    CSVファイルをデータベースにロードします。
•    これらの表のビューとしてプロパティ・グラフを作成します。
•    プロパティ・グラフの問合せ

ユーザーGRAPHUSERの作成

VMが起動し、データベースが稼働したら、SYSとしてデータベースに接続し、必要な割当て制限と権限をGRAPHUSERwithという名前の新しいユーザーを作成します。
SQLclを使用して、FREEPDB1という名前のPDBに接続します。

sql sys@localhost:1521/freepdb1 as sysdba

プロンプトが表示されたら、パスワードを入力します。できれば変更いただきたい初期パスワードについては、VMのReadmeファイルを参照してください。

create user graphuser identified by <supply-a-password> quota unlimited on users ;
grant connect, resource to graphuser ;

GRAPHUSERとして接続し、データをロード

conn graphuser@localhost:1521/freepdb1

プロンプトが表示されたら、パスワードを入力します。

表の作成後にCSVファイルからデータをロードするには、LOADコマンドを入力します。

load bank_accounts bankgraphdataset/bank_accounts.csv new ;

LOAD command to load data

送金について繰り返します。

load bank_transfers bankgraphdataset/bank_transfers.csv new ;

LOAD command to load more data

BANK_GRAPHという名前のプロパティ・グラフの作成

BANK_TRANSFERS表には、TXN_ID、SRC_ACCT_ID、DST_ACCT_IDおよびAMOUNTという名前の列があります。各行は、SRC_ACCT_IDからDST_ACCT_IDへの送金を表します。したがって、この表は2つのアカウント間の接続を表しているため、プロパティ・グラフのedgeになります。TXN_ID値はedgeとAMOUNTを識別し、オプションでSRC_ACCT_IDおよびDST_ACCT_IDはedgeのプロパティになります。

edgeverticesを接続します。この場合、BANK_ACCOUNTS表はそれらのverticesを表します。ID列はvertexを識別しますが、NAME列とBALANCE列はそのプロパティになります。

つまり、プロパティ・グラフ用語で言えば、BANK_ACCOUNTSはvertex表、BANK_TRANSFERSはedge表ということになります。

次に、プロパティ・グラフを作成します。GRAPHUSERとして接続されている間に、SQLclに次の文を入力して実行します。

CREATE PROPERTY GRAPH BANK_GRAPH
    VERTEX TABLES (
        BANK_ACCOUNTS
        KEY (ID)
        PROPERTIES (ID, Name, Balance)
    )
    EDGE TABLES (
        BANK_TRANSFERS
        KEY (TXN_ID)
        SOURCE KEY (src_acct_id) REFERENCES BANK_ACCOUNTS(ID)
        DESTINATION KEY (dst_acct_id) REFERENCES BANK_ACCOUNTS(ID)
        PROPERTIES (src_acct_id, dst_acct_id, amount)
    );

詳細は、プロパティ・グラフのグラフ開発者ガイドの「プロパティ・グラフのSQL DDL文」に関する項を参照してください。

次に、BANK_GRAPHを問い合せて、循環支払チェーンを検索します。

まず、GRAPH_TABLEおよびMATCH句の構成要素について簡単に説明します。

プロパティ・グラフの問合せ

GRAPH_TABLEは、検索するグラフ・パターンを指定してプロパティ・グラフを問い合せて、その結果を列のセット(通常のSQL表)として返すことができる演算子です。

MATCH句を使用すると、グラフ・パターンを指定できます。次に例を示します。

(src) – [e] -> (dst)

2つのvertexパターンと1つのedgeパターンで構成されます。()はvertex、[]はedgeを示し、矢印 -> はedgeの方向を指定します。

詳細は、プロパティ・グラフのグラフ開発者ガイドの「SQL GRAPH_TABLE問合せ」に関する項を参照してください。

次に、BANK_GRAPHを問い合せます。
最初に、受信転送の数で上位10件のアカウントを検索します。次に、2ホップ転送の中心にある上位10件のアカウントです。

REM Find the top 10 accounts by incoming transfers
SELECT acct_id, COUNT(1) AS Num_Transfers
    FROM graph_table ( BANK_GRAPH
        MATCH (src) - [IS BANK_TRANSFERS] -> (dst)
        COLUMNS ( dst.id AS acct_id )
    ) GROUP BY acct_id ORDER BY Num_Transfers DESC
FETCH FIRST 10 ROWS ONLY;

結果は次のようになります。:

   ACCT_ID    NUM_TRANSFERS
__________ ________________
       387               39
       934               39
       135               36
       534               32
       380               31
       330               30
       406               28
       746               28
       920               26
       259               26

10 rows selected.
REM Find the top 10 accounts in the middle of a 2-hop chain of transfers
SELECT acct_id, COUNT(1) AS Num_In_Middle
    FROM graph_table ( BANK_GRAPH
        MATCH (src) - [IS BANK_TRANSFERS] -> (via) - [IS BANK_TRANSFERS] -> (dst)
        COLUMNS ( via.id AS acct_id )
    ) GROUP BY acct_id ORDER BY Num_In_Middle DESC FETCH FIRST 10 ROWS ONLY;

結果は次のようになります。:

   ACCT_ID    NUM_IN_MIDDLE
__________ ________________
       387              195
       934              195
       135              180
       534              160
       380              155
       330              150
       406              140
       746              140
       920              130
       259              130

10 rows selected.

次に、3ホップ、4ホップまたは5ホップの循環支払チェーンがあるかどうかを確認します。

REM Check if there are any 3-hop (triangles) transfers that start and end at the same account
SELECT acct_id, COUNT(1) AS Num_Triangles
    FROM graph_table (BANK_GRAPH
        MATCH (src) - []->{3} (src)
        COLUMNS (src.id AS acct_id)
    ) GROUP BY acct_id ORDER BY Num_Triangles DESC;

   ACCT_ID    NUM_TRIANGLES
__________ ________________
       918                3
       751                3
       534                3
       359                3
       119                2
       677                2
       218                2
…
118 rows selected.
REM Check if there are any 4-hop transfers that start and end at the same account
SELECT acct_id, COUNT(1) AS Num_4hop_Chains
    FROM graph_table (BANK_GRAPH
        MATCH (src) - []->{4} (src)
        COLUMNS (src.id AS acct_id)
    ) GROUP BY acct_id ORDER BY Num_4hop_Chains DESC;

   ACCT_ID    NUM_4HOP_CHAINS
__________ __________________
       397                  8
       387                  7
       579                  7
       801                  6
       559                  6
       499                  6
       716                  5
…
329 rows selected.
REM Check if there are any 5-hop transfers that start and end at the same account
SELECT acct_id, COUNT(1) AS Num_5hop_Chains
    FROM graph_table (BANK_GRAPH
        MATCH (src) - []->{5} (src)
        COLUMNS (src.id AS acct_id)
    ) GROUP BY acct_id ORDER BY Num_5hop_Chains DESC;

   ACCT_ID    NUM_4HOP_CHAINS
__________ __________________
       397                  8
       387                  7
       579                  7
       801                  6
       559                  6
       499                  6
       716                  5
…
619 rows selected.

最後に、3ホップから5ホップの長さの循環支払チェーンを持つ上位10のアカウントをリストします。

REM Query by number of 3 to 5 hops cycles in descending order. Show top 10.
SELECT DISTINCT(account_id), COUNT(1) AS Num_Cycles
    FROM graph_table(BANK_GRAPH
        MATCH (v1)-[IS BANK_TRANSFERS]->{3, 5}(v1)
        COLUMNS (v1.id AS account_id)
    ) GROUP BY account_id ORDER BY Num_Cycles DESC FETCH FIRST 10 ROWS ONLY;

   ACCOUNT_ID    NUM_CYCLES
_____________ _____________
          135            37
          387            34
          934            30
          640            28
          458            27
           13            27
          559            25
          352            23
          406            23
          499            22

10 rows selected.

この簡単な紹介が役立つことをご理解いただき、データセットやユース・ケースで実験する意欲が湧くことを願っています。Oracle Database Free – Developer Releaseフォーラムで、経験について話し合い、アイデアを投稿したり、質問してください。Oracle Database 23c Free – Developer Releaseは、次世代のOracle Databaseの最初のリリースです。これにより、開発者は、最新のデータドリブン・アプリケーションの開発を簡素化する革新的な23cの機能により、アプリケーションの構築をすぐに開始できます。Oracle Database 23cの機能セット全体は、今後12か月以内に一般提供する予定です。